bool GroupCache::Replicate(const mongo::BSONElement& id) { if (id.type() != 16) return true; acl::GroupID gid = id.Int(); try { SafeConnection conn; auto fields = BSON("gid" << 1 << "name" << 1); auto data = conn.QueryOne<GroupPair>("groups", QUERY("gid" << gid), &fields); if (data) { // group found, refresh cached data { std::lock_guard<std::mutex> lock(gidsMutex); gids[data->name] = data->gid; } { std::lock_guard<std::mutex> lock(namesMutex); names[data->gid] = data->name; } } else { // group not found, must be deleted, remove from cache std::lock(gidsMutex, namesMutex); std::lock_guard<std::mutex> gidsLock(gidsMutex, std::adopt_lock); std::lock_guard<std::mutex> namesLock(namesMutex, std::adopt_lock); auto it = names.find(gid); if (it != names.end()) { gids.erase(it->second); names.erase(it); } } } catch (const DBError&) { return false; } return true; }
int getField<int>(const mongo::BSONElement &elem) { return elem.Int(); }
bool UserCache::Replicate(const mongo::BSONElement& id) { if (id.type() != 16) return true; acl::UserID uid = id.Int(); updatedCallback(uid); try { SafeConnection conn; auto fields = BSON("uid" << 1 << "name" << 1 << "primary gid" << 1); auto data = conn.QueryOne<UserTriple>("users", QUERY("uid" << uid), &fields); if (data) { // user found, refresh cached data { std::lock_guard<std::mutex> lock(uidsMutex); uids[data->name] = data->uid; } { std::lock_guard<std::mutex> lock(namesMutex); names[data->uid] = data->name; } { std::lock_guard<std::mutex> lock(primaryGidsMutex); primaryGids[data->uid] = data->primaryGid; } auto masks = LookupIPMasks(conn, uid); { std::lock_guard<std::mutex> lock(ipMasksMutex); ipMasks[data->uid] = std::move(masks); } } else { // user not found, must be deleted, remove from cache { std::lock(uidsMutex, namesMutex); std::lock_guard<std::mutex> uidsLock(uidsMutex, std::adopt_lock); std::lock_guard<std::mutex> namesLock(namesMutex, std::adopt_lock); auto it = names.find(uid); if (it != names.end()) { uids.erase(it->second); names.erase(it); } } { std::lock_guard<std::mutex> lock(primaryGidsMutex); primaryGids.erase(uid); } { std::lock_guard<std::mutex> lock(ipMasksMutex); ipMasks.erase(uid); } } } catch (const DBError&) { return false; } return true; }
void buildJsonString(const mongo::BSONElement &elem,std::string &con, UUIDEncoding uuid, SupportedTimes tz) { switch (elem.type()) { case NumberDouble: { char dob[32] = {0}; sprintf(dob, "%f", elem.Double()); con.append(dob); } break; case String: { con.append(elem.valuestr(), elem.valuestrsize() - 1); } break; case Object: { buildJsonString(elem.Obj(), con, uuid, tz); } break; case Array: { buildJsonString(elem.Obj(), con, uuid, tz); } break; case BinData: { mongo::BinDataType binType = elem.binDataType(); if (binType == mongo::newUUID || binType == mongo::bdtUUID) { std::string uu = HexUtils::formatUuid(elem, uuid); con.append(uu); break; } con.append("<binary>"); } break; case Undefined: con.append("<undefined>"); break; case jstOID: { std::string idValue = elem.OID().toString(); char buff[256] = {0}; sprintf(buff, "ObjectId(\"%s\")", idValue.c_str()); con.append(buff); } break; case Bool: con.append(elem.Bool() ? "true" : "false"); break; case Date: { long long ms = (long long) elem.Date().millis; boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); boost::posix_time::time_duration diff = boost::posix_time::millisec(ms); boost::posix_time::ptime time = epoch + diff; std::string date = miutil::isotimeString(time,false,tz==LocalTime); con.append(date); break; } case jstNULL: con.append("<null>"); break; case RegEx: { con.append("/" + std::string(elem.regex()) + "/"); for ( const char *f = elem.regexFlags(); *f; ++f ) { switch ( *f ) { case 'g': case 'i': case 'm': con+=*f; default: break; } } } break; case DBRef: break; case Code: con.append(elem._asCode()); break; case Symbol: con.append(elem.valuestr(), elem.valuestrsize() - 1); break; case CodeWScope: { mongo::BSONObj scope = elem.codeWScopeObject(); if (!scope.isEmpty() ) { con.append(elem._asCode()); break; } } break; case NumberInt: { char num[16]={0}; sprintf(num,"%d",elem.Int()); con.append(num); break; } case Timestamp: { Date_t date = elem.timestampTime(); unsigned long long millis = date.millis; if ((long long)millis >= 0 && ((long long)millis/1000) < (std::numeric_limits<time_t>::max)()) { con.append(date.toString()); } break; } case NumberLong: { char num[32]={0}; sprintf(num,"%lld",elem.Long()); con.append(num); break; } default: con.append("<unsupported>"); break; } }