void MMAPV1DatabaseCatalogEntry::_removeNamespaceFromNamespaceCollection(OperationContext* txn, StringData ns) { if (nsToCollectionSubstring(ns) == "system.namespaces") { // system.namespaces holds all the others, so it is not explicitly listed in the catalog. return; } auto entry = _collections.find(ns.toString()); if (entry == _collections.end()) { return; } RecordStoreV1Base* rs = _getNamespaceRecordStore(); invariant(rs); rs->deleteRecord(txn, entry->second->catalogEntry->getNamespacesRecordId()); }
void MMAPV1DatabaseCatalogEntry::_removeNamespaceFromNamespaceCollection( OperationContext* txn, const StringData& ns ) { if ( nsToCollectionSubstring( ns ) == "system.namespaces" ) { // system.namespaces holds all the others, so it is not explicitly listed in the catalog. return; } RecordStoreV1Base* rs = _getNamespaceRecordStore(); invariant( rs ); scoped_ptr<RecordIterator> it( rs->getIterator(txn) ); while ( !it->isEOF() ) { DiskLoc loc = it->getNext(); BSONObj entry = it->dataFor( loc ).toBson(); BSONElement name = entry["name"]; if ( name.type() == String && name.String() == ns ) { rs->deleteRecord( txn, loc ); break; } } }
Status MMAPV1DatabaseCatalogEntry::renameCollection( OperationContext* txn, const StringData& fromNS, const StringData& toNS, bool stayTemp ) { Status s = _renameSingleNamespace( txn, fromNS, toNS, stayTemp ); if ( !s.isOK() ) return s; NamespaceDetails* details = _namespaceIndex.details( toNS ); invariant( details ); RecordStoreV1Base* systemIndexRecordStore = _getIndexRecordStore( txn ); scoped_ptr<RecordIterator> it( systemIndexRecordStore->getIterator() ); while ( !it->isEOF() ) { DiskLoc loc = it->getNext(); const Record* rec = it->recordFor( loc ); BSONObj oldIndexSpec( rec->data() ); if ( fromNS != oldIndexSpec["ns"].valuestrsafe() ) continue; BSONObj newIndexSpec; { BSONObjBuilder b; BSONObjIterator i( oldIndexSpec ); while( i.more() ) { BSONElement e = i.next(); if ( strcmp( e.fieldName(), "ns" ) != 0 ) b.append( e ); else b << "ns" << toNS; } newIndexSpec = b.obj(); } StatusWith<DiskLoc> newIndexSpecLoc = systemIndexRecordStore->insertRecord( txn, newIndexSpec.objdata(), newIndexSpec.objsize(), -1 ); if ( !newIndexSpecLoc.isOK() ) return newIndexSpecLoc.getStatus(); const string& indexName = oldIndexSpec.getStringField( "name" ); { // fix IndexDetails pointer NamespaceDetailsCollectionCatalogEntry ce( toNS, details, _getIndexRecordStore( txn ), this ); int indexI = ce._findIndexNumber( indexName ); IndexDetails& indexDetails = details->idx(indexI); *txn->recoveryUnit()->writing(&indexDetails.info) = newIndexSpecLoc.getValue(); // XXX: dur } { // move underlying namespac string oldIndexNs = IndexDescriptor::makeIndexNamespace( fromNS, indexName ); string newIndexNs = IndexDescriptor::makeIndexNamespace( toNS, indexName ); Status s = _renameSingleNamespace( txn, oldIndexNs, newIndexNs, false ); if ( !s.isOK() ) return s; } systemIndexRecordStore->deleteRecord( txn, loc ); } return Status::OK(); }
Status MMAPV1DatabaseCatalogEntry::renameCollection(OperationContext* txn, StringData fromNS, StringData toNS, bool stayTemp) { Status s = _renameSingleNamespace(txn, fromNS, toNS, stayTemp); if (!s.isOK()) return s; NamespaceDetails* details = _namespaceIndex.details(toNS); invariant(details); RecordStoreV1Base* systemIndexRecordStore = _getIndexRecordStore(); auto cursor = systemIndexRecordStore->getCursor(txn); while (auto record = cursor->next()) { BSONObj oldIndexSpec = record->data.releaseToBson(); if (fromNS != oldIndexSpec["ns"].valuestrsafe()) continue; BSONObj newIndexSpec; { BSONObjBuilder b; BSONObjIterator i(oldIndexSpec); while (i.more()) { BSONElement e = i.next(); if (strcmp(e.fieldName(), "ns") != 0) b.append(e); else b << "ns" << toNS; } newIndexSpec = b.obj(); } StatusWith<RecordId> newIndexSpecLoc = systemIndexRecordStore->insertRecord( txn, newIndexSpec.objdata(), newIndexSpec.objsize(), false); if (!newIndexSpecLoc.isOK()) return newIndexSpecLoc.getStatus(); const std::string& indexName = oldIndexSpec.getStringField("name"); { // Fix the IndexDetails pointer. int indexI = getCollectionCatalogEntry(toNS)->_findIndexNumber(txn, indexName); IndexDetails& indexDetails = details->idx(indexI); *txn->recoveryUnit()->writing(&indexDetails.info) = DiskLoc::fromRecordId(newIndexSpecLoc.getValue()); } { // Move the underlying namespace. std::string oldIndexNs = IndexDescriptor::makeIndexNamespace(fromNS, indexName); std::string newIndexNs = IndexDescriptor::makeIndexNamespace(toNS, indexName); Status s = _renameSingleNamespace(txn, oldIndexNs, newIndexNs, false); if (!s.isOK()) return s; } systemIndexRecordStore->deleteRecord(txn, record->id); } return Status::OK(); }