void run() { Document document = fromBson( BSONObj() ); ASSERT_EQUALS( 0U, document->getFieldCount() ); document = fromBson( BSON( "a" << 1 << "b" << "q" ) ); ASSERT_EQUALS( 2U, document->getFieldCount() ); ASSERT_EQUALS( "a", getNthField(document, 0).first.toString() ); ASSERT_EQUALS( 1, getNthField(document, 0).second.getInt() ); ASSERT_EQUALS( "b", getNthField(document, 1).first.toString() ); ASSERT_EQUALS( "q", getNthField(document, 1).second.getString() ); assertRoundTrips( document ); }
void assertRoundTrips( const Document& document1 ) { BSONObj obj1 = toBson( document1 ); Document document2 = fromBson( obj1 ); BSONObj obj2 = toBson( document2 ); ASSERT_EQUALS( obj1, obj2 ); ASSERT_EQUALS( 0, Document::compare( document1, document2 ) ); }
QVariantMap fromBson(mongo::BSONObj bson) { QVariantMap obj; for(mongo::BSONObjIterator i(bson); i.more();) { mongo::BSONElement e = i.next(); QString name = QString::fromStdString(e.fieldName()); switch(e.type()) { case mongo::EOO: return obj; case mongo::NumberDouble: obj[name] = e.numberDouble(); break; case mongo::String: obj[name] = QString::fromStdString(e.str()); break; case mongo::Object: obj[name] = fromBson(e.embeddedObject()); break; case mongo::Date: obj[name] = QDateTime::fromTime_t(e.date()); break; case mongo::Undefined: obj[name] = QVariant(); break; case mongo::jstOID: obj[name] = QString::fromStdString(e.__oid().str()); break; case mongo::jstNULL: obj[name] = QVariant(); break; case mongo::Bool: obj[name] = e.boolean(); break; case mongo::CodeWScope: obj[name] = "MongoCode["+QString::fromStdString(e.codeWScopeCode())+"]"; break; case mongo::NumberInt: obj[name] = e.numberInt(); break; default: qCritical() << "fromBson() type" << e.type() << "unknown!"; Q_ASSERT(false); } } return obj; }
QVariantMap TBson::fromBson(const TBsonObject *obj) { QVariantMap ret; bson_iter_t it; const bson_t *bson = (const bson_t *)obj; bson_iter_init(&it, bson); while (bson_iter_next(&it)) { bson_type_t t = bson_iter_type(&it); QString key(bson_iter_key(&it)); switch (t) { case BSON_TYPE_EOD: return ret; break; case BSON_TYPE_DOUBLE: ret[key] = bson_iter_double(&it); break; case BSON_TYPE_UTF8: ret[key] = QString::fromUtf8(bson_iter_utf8(&it, nullptr)); break; case BSON_TYPE_ARRAY: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_array(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub).values(); } break; } case BSON_TYPE_DOCUMENT: { const uint8_t *docbuf = nullptr; uint32_t doclen = 0; bson_t sub[1]; bson_iter_document(&it, &doclen, &docbuf); if (bson_init_static(sub, docbuf, doclen)) { ret[key] = fromBson(sub); } break; } case BSON_TYPE_BINARY: { const uint8_t *binary = nullptr; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; uint32_t len = 0; bson_iter_binary(&it, &subtype, &len, &binary); if (binary) { ret[key] = QByteArray((char *)binary, len); } break; } case BSON_TYPE_UNDEFINED: ret[key] = QVariant(); break; case BSON_TYPE_OID: { char oidhex[25]; bson_oid_to_string(bson_iter_oid(&it), oidhex); ret[key] = QString(oidhex); break; } case BSON_TYPE_BOOL: ret[key] = (bool)bson_iter_bool(&it); break; case BSON_TYPE_DATE_TIME: { #if QT_VERSION >= 0x040700 QDateTime date; date.setMSecsSinceEpoch(bson_iter_date_time(&it)); #else qint64 val = bson_iter_date_time(&it); qint64 days = val / 86400000; // 24*60*60*1000 int msecs = val % 86400000; QDate dt = QDate(1970, 1, 1).addDays(days); QTime tm = QTime(0, 0, 0).addMSecs(msecs); QDateTime date(dt, tm, Qt::UTC); #endif ret[key] = date; break; } case BSON_TYPE_NULL: ret[key] = QVariant(); break; case BSON_TYPE_REGEX: ret[key] = QRegExp(QLatin1String(bson_iter_regex(&it, nullptr))); break; case BSON_TYPE_CODE: ret[key] = QString(bson_iter_code(&it, nullptr)); break; case BSON_TYPE_SYMBOL: ret[key] = QString(bson_iter_symbol(&it, nullptr)); break; case BSON_TYPE_INT32: ret[key] = bson_iter_int32(&it); break; case BSON_TYPE_INT64: ret[key] = (qint64)bson_iter_int64(&it); break; case BSON_TYPE_CODEWSCOPE: // FALL THROUGH case BSON_TYPE_TIMESTAMP: // FALL THROUGH (internal use) // do nothing break; default: tError("fromBson() unknown type: %d", t); break; } //tSystemDebug("fromBson : t:%d key:%s = %s", t, qPrintable(key), qPrintable(ret[key].toString())); } return ret; }
QVariant TBson::value(const QString &key, const QVariant &defaultValue) const { return fromBson(*this).value(key, defaultValue); }