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();
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}