PassRefPtr<Database> DatabaseManager::openDatabase(ScriptExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, DatabaseError& error) { ScriptController::initializeThreading(); ASSERT(error == DatabaseError::None); bool setVersionInNewDatabase = !creationCallback; String errorMessage; RefPtr<DatabaseBackendBase> backend = openDatabaseBackend(context, DatabaseType::Async, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage); if (!backend) return 0; RefPtr<Database> database = Database::create(context, backend); RefPtr<DatabaseContext> databaseContext = databaseContextFor(context); databaseContext->setHasOpenDatabases(); InspectorInstrumentation::didOpenDatabase(context, database, context->securityOrigin()->host(), name, expectedVersion); if (backend->isNew() && creationCallback.get()) { LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database.get()); database->m_scriptExecutionContext->postTask([creationCallback, database] (ScriptExecutionContext&) { creationCallback->handleEvent(database.get()); }); } ASSERT(database); return database.release(); }
PassRefPtr<DatabaseBackendBase> DatabaseManager::openDatabaseBackend(ScriptExecutionContext* context, DatabaseType type, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError& error, String& errorMessage) { ASSERT(error == DatabaseError::None); RefPtr<DatabaseContext> databaseContext = databaseContextFor(context); RefPtr<DatabaseBackendContext> backendContext = databaseContext->backend(); RefPtr<DatabaseBackendBase> backend = m_server->openDatabase(backendContext, type, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage); if (!backend) { ASSERT(error != DatabaseError::None); switch (error) { case DatabaseError::DatabaseIsBeingDeleted: case DatabaseError::DatabaseSizeOverflowed: case DatabaseError::GenericSecurityError: logOpenDatabaseError(context, name); return 0; case DatabaseError::InvalidDatabaseState: logErrorMessage(context, errorMessage); return 0; case DatabaseError::DatabaseSizeExceededQuota: // Notify the client that we've exceeded the database quota. // The client may want to increase the quota, and we'll give it // one more try after if that is the case. { ProposedDatabase proposedDb(*this, context->securityOrigin(), name, displayName, estimatedSize); databaseContext->databaseExceededQuota(name, proposedDb.details()); } error = DatabaseError::None; backend = m_server->openDatabase(backendContext, type, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage, AbstractDatabaseServer::RetryOpenDatabase); break; default: ASSERT_NOT_REACHED(); } if (!backend) { ASSERT(error != DatabaseError::None); if (error == DatabaseError::InvalidDatabaseState) { logErrorMessage(context, errorMessage); return 0; } logOpenDatabaseError(context, name); return 0; } } return backend.release(); }
PassRefPtr<DatabaseBackendBase> DatabaseManager::openDatabaseBackend(ScriptExecutionContext* context, DatabaseType type, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError& error, String& errorMessage) { ASSERT(error == DatabaseError::None); RefPtr<DatabaseContext> databaseContext = databaseContextFor(context); RefPtr<DatabaseBackendContext> backendContext = databaseContext->backend(); RefPtr<DatabaseBackendBase> backend = m_server->openDatabase(backendContext, type, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage); if (!backend) { ASSERT(error != DatabaseError::None); switch (error) { case DatabaseError::DatabaseIsBeingDeleted: case DatabaseError::DatabaseSizeOverflowed: case DatabaseError::GenericSecurityError: case DatabaseError::DatabaseSizeExceededQuota: logOpenDatabaseError(context, name); return 0; case DatabaseError::InvalidDatabaseState: logErrorMessage(context, errorMessage); return 0; default: ASSERT_NOT_REACHED(); } } return backend.release(); }
Database* DatabaseManager::openDatabaseInternal(ExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError& error, String& errorMessage) { ASSERT(error == DatabaseError::None); DatabaseContext* backendContext = databaseContextFor(context)->backend(); if (DatabaseTracker::tracker().canEstablishDatabase(backendContext, name, displayName, estimatedSize, error)) { Database* backend = new Database(backendContext, name, expectedVersion, displayName, estimatedSize); if (backend->openAndVerifyVersion(setVersionInNewDatabase, error, errorMessage)) return backend; } ASSERT(error != DatabaseError::None); switch (error) { case DatabaseError::GenericSecurityError: logOpenDatabaseError(context, name); return nullptr; case DatabaseError::InvalidDatabaseState: logErrorMessage(context, errorMessage); return nullptr; default: ASSERT_NOT_REACHED(); } return nullptr; }
Database* DatabaseManager::openDatabase(ExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, DatabaseCallback* creationCallback, DatabaseError& error, String& errorMessage) { ASSERT(error == DatabaseError::None); bool setVersionInNewDatabase = !creationCallback; Database* database = openDatabaseInternal(context, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage); if (!database) return nullptr; databaseContextFor(context)->setHasOpenDatabases(); DatabaseClient::from(context)->didOpenDatabase(database, context->getSecurityOrigin()->host(), name, expectedVersion); if (database->isNew() && creationCallback) { WTF_LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database); database->getExecutionContext()->postTask(BLINK_FROM_HERE, DatabaseCreationCallbackTask::create(database, creationCallback)); } ASSERT(database); return database; }