void testToChar() { cout << "testToChar" << endl; BSONObj obj; obj.add("int", 1); obj.add("string", (char*)"test"); obj.add("char*", (char*)"char*"); obj.add("long", (__int64)1L); obj.add("double", 1.1); char* json = obj.toChar(); int res = strcmp(json, "{ \"char*\" : \"char*\", \"double\" : 1.100000, \"int\" : 1, \"long\" : 1, \"string\" : \"test\"}"); TEST_ASSERT(res == 0); if (res != 0) { cout << "\nResult: " << json << endl; } free(json); BSONObj inner; inner.add("int", 1); inner.add("string", (char*)"test"); inner.add("char*", (char*)"char*"); inner.add("long", (__int64)1L); inner.add("double", 1.1); obj.add("inner", inner); json = obj.toChar(); cout << "\nResult: " << json << endl; free(json); }
void testBigBSON() { cout << "testBigBSON" << endl; BSONObj* obj = new BSONObj(); int chars = 1000; // Add in obj->add("int", 1); obj->add("long", (__int64)LONG_MAX); obj->add("long long", (__int64)LLONG_MAX); char* temp = (char*)malloc(chars+1); memset(temp, 0, chars+1); memset(temp, 'a', chars); obj->add("char*", temp); BSONObj rel; rel.add("innertext", temp); obj->add("rel1", rel); char* json = obj->toChar(); BSONObj* obj2 = BSONParser::parse(json); free(json); TEST_ASSERT(obj->has("int")); TEST_ASSERT(obj->getInt("int") == 1); TEST_ASSERT(obj->has("long")); TEST_ASSERT(obj->getLong("long") == LONG_MAX); TEST_ASSERT(obj->has("long long")); TEST_ASSERT(obj->getLong("long long") == LLONG_MAX); TEST_ASSERT(strcmp(obj->getString("char*"), temp) == 0); TEST_ASSERT(obj->has("rel1")); TEST_ASSERT(strcmp(obj->getBSON("rel1")->getString("innertext"), temp) == 0); delete obj; delete obj2; free(temp); }
char* BSONObj::toChar() { // if the toChar was already calculated before use it if (_cBSON != NULL) { return strcpy(_cBSON); } Logger* log = getLogger(NULL); char* result = (char*)malloc(MAX_BSONOBJ_BUFFER); memset(result, 0, MAX_BSONOBJ_BUFFER); __int32 pos = 0; result[0] = '{'; pos += 1; bool first = true; for (std::map<std::string, BSONContent* >::const_iterator i = _elements.begin(); i != _elements.end(); i++) { if (!first) { result[pos] = ','; pos++; } first = false; BSONContent* content = i->second; std::string key = i->first; sprintf(result + pos, " \"%s\" : ", key.c_str()); pos += key.length() + 6; //ss << "\"" << key << "\" :"; char* chr; const char* cstr; switch (content->type()) { case BSON_TYPE: { BSONContentBSON* bbson = (BSONContentBSON*)content; BSONObj* bson = (BSONObj*)*bbson; char* chrbson = bson->toChar(); sprintf(result + pos, "%s", chrbson); free(chrbson); break; } case BSONARRAY_TYPE: { BSONContentBSONArray* bbsonarray = (BSONContentBSONArray*)content; BSONArrayObj* bsonarray = (BSONArrayObj*)*bbsonarray; char* chrbsonarray = bsonarray->toChar(); sprintf(result + pos, "%s", chrbsonarray); free(chrbsonarray); break; } case BOOL_TYPE: { BSONContentBoolean* bb = (BSONContentBoolean*)content; sprintf(result + pos, "%s", ((bool)*bb?"true": "false")); break; } case INT_TYPE: { BSONContentInt* bint = (BSONContentInt*)content; sprintf(result + pos, "%d", (__int32)*bint); break; } case LONG_TYPE: { BSONContentLong* blong = (BSONContentLong*)content; sprintf(result + pos, "%ld", (__int64)*blong); break; } case DOUBLE_TYPE: { BSONContentDouble* bdouble = (BSONContentDouble*)content; sprintf(result + pos, "%f", (double)*bdouble); break; } case STRING_TYPE: case PTRCHAR_TYPE: { BSONContentString* bstring = (BSONContentString*)content; djondb::string s = *bstring; sprintf(result + pos, "\"%.*s\"", s.length(), s.c_str()); break; } } pos = strlen(result); assert(pos < MAX_BSONOBJ_BUFFER); } result[pos] = '}'; result[pos+1] = 0; pos++; __int32 len = strlen(result); // Saves the value to cache the calculated value _cBSON = result; char* cresult = strcpy(result); if (log->isDebug()) log->debug("toChar result: %s", cresult); return cresult; }
bool Connection::update(const std::string& db, const std::string& ns, const BSONObj& obj) { if (_logger->isDebug()) _logger->debug(2, "Update command. db: %s, ns: %s, bson: %s", db.c_str(), ns.c_str(), obj.toChar()); UpdateCommand cmd; cmd.setBSON(obj); cmd.setDB(db); cmd.setNameSpace(ns); _commandWriter->writeCommand(&cmd); cmd.readResult(_inputStream); return true; }
bool Connection::insert(const std::string& db, const std::string& ns, const BSONObj& bson) { if (_logger->isDebug()) _logger->debug(2, "Insert command. db: %s, ns: %s, bson: %s", db.c_str(), ns.c_str(), bson.toChar()); BSONObj obj(bson); InsertCommand cmd; cmd.setDB(db); if (!obj.has("_id")) { std::string* id = uuid(); obj.add("_id", *id); delete id; } if (!obj.has("_revision")) { std::string* rev = uuid(); obj.add("_revision", *rev); delete rev; } cmd.setBSON(obj); cmd.setNameSpace(ns); _commandWriter->writeCommand(&cmd); cmd.readResult(_inputStream); int hasResults = false; //_inputStream->readInt(); if (hasResults) { // When the bson didnt contain an id the server will return a bson with it // At this moment this will never occur, but I will leave this code for later } return true; }
BSONObj* DBController::readBSON(StreamType* stream) { auto_ptr<BSONInputStream> is(new BSONInputStream(stream)); BSONObj* res = is->readBSON(); if (_logger->isDebug()) _logger->debug(3, "DBController read bson from disc: %s", res->toChar()); return res; }