Status MMAPV1DatabaseCatalogEntry::dropCollection( OperationContext* txn, const StringData& ns ) {
        invariant( txn->lockState()->isWriteLocked( ns ) );
        _removeFromCache( ns );

        NamespaceDetails* details = _namespaceIndex.details( ns );

        if ( !details ) {
            return Status( ErrorCodes::NamespaceNotFound, str::stream() << "ns not found: " << ns );
        }

        invariant( details->nIndexes == 0 ); // TODO: delete instead?
        invariant( details->indexBuildsInProgress == 0 ); // TODO: delete instead?

        _removeNamespaceFromNamespaceCollection( txn, ns );

        // free extents
        if( !details->firstExtent.isNull() ) {
            _extentManager.freeExtents(txn, details->firstExtent, details->lastExtent);
            *txn->recoveryUnit()->writing( &details->firstExtent ) = DiskLoc().setInvalid();
            *txn->recoveryUnit()->writing( &details->lastExtent ) = DiskLoc().setInvalid();
        }

        // remove from the catalog hashtable
        _namespaceIndex.kill_ns( txn, ns );

        return Status::OK();
    }
Esempio n. 2
0
bool QgsOracleTableCache::saveToCache( const QString& connName, CacheFlags flags, const QVector<QgsOracleLayerProperty>& layers )
{
  sqlite3* db = _openCacheDatabase();
  if ( !db )
    return false;

  QString tblNameRaw = "oracle_" + connName;
  QString tblName = QgsOracleConn::quotedIdentifier( tblNameRaw );

  // recreate the cache table

  if ( !_removeFromCache( db, connName ) )
  {
    sqlite3_close( db );
    return false;
  }

  QString sqlCreateTable = QString( "CREATE TABLE %1 (ownername text, tablename text, geometrycolname text, isview int, sql text, pkcols text, geomtypes text, geomsrids text)" ).arg( tblName );
  QString sqlInsertToMeta = QString( "INSERT INTO meta_oracle VALUES (%1, %2)" ).arg( QgsOracleConn::quotedValue( connName ) ).arg(( int ) flags );

  bool res1 = _executeSqliteStatement( db, sqlCreateTable );
  bool res2 = _executeSqliteStatement( db, sqlInsertToMeta );
  if ( !res1 || !res2 )
  {
    sqlite3_close( db );
    return false;
  }

  // insert data

  _executeSqliteStatement( db, "BEGIN" );

  QString sqlInsert = QString( "INSERT INTO %1 VALUES(?,?,?,?,?,?,?,?)" ).arg( tblName );
  sqlite3_stmt* stmtInsert;
  if ( sqlite3_prepare_v2( db, sqlInsert.toUtf8().data(), -1, &stmtInsert, 0 ) != SQLITE_OK )
  {
    sqlite3_close( db );
    return false;
  }

  bool insertOk = true;
  Q_FOREACH ( const QgsOracleLayerProperty& item, layers )
  {
    sqlite3_bind_text( stmtInsert, 1, item.ownerName.toUtf8().data(), -1, SQLITE_TRANSIENT );
    sqlite3_bind_text( stmtInsert, 2, item.tableName.toUtf8().data(), -1, SQLITE_TRANSIENT );
    sqlite3_bind_text( stmtInsert, 3, item.geometryColName.toUtf8().data(), -1, SQLITE_TRANSIENT );
    sqlite3_bind_int( stmtInsert, 4, item.isView );
    sqlite3_bind_text( stmtInsert, 5, item.sql.toUtf8().data(), -1, SQLITE_TRANSIENT );

    sqlite3_bind_text( stmtInsert, 6, item.pkCols.join( "," ).toUtf8().data(), -1, SQLITE_TRANSIENT );

    QStringList geomTypes;
    Q_FOREACH ( QGis::WkbType geomType, item.types )
      geomTypes.append( QString::number( static_cast<ulong>( geomType ) ) );
    sqlite3_bind_text( stmtInsert, 7, geomTypes.join( "," ).toUtf8().data(), -1, SQLITE_TRANSIENT );

    QStringList geomSrids;
    Q_FOREACH ( int geomSrid, item.srids )
      geomSrids.append( QString::number( geomSrid ) );
    sqlite3_bind_text( stmtInsert, 8, geomSrids.join( "," ).toUtf8().data(), -1, SQLITE_TRANSIENT );

    if ( sqlite3_step( stmtInsert ) != SQLITE_DONE )
      insertOk = false;

    sqlite3_reset( stmtInsert );
  }
    Status MMAPV1DatabaseCatalogEntry::_renameSingleNamespace( OperationContext* txn,
                                                              const StringData& fromNS,
                                                              const StringData& toNS,
                                                              bool stayTemp ) {
        // some sanity checking
        NamespaceDetails* fromDetails = _namespaceIndex.details( fromNS );
        if ( !fromDetails )
            return Status( ErrorCodes::BadValue, "from namespace doesn't exist" );

        if ( _namespaceIndex.details( toNS ) )
            return Status( ErrorCodes::BadValue, "to namespace already exists" );

        _removeFromCache( fromNS );

        // at this point, we haven't done anything destructive yet

        // ----
        // actually start moving
        // ----

        // this could throw, but if it does we're ok
        _namespaceIndex.add_ns( txn, toNS, fromDetails );
        NamespaceDetails* toDetails = _namespaceIndex.details( toNS );

        try {
            toDetails->copyingFrom(txn,
                                   toNS,
                                   _namespaceIndex,
                                   fromDetails); // fixes extraOffset
        }
        catch( DBException& ) {
            // could end up here if .ns is full - if so try to clean up / roll back a little
            _namespaceIndex.kill_ns( txn, toNS );
            throw;
        }

        // at this point, code .ns stuff moved

        _namespaceIndex.kill_ns( txn, fromNS );
        fromDetails = NULL;

        // fix system.namespaces
        BSONObj newSpec;
        DiskLoc oldSpecLocation;
        {

            BSONObj oldSpec;
            {
                RecordStoreV1Base* rs = _getNamespaceRecordStore();
                scoped_ptr<RecordIterator> it( rs->getIterator(txn) );
                while ( !it->isEOF() ) {
                    DiskLoc loc = it->getNext();
                    BSONObj entry = it->dataFor( loc ).toBson();
                    if ( fromNS == entry["name"].String() ) {
                        oldSpecLocation = loc;
                        oldSpec = entry.getOwned();
                        break;
                    }
                }
            }
            invariant( !oldSpec.isEmpty() );
            invariant( !oldSpecLocation.isNull() );

            BSONObjBuilder b;
            BSONObjIterator i( oldSpec.getObjectField( "options" ) );
            while( i.more() ) {
                BSONElement e = i.next();
                if ( strcmp( e.fieldName(), "create" ) != 0 ) {
                    if (stayTemp || (strcmp(e.fieldName(), "temp") != 0))
                        b.append( e );
                }
                else {
                    b << "create" << toNS;
                }
            }
            newSpec = b.obj();
        }

        _addNamespaceToNamespaceCollection( txn, toNS, newSpec.isEmpty() ? 0 : &newSpec );

        _getNamespaceRecordStore()->deleteRecord( txn, oldSpecLocation );

        boost::mutex::scoped_lock lk( _collectionsLock );
        Entry*& entry = _collections[toNS.toString()];
        invariant( entry == NULL );
        entry = new Entry();
        _fillInEntry_inlock( txn, toNS, entry );

        return Status::OK();
    }