std::string formatUuid(mongo::BSONElement &element, Robomongo::UUIDEncoding encoding) { mongo::BinDataType binType = element.binDataType(); if (binType != mongo::newUUID && binType != mongo::bdtUUID) throw new std::invalid_argument("Binary subtype should be 3 (bdtUUID) or 4 (newUUID)"); int len; const char *data = element.binData(len); std::string hex = HexUtils::toStdHexLower(data, len); if (binType == mongo::bdtUUID) { std::string uuid = HexUtils::hexToUuid(hex, encoding); switch(encoding) { case DefaultEncoding: return "LUUID(\"" + uuid + "\")"; case JavaLegacy: return "JUUID(\"" + uuid + "\")"; case CSharpLegacy: return "NUUID(\"" + uuid + "\")"; case PythonLegacy: return "PYUUID(\"" + uuid + "\")"; default: return "LUUID(\"" + uuid + "\")"; } } else { std::string uuid = HexUtils::hexToUuid(hex, DefaultEncoding); return "UUID(\"" + uuid + "\")"; } }
bool isUuidType(const mongo::BSONElement &elem) { if (elem.type() != mongo::BinData) return false; mongo::BinDataType binType = elem.binDataType(); return (binType == mongo::newUUID || binType == mongo::bdtUUID); }
void repo::core::RepoNodeMesh::retrieveFacesArray( const mongo::BSONElement &bse, const unsigned int api, const unsigned int facesByteCount, const unsigned int facesCount, std::vector<aiFace> *faces) { //-------------------------------------------------------------------------- // TODO make use of RepoTranscoderBSON to retrieve vector of unsigned int if (REPO_NODE_API_LEVEL_1 == api) { faces->resize(facesCount); unsigned int * serializedFaces = new unsigned int[facesByteCount/sizeof(unsigned int)]; if (NULL != faces && NULL != serializedFaces && facesCount > 0 && bse.binDataType() == mongo::BinDataGeneral) { // Copy over all the integers int len = (int) facesByteCount; const char *binData = bse.binData(len); memcpy(serializedFaces, binData, facesByteCount); // Retrieve numbers of vertices for each face and subsequent // indices into the vertex array. // In API level 1, mesh is represented as // [n1, v1, v2, ..., n2, v1, v2...] unsigned int counter = 0; int mNumIndicesIndex = 0; while (counter < facesCount) { int mNumIndices = serializedFaces[mNumIndicesIndex]; aiFace face; face.mNumIndices = mNumIndices; unsigned int *indices = new unsigned int[mNumIndices]; for (int i = 0; i < mNumIndices; ++i) indices[i] = serializedFaces[mNumIndicesIndex + 1 + i]; face.mIndices = indices; (*faces)[counter] = face; mNumIndicesIndex = mNumIndicesIndex + mNumIndices + 1; ++counter; } } // Memory cleanup if (NULL != serializedFaces) delete [] serializedFaces; } else if (REPO_NODE_API_LEVEL_2 == api) { // TODO: triangles only } else if (REPO_NODE_API_LEVEL_3 == api) { // TODO: compression } }
Datum convert_element<int>(PG_FUNCTION_ARGS, const mongo::BSONElement e) { if(e.type() == mongo::NumberInt) { PG_RETURN_INT32(e._numberInt()); } else { throw convertion_error("int4"); } }
Datum convert_element<std::string>(PG_FUNCTION_ARGS, const mongo::BSONElement e) { std::stringstream ss; switch(e.type()) { case mongo::String: case mongo::DBRef: case mongo::Symbol: return return_string(std::string(e.valuestr(), e.valuestrsize()-1)); case mongo::NumberDouble: ss << e._numberDouble(); break; case mongo::jstOID: ss << e.__oid().str(); break; case mongo::Bool: ss << std::boolalpha << e.boolean(); break; case mongo::Date: return return_string( to_iso_extended_string( boost::posix_time::ptime( boost::gregorian::date(1970, 1, 1), boost::posix_time::milliseconds(e.date().millis) ) ) ); case mongo::RegEx: ss << e.regex(); break; case mongo::NumberInt: ss << e._numberInt(); break; case mongo::NumberLong: ss << e._numberLong(); break; default: throw convertion_error("text"); } return return_string(ss.str()); }
Datum convert_element<int64>(PG_FUNCTION_ARGS, const mongo::BSONElement e) { switch(e.type()) { case mongo::NumberLong: PG_RETURN_INT64(e._numberLong()); // this conversion has to be imlicitly allowedm, otherwise defining object form json would be pain int the ass case mongo::NumberInt: PG_RETURN_INT64(static_cast<int64>(e._numberInt())); default: throw convertion_error("int8"); } }
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; }
repoUUID RepoBSON::getUUIDField(const std::string &label) const{ repoUUID uuid; if (hasField(label)) { const mongo::BSONElement bse = getField(label); if (bse.type() == mongo::BSONType::BinData && (bse.binDataType() == mongo::bdtUUID || bse.binDataType() == mongo::newUUID)) { int len = static_cast<int>(bse.size() * sizeof(boost::uint8_t)); const char *binData = bse.binData(len); memcpy(uuid.data, binData, len); } else { repoError << "Field " << label << " is not of type UUID!"; uuid = generateUUID(); // failsafe } } else { repoError << "Field " << label << " does not exist!"; uuid = generateUUID(); // failsafe } return uuid; }
mongo::BSONObj getField<mongo::BSONObj>(const mongo::BSONElement &elem) { mongo::BSONObj res; try { res = elem.Obj(); } catch(const UserException &) { } return res; }
std::string MongoSchema::getType(mongo::BSONElement belem){ if(belem.isABSONObj()) { return "BSON"; }else if(belem.isSimpleType()){ // Simple Type: Number, String, Date, Bool or OID if(belem.isNumber()){ return "Number"; }else if(belem.type() == mongo::String){ return "String"; }else if(belem.type() == mongo::Date){ return "Date"; }else if(belem.type() == mongo::Bool){ return "Boolean"; }else{ return "Other"; } }else{ return "Unknown"; } }
mongo::BSONObj getField<mongo::BSONObj>(const mongo::BSONElement &elem) { return elem.embeddedObject(); }
long long getField<long long>(const mongo::BSONElement &elem) { return elem.safeNumberLong(); }
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; }
bool getField<bool>(const mongo::BSONElement &elem) { return elem.Bool(); }
std::string getField<std::string>(const mongo::BSONElement &elem) { return elem.String(); }
int decode(T *t, const mongo::BSONElement &elm){ int len = 0; const char *p = elm.binData(len); memcpy((t->*ptr).id, p, len); return 0; }
bool isArray(const mongo::BSONElement &elem) { return isArray(elem.type()); }
bool isDocument(const mongo::BSONElement &elem) { return isDocument(elem.type()); }
std::vector<BSONElement> getField<std::vector<BSONElement> >(const mongo::BSONElement &elem) { return elem.Array(); }
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; } }
bool isSimpleType(const mongo::BSONElement &elem) { return isSimpleType(elem.type()); }
double getField<double>(const mongo::BSONElement &elem) { return elem.numberDouble(); }