// Execute the query bool QueryInsert::execute() { string sql = toString(); if(!sql.length()) { return false; } sqlite3_stmt* stmt; if(!getDB().prepare(sql, &stmt)) { sqlite3_finalize(stmt); return false; } if(!getDB().bind(field_values.getParams(), &stmt, Database::QUERY_INSERT)) { sqlite3_finalize(stmt); return false; } if(sqlite3_step(stmt) != SQLITE_DONE) { printf("error: %s\n", sqlite3_errmsg(getSQLite())); sqlite3_finalize(stmt); return false; } sqlite3_finalize(stmt); return true; }
bool QvernoteStorage::updateTag(Tag& updatedTag) { if(updatedTag.updateSequenceNum != 0) updatedTag.updateSequenceNum++; QTag::update(getDB(), updatedTag); if(updatedTag.updateSequenceNum != 0) QItem::setDirtyFlag(getDB(), "tags", "guid", QString::fromStdString(updatedTag.guid), 1); }
Status DBHandle::Get(const std::string& domain, const std::string& key, std::string& value) const { if (getDB() == nullptr) { return Status(1, "Database not opened"); } auto cfh = getHandleForColumnFamily(domain); if (cfh == nullptr) { return Status(1, "Could not get column family for " + domain); } auto s = getDB()->Get(rocksdb::ReadOptions(), cfh, key, &value); return Status(s.code(), s.ToString()); }
/* * Construct the body of the request by filtering * the attr_filter string. The body format should * look like the following: * create: attrvals[][attrib]=<name|industry>&attrvals[][object]=<locallygeneratedid>&attrvals[][value]=<some value> * update: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid>&attrvals[][value]=<some new value> * delete: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid> */ void CSyncSource::makePushBody(String& strBody, const char* szUpdateType) { getDB().Lock(); DBResult( res , getDB().executeSQL("SELECT attrib, object, value, attrib_type, main_id " "FROM changed_values where source_id=? and update_type =? and sent<=1 ORDER BY sent DESC", getID(), szUpdateType ) ); if ( res.isEnd() ) { getDB().Unlock(); return; } for( ; !res.isEnd(); res.next() ) { String strSrcBody = "attrvals[][attrib]=" + res.getStringByIdx(0); if ( res.getStringByIdx(1).length() > 0 ) strSrcBody += "&attrvals[][object]=" + res.getStringByIdx(1); uint64 main_id = res.getUInt64ByIdx(4); if ( main_id != 0 ) strSrcBody += "&attrvals[][id]=" + convertToStringA(main_id); String value = res.getStringByIdx(2); String attribType = res.getStringByIdx(3); //if ( value.length() > 0 ) { if ( attribType == "blob.file" ) { common::CFilePath oBlobPath(value); strSrcBody += "&attrvals[][value]="; strSrcBody += oBlobPath.getBaseName(); strSrcBody += "&attrvals[][attrib_type]=blob"; if ( value.length() > 0 ) m_arSyncBlobs.addElement(new CSyncBlob(strSrcBody,value)); continue; }else strSrcBody += "&attrvals[][value]=" + value; } if ( strBody.length() > 0 ) strBody += "&"; strBody += strSrcBody; } getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), szUpdateType ); getDB().Unlock(); }
void CSyncSource::syncClientChanges() { const char* arUpdateTypes[] = {"create", "update", "delete"}; for( int i = 0; i < 3 && getSync().isContinueSync(); i++ ) { String strUrl = getUrl() + "/" + arUpdateTypes[i]; strUrl += "objects"; String strQuery = CSyncEngine::SYNC_SOURCE_FORMAT() + "&client_id=" + getSync().getClientID(); m_arSyncBlobs.removeAllElements(); String strBody; makePushBody(strBody, arUpdateTypes[i]); if ( strBody.length() > 0 ) { LOG(INFO) + "Push client changes to server. Source: " + getName() + "Size :" + strBody.length(); LOG(TRACE) + "Push body: " + strBody; NetResponse( resp, getNet().pushData(strUrl+strQuery,strBody, &getSync()) ); if ( !resp.isOK() ) { getSync().setState(CSyncEngine::esStop); m_nErrCode = RhoRuby.ERR_REMOTESERVER; continue; } } if ( m_arSyncBlobs.size() > 0 ) { LOG(INFO) + "Push blobs to server. Source: " + getName() + "Count :" + m_arSyncBlobs.size(); //oo conflicts if ( i < 1 ) //create getDB().executeSQL("UPDATE changed_values SET sent=2 WHERE source_id=? and update_type=? and (attrib_type IS NULL or attrib_type!=?) and sent=1", getID(), arUpdateTypes[i], "blob.file" ); else // getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=? and (attrib_type IS NULL or attrib_type!=? and sent=1)", getID(), arUpdateTypes[i], "blob.file" ); syncClientBlobs(strUrl+strQuery); }else if ( strBody.length() > 0 ) { //oo conflicts if ( i < 1 ) //create getDB().executeSQL("UPDATE changed_values SET sent=2 WHERE source_id=? and update_type=? and sent=1", getID(), arUpdateTypes[i] ); else // getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=? and sent=1", getID(), arUpdateTypes[i] ); } } }
TEST( RocksRecoveryUnitTest, Simple1 ) { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); db->Put( rocksdb::WriteOptions(), "a", "b" ); string value; db->Get( rocksdb::ReadOptions(), "a", &value ); ASSERT_EQUALS( value, "b" ); { RocksRecoveryUnit ru( db.get(), false ); ru.beginUnitOfWork(); ru.writeBatch()->Put( "a", "c" ); value = "x"; db->Get( rocksdb::ReadOptions(), "a", &value ); ASSERT_EQUALS( value, "b" ); ru.endUnitOfWork(); value = "x"; db->Get( rocksdb::ReadOptions(), "a", &value ); ASSERT_EQUALS( value, "c" ); } }
TEST( RocksRecordStoreTest, Stats1 ) { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); RocksRecordStore rs( "foo.bar", db.get(), db->DefaultColumnFamily(), db->DefaultColumnFamily() ); string s = "eliot was here"; { MyOperationContext opCtx( db.get() ); DiskLoc loc; { WriteUnitOfWork uow( opCtx.recoveryUnit() ); StatusWith<DiskLoc> res = rs.insertRecord( &opCtx, s.c_str(), s.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); loc = res.getValue(); } ASSERT_EQUALS( s, rs.dataFor( loc ).data() ); } { MyOperationContext opCtx( db.get() ); BSONObjBuilder b; rs.appendCustomStats( &opCtx, &b, 1 ); BSONObj obj = b.obj(); ASSERT( obj["stats"].String().find( "WAL" ) != string::npos ); } }
bool QvernoteStorage::listNotebooks(std::vector<Notebook>& notebookList) { QVector<Notebook> qNotebooklist; QNotebook::loadList(getDB(), qNotebooklist); notebookList = qNotebooklist.toStdVector(); return true; }
TEST( RocksRecordStoreTest, Insert1 ) { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); int size; { RocksRecordStore rs( "foo.bar", db.get(), db->DefaultColumnFamily(), db->DefaultColumnFamily() ); string s = "eliot was here"; size = s.length() + 1; MyOperationContext opCtx( db.get() ); DiskLoc loc; { WriteUnitOfWork uow( opCtx.recoveryUnit() ); StatusWith<DiskLoc> res = rs.insertRecord( &opCtx, s.c_str(), s.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); loc = res.getValue(); } ASSERT_EQUALS( s, rs.dataFor( loc ).data() ); } { RocksRecordStore rs( "foo.bar", db.get(), db->DefaultColumnFamily(), db->DefaultColumnFamily() ); ASSERT_EQUALS( 1, rs.numRecords() ); ASSERT_EQUALS( size, rs.dataSize() ); } }
bool QvernoteStorage::listTagsByNotebook(std::vector<Tag>& tagList, Guid notebookGuid) { QVector<Tag> qTaglist; QTag::loadForNotebook(getDB(), notebookGuid, qTaglist); tagList = qTaglist.toStdVector(); return true; }
bool QvernoteStorage::copyNote(Guid noteGuid, Guid toNotebookGuid) { Note note; QNote::load(getDB(), noteGuid, note); note.notebookGuid = toNotebookGuid; return createNote(note); }
void CSyncSource::updateAssociation(const String& strOldObject, const String& strNewObject, const String& strAttrib) { if ( m_bSchemaSource ) { String strSqlUpdate = "UPDATE "; strSqlUpdate += getName() + " SET " + strAttrib + "=? where " + strAttrib + "=?"; getDB().executeSQL(strSqlUpdate.c_str(), strNewObject, strOldObject ); } else getDB().executeSQL("UPDATE object_values SET value=? where attrib=? and source_id=? and value=?", strNewObject, strAttrib, getID(), strOldObject ); getDB().executeSQL("UPDATE changed_values SET value=? where attrib=? and source_id=? and value=?", strNewObject, strAttrib, getID(), strOldObject ); }
bool QvernoteStorage::createNotebook(Notebook& newNotebook) { newNotebook.guid = getGuid().toStdString(); newNotebook.updateSequenceNum = 0; QNotebook::store(getDB(), newNotebook); return true; }
bool QvernoteStorage::createTag(Tag& newTag) { newTag.guid = getGuid().toStdString(); newTag.updateSequenceNum = 0; QTag::store(getDB(), newTag); return true; }
void CSyncSource::processServerCmd_Ver3(const String& strCmd, const String& strObject, const String& strAttriba, const String& strValuea)//throws Exception { CAttrValue oAttrValue(strAttriba,strValuea); if ( strCmd.compare("insert") == 0 ) { if ( !processBlob(strCmd,strObject,oAttrValue) ) return; DBResult(resInsert, getDB().executeSQLReportNonUnique("INSERT INTO object_values \ (attrib, source_id, object, value) VALUES(?,?,?,?)", oAttrValue.m_strAttrib, getID(), strObject, oAttrValue.m_strValue ) ); if ( resInsert.isNonUnique() ) { getDB().executeSQL("UPDATE object_values \ SET value=? WHERE object=? and attrib=? and source_id=?", oAttrValue.m_strValue, strObject, oAttrValue.m_strAttrib, getID() ); if ( getSyncType().compare("none") != 0 ) { // oo conflicts getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1", strObject, oAttrValue.m_strAttrib, getID() ); // } } if ( getSyncType().compare("none") != 0 ) getNotify().onObjectChanged(getID(),strObject, CSyncNotify::enUpdate); m_nInserted++; }else if (strCmd.compare("delete") == 0)
void SASLServerMechanismRegistry::advertiseMechanismNamesForUser(OperationContext* opCtx, const BSONObj& isMasterCmd, BSONObjBuilder* builder) { BSONElement saslSupportedMechs = isMasterCmd["saslSupportedMechs"]; if (saslSupportedMechs.type() == BSONType::String) { const auto userName = uassertStatusOK(UserName::parse(saslSupportedMechs.String())); AuthorizationManager* authManager = AuthorizationManager::get(opCtx->getServiceContext()); UserHandle user; const auto swUser = authManager->acquireUser(opCtx, userName); if (!swUser.isOK()) { auto& status = swUser.getStatus(); if (status.code() == ErrorCodes::UserNotFound) { log() << "Supported SASL mechanisms requested for unknown user '" << userName << "'"; return; } uassertStatusOK(status); } user = std::move(swUser.getValue()); BSONArrayBuilder mechanismsBuilder; const auto& mechList = _getMapRef(userName.getDB()); for (const auto& factoryIt : mechList) { SecurityPropertySet properties = factoryIt->properties(); if (!properties.hasAllProperties(SecurityPropertySet{SecurityProperty::kNoPlainText, SecurityProperty::kMutualAuth}) && userName.getDB() != "$external") { continue; } auto mechanismEnabled = _mechanismSupportedByConfig(factoryIt->mechanismName()); if (!mechanismEnabled && userName == internalSecurity.user->getName()) { mechanismEnabled = factoryIt->isInternalAuthMech(); } if (mechanismEnabled && factoryIt->canMakeMechanismForUser(user.get())) { mechanismsBuilder << factoryIt->mechanismName(); } } builder->appendArray("saslSupportedMechs", mechanismsBuilder.arr()); } }
TEST( RocksRecordStoreTest, ForwardIterator ) { { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); rocksdb::ColumnFamilyHandle* cf1; rocksdb::ColumnFamilyHandle* cf1_m; rocksdb::Status status; status = db->CreateColumnFamily( getColumnFamilyOptions(), "foo.bar1", &cf1 ); ASSERT_OK( toMongoStatus( status ) ); status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar1&", &cf1_m ); ASSERT_OK( toMongoStatus( status ) ); RocksRecordStore rs( "foo.bar", db.get(), cf1, cf1_m ); string s1 = "eliot was here"; string s2 = "antonio was here"; string s3 = "eliot and antonio were here"; DiskLoc loc1; DiskLoc loc2; DiskLoc loc3; { MyOperationContext opCtx( db.get() ); { WriteUnitOfWork uow( opCtx.recoveryUnit() ); StatusWith<DiskLoc> res = rs.insertRecord( &opCtx, s1.c_str(), s1.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); loc1 = res.getValue(); res = rs.insertRecord( &opCtx, s2.c_str(), s2.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); loc2 = res.getValue(); res = rs.insertRecord( &opCtx, s3.c_str(), s3.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); loc3 = res.getValue(); } } OperationContextNoop txn; scoped_ptr<RecordIterator> iter( rs.getIterator( &txn ) ); ASSERT_EQUALS( false, iter->isEOF() ); ASSERT_EQUALS( loc1, iter->getNext() ); ASSERT_EQUALS( s1, iter->dataFor( loc1 ).data() ); ASSERT_EQUALS( false, iter->isEOF() ); ASSERT_EQUALS( loc2, iter->getNext() ); ASSERT_EQUALS( s2, iter->dataFor( loc2 ).data() ); ASSERT_EQUALS( false, iter->isEOF() ); ASSERT_EQUALS( loc3, iter->getNext() ); ASSERT_EQUALS( s3, iter->dataFor( loc3 ).data() ); ASSERT_EQUALS( true, iter->isEOF() ); ASSERT_EQUALS( DiskLoc(), iter->getNext() ); } }
bool QvernoteStorage::listTags(vector<Tag>& tagList) { QVector<Tag> qTagList; QTag::loadList(getDB(), qTagList); tagList = qTagList.toStdVector(); return true; }
bool QvernoteStorage::getFavoriteNotes(vector<Note>& noteList) { QVector<Note> qNoteList; QNote::getFavorites(getDB(), qNoteList); noteList = qNoteList.toStdVector(); return true; }
bool QvernoteStorage::getResourceByHash(Resource& loadedResource, Guid noteGuid, QString hexContentHash) { QVector<Resource> qResourceList; QNoteResource::loadForNote(getDB(), noteGuid, qResourceList); for(QVector<Resource>::iterator i = qResourceList.begin(); i != qResourceList.end(); i++) { QByteArray resourceHash = QByteArray::fromRawData((*i).data.bodyHash.c_str(), (*i).data.bodyHash.size()); if(resourceHash.toHex() == hexContentHash) { QNoteResource::load(getDB(), (*i).guid, loadedResource); return true; } } return false; }
osquery::Status DBHandle::Delete(const std::string& domain, const std::string& key) { auto cfh = getHandleForColumnFamily(domain); if (cfh == nullptr) { return Status(1, "Could not get column family for " + domain); } auto s = getDB()->Delete(rocksdb::WriteOptions(), cfh, key); return Status(s.code(), s.ToString()); }
bool QvernoteStorage::getNoteContent(Note& note) { if(getShallowNote(note, note.guid)) { QNote::load_content(getDB(), note); return true; } return false; }
void CSyncSource::getAndremoveAsk() { String askParams = ""; { DBResult( res , getDB().executeSQL("SELECT object, attrib, value " "FROM changed_values WHERE source_id=? and update_type =?", getID(), "ask" ) ); if ( !res.isEnd() ) { askParams = res.getStringByIdx(2); getDB().executeSQL("DELETE FROM object_values WHERE object=? and attrib=? and source_id=?", res.getStringByIdx(0), res.getStringByIdx(1), getID() ); } } getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=?", getID(), "ask" ); setAskParams(askParams); }
Status DBHandle::Scan(const std::string& domain, std::vector<std::string>& results) const { if (getDB() == nullptr) { return Status(1, "Database not opened"); } auto cfh = getHandleForColumnFamily(domain); if (cfh == nullptr) { return Status(1, "Could not get column family for " + domain); } auto it = getDB()->NewIterator(rocksdb::ReadOptions(), cfh); if (it == nullptr) { return Status(1, "Could not get iterator for " + domain); } for (it->SeekToFirst(); it->Valid(); it->Next()) { results.push_back(it->key().ToString()); } delete it; return Status(0, "OK"); }
//------------------------------------------------------------------------------ void ServerFiber::main() { server_->config_->parse(); stdErr.setDebugLevels(server_->config_->value("debug_levels","+0,+1,+2,+3")); union { uint8_t cmd; uint8_t ui8; }; auth(); while( !terminated_ ){ *this >> cmd; switch( cmd ){ case cmQuit : putCode(eOK); terminate(); break; case cmGetProcessStartTime : *this << getProcessStartTime(); break; case cmSelectServerType : *this >> ui8; putCode(ui8 < stCount ? eOK : eInvalidServerType); serverType_ = ServerType(ui8); break; case cmRegisterClient : registerClient(); break; case cmRegisterDB : registerDB(); break; case cmGetDB : getDB(); break; case cmSendMail : sendMail(); break; case cmRecvMail : recvMail(); break; case cmRemoveMail : removeMail(); break; case cmSelectProtocol : *this >> ui8; putCode(ui8 < 2 ? eOK : eInvalidProtocol); protocol_ = ui8; break; default : // unrecognized or unsupported command, terminate putCode(eInvalidCommand); terminate(); } } }
bool QvernoteStorage::updateNote(Note& existingNote) { // Do not increment usn on new notes, otherwise we wont sync them with server as new notes if(existingNote.updateSequenceNum != 0) existingNote.updateSequenceNum++; // Update resource Guid for(vector<Resource>::iterator i = existingNote.resources.begin(); i != existingNote.resources.end(); i++) { if((*i).guid.empty()) (*i).guid = getGuid().toStdString(); (*i).noteGuid = existingNote.guid; } QNote::update(getDB(), existingNote); if(existingNote.updateSequenceNum != 0) QItem::setDirtyFlag(getDB(), "notes", "guid", QString::fromStdString(existingNote.guid), 1); return true; }
bool QvernoteStorage::getNoteTagNames(vector<string>& tagNames, Guid noteGuid) { QVector<Tag> qTagList; QTag::loadForNote(getDB(), noteGuid, qTagList); for(QVector<Tag>::iterator i = qTagList.begin(); i != qTagList.end(); i++) { tagNames.push_back((*i).name); } return true; }
void CSyncSource::processSyncCommand(const String& strCmd, CJSONEntry oCmdEntry) { CJSONStructIterator objIter(oCmdEntry); for( ; !objIter.isEnd() && getSync().isContinueSync(); objIter.next() ) { String strObject = objIter.getCurKey(); CJSONStructIterator attrIter( objIter.getCurValue() ); if ( m_bSchemaSource ) processServerCmd_Ver3_Schema(strCmd,strObject,attrIter); else { for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() ) { String strAttrib = attrIter.getCurKey(); String strValue = attrIter.getCurString(); processServerCmd_Ver3(strCmd,strObject,strAttrib,strValue); } } if ( getSyncType().compare("none") == 0 ) continue; int nSyncObjectCount = getNotify().incLastSyncObjectCount(getID()); if ( getProgressStep() > 0 && (nSyncObjectCount%getProgressStep() == 0) ) getNotify().fireSyncNotification(this, false, RhoAppAdapter.ERR_NONE, ""); if ( getDB().isUIWaitDB() ) { LOG(INFO) + "Commit transaction because of UI request."; getDB().endTransaction(); CSyncThread::getInstance()->sleep(1000); getDB().startTransaction(); } } }
TEST( RocksRecordStoreTest, Truncate1 ) { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); { rocksdb::ColumnFamilyHandle* cf1; rocksdb::ColumnFamilyHandle* cf1_m; rocksdb::Status status; status = db->CreateColumnFamily( getColumnFamilyOptions(), "foo.bar1", &cf1 ); ASSERT_OK( toMongoStatus( status ) ); status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar1&", &cf1_m ); ASSERT_OK( toMongoStatus( status ) ); RocksRecordStore rs( "foo.bar", db.get(), cf1, cf1_m ); string s = "antonio was here"; { MyOperationContext opCtx( db.get() ); WriteUnitOfWork uow( opCtx.recoveryUnit() ); StatusWith<DiskLoc> res = rs.insertRecord( &opCtx, s.c_str(), s.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); res = rs.insertRecord( &opCtx, s.c_str(), s.size() + 1, -1 ); ASSERT_OK( res.getStatus() ); } { MyOperationContext opCtx( db.get() ); WriteUnitOfWork uow( opCtx.recoveryUnit() ); Status stat = rs.truncate( &opCtx ); ASSERT_OK( stat ); ASSERT_EQUALS( 0, rs.numRecords() ); ASSERT_EQUALS( 0, rs.dataSize() ); } // Test that truncate does not fail on an empty collection { MyOperationContext opCtx( db.get() ); WriteUnitOfWork uow( opCtx.recoveryUnit() ); Status stat = rs.truncate( &opCtx ); ASSERT_OK( stat ); ASSERT_EQUALS( 0, rs.numRecords() ); ASSERT_EQUALS( 0, rs.dataSize() ); } } }
TEST( RocksRecordStoreTest, TwoCollections ) { unittest::TempDir td( _rocksRecordStoreTestDir ); scoped_ptr<rocksdb::DB> db( getDB( td.path() ) ); rocksdb::ColumnFamilyHandle* cf1; rocksdb::ColumnFamilyHandle* cf2; rocksdb::ColumnFamilyHandle* cf1_m; rocksdb::ColumnFamilyHandle* cf2_m; rocksdb::Status status; status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar1", &cf1 ); ASSERT_OK( toMongoStatus( status ) ); status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar2", &cf2 ); ASSERT_OK( toMongoStatus( status ) ); status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar1&", &cf1_m ); ASSERT_OK( toMongoStatus( status ) ); status = db->CreateColumnFamily( rocksdb::ColumnFamilyOptions(), "foo.bar2&", &cf2_m ); ASSERT_OK( toMongoStatus( status ) ); RocksRecordStore rs1( "foo.bar1", db.get(), cf1, cf1_m ); RocksRecordStore rs2( "foo.bar2", db.get(), cf2, cf2_m ); DiskLoc a; DiskLoc b; { MyOperationContext opCtx( db.get() ); WriteUnitOfWork uow( opCtx.recoveryUnit() ); StatusWith<DiskLoc> result = rs1.insertRecord( &opCtx, "a", 2, -1 ); ASSERT_OK( result.getStatus() ); a = result.getValue(); result = rs2.insertRecord( &opCtx, "b", 2, -1 ); ASSERT_OK( result.getStatus() ); b = result.getValue(); } ASSERT_EQUALS( a, b ); ASSERT_EQUALS( string("a"), rs1.dataFor( a ).data() ); ASSERT_EQUALS( string("b"), rs2.dataFor( b ).data() ); delete cf2; delete cf1; }