⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 database.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    m_document->databaseThread()->unscheduleDatabaseTasks(this);    RefPtr<DatabaseCloseTask> task = DatabaseCloseTask::create(this);    task->lockForSynchronousScheduling();    m_document->databaseThread()->scheduleImmediateTask(task);    task->waitForSynchronousCompletion();}void Database::close(){    m_sqliteDatabase.close();}void Database::stop(){    // FIXME: The net effect of the following code is to remove all pending transactions and statements, but allow the current statement    // to run to completion.  In the future we can use the sqlite3_progress_handler or sqlite3_interrupt interfaces to cancel the current    // statement in response to close(), as well.        // This method is meant to be used as an analog to cancelling a loader, and is used when a document is shut down as the result of     // a page load or closing the page    m_stopped = true;    {        MutexLocker locker(m_transactionInProgressMutex);        m_transactionQueue.kill();        m_transactionInProgress = false;    }}unsigned long long Database::databaseSize() const{    long long size;    if (!getFileSize(m_filename, size))        size = 0;    return size;}unsigned long long Database::maximumSize() const{    // The maximum size for this database is the full quota for this origin, minus the current usage within this origin,    // except for the current usage of this database        OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager());    Locker<OriginQuotaManager> locker(manager);        return DatabaseTracker::tracker().quotaForOrigin(m_securityOrigin.get()) - manager.diskUsage(m_securityOrigin.get()) + databaseSize();}void Database::disableAuthorizer(){    ASSERT(m_databaseAuthorizer);    m_databaseAuthorizer->disable();}void Database::enableAuthorizer(){    ASSERT(m_databaseAuthorizer);    m_databaseAuthorizer->enable();}static int guidForOriginAndName(const String& origin, const String& name){    String stringID;    if (origin.endsWith("/"))        stringID = origin + name;    else        stringID = origin + "/" + name;    // Note: We don't have to use AtomicallyInitializedStatic here because    // this function is called once in the constructor on the main thread    // before any other threads that call this function are used.    DEFINE_STATIC_LOCAL(Mutex, stringIdentifierMutex, ());    MutexLocker locker(stringIdentifierMutex);    typedef HashMap<String, int> IDGuidMap;    DEFINE_STATIC_LOCAL(IDGuidMap, stringIdentifierToGUIDMap, ());    int guid = stringIdentifierToGUIDMap.get(stringID);    if (!guid) {        static int currentNewGUID = 1;        guid = currentNewGUID++;        stringIdentifierToGUIDMap.set(stringID, guid);    }    return guid;}void Database::resetAuthorizer(){    if (m_databaseAuthorizer)        m_databaseAuthorizer->reset();}void Database::performPolicyChecks(){    // FIXME: Code similar to the following will need to be run to enforce the per-origin size limit the spec mandates.    // Additionally, we might need a way to pause the database thread while the UA prompts the user for permission to    // increase the size limit    /*    if (m_databaseAuthorizer->lastActionIncreasedSize())        DatabaseTracker::scheduleFileSizeCheckOnMainThread(this);    */    notImplemented();}bool Database::performOpenAndVerify(ExceptionCode& e){    if (!m_sqliteDatabase.open(m_filename)) {        LOG_ERROR("Unable to open database at path %s", m_filename.ascii().data());        e = INVALID_STATE_ERR;        return false;    }    ASSERT(m_databaseAuthorizer);    m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer);    if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) {        if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {            LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data());            e = INVALID_STATE_ERR;            return false;        }    }    String currentVersion;    {        MutexLocker locker(guidMutex());        currentVersion = guidToVersionMap().get(m_guid);        if (currentVersion.isNull())            LOG(StorageAPI, "Current cached version for guid %i is null", m_guid);        else            LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data());        if (currentVersion.isNull()) {            if (!getVersionFromDatabase(currentVersion)) {                LOG_ERROR("Failed to get current version from database %s", databaseDebugName().ascii().data());                e = INVALID_STATE_ERR;                return false;            }            if (currentVersion.length()) {                LOG(StorageAPI, "Retrieved current version %s from database %s", currentVersion.ascii().data(), databaseDebugName().ascii().data());            } else {                LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());                if (!setVersionInDatabase(m_expectedVersion)) {                    LOG_ERROR("Failed to set version %s in database %s", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());                    e = INVALID_STATE_ERR;                    return false;                }                currentVersion = m_expectedVersion;            }            guidToVersionMap().set(m_guid, currentVersion.copy());        }    }    if (currentVersion.isNull()) {        LOG(StorageAPI, "Database %s does not have its version set", databaseDebugName().ascii().data());        currentVersion = "";    }    // FIXME: For now, the spec says that if the database has no version, it is valid for any "Expected version" string.  That seems silly and I think it should be    // changed, and here's where we would change it    if (m_expectedVersion.length()) {        if (currentVersion.length() && m_expectedVersion != currentVersion) {            LOG(StorageAPI, "page expects version %s from database %s, which actually has version name %s - openDatabase() call will fail", m_expectedVersion.ascii().data(),                databaseDebugName().ascii().data(), currentVersion.ascii().data());            e = INVALID_STATE_ERR;            return false;        }    }    return true;}void Database::changeVersion(const String& oldVersion, const String& newVersion,                              PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,                             PassRefPtr<VoidCallback> successCallback){    m_transactionQueue.append(SQLTransaction::create(this, callback, errorCallback, successCallback, ChangeVersionWrapper::create(oldVersion, newVersion)));    MutexLocker locker(m_transactionInProgressMutex);    if (!m_transactionInProgress)        scheduleTransaction();}void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,                           PassRefPtr<VoidCallback> successCallback){    m_transactionQueue.append(SQLTransaction::create(this, callback, errorCallback, successCallback, 0));    MutexLocker locker(m_transactionInProgressMutex);    if (!m_transactionInProgress)        scheduleTransaction();}void Database::scheduleTransaction(){    ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller.    RefPtr<SQLTransaction> transaction;    if (m_transactionQueue.tryGetMessage(transaction) && m_document->databaseThread()) {        RefPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);        LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction());        m_transactionInProgress = true;        m_document->databaseThread()->scheduleTask(task.release());    } else        m_transactionInProgress = false;}void Database::scheduleTransactionStep(SQLTransaction* transaction){    if (m_document->databaseThread()) {        RefPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction);        LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get());        m_document->databaseThread()->scheduleTask(task.release());    }}void Database::scheduleTransactionCallback(SQLTransaction* transaction){    transaction->ref();    callOnMainThread(deliverPendingCallback, transaction);}Vector<String> Database::performGetTableNames(){    disableAuthorizer();    SQLiteStatement statement(m_sqliteDatabase, "SELECT name FROM sqlite_master WHERE type='table';");    if (statement.prepare() != SQLResultOk) {        LOG_ERROR("Unable to retrieve list of tables for database %s", databaseDebugName().ascii().data());        enableAuthorizer();        return Vector<String>();    }    Vector<String> tableNames;    int result;    while ((result = statement.step()) == SQLResultRow) {        String name = statement.getColumnText(0);        if (name != databaseInfoTableName())            tableNames.append(name);    }    enableAuthorizer();    if (result != SQLResultDone) {        LOG_ERROR("Error getting tables for database %s", databaseDebugName().ascii().data());        return Vector<String>();    }    return tableNames;}String Database::version() const{    if (m_deleted)        return String();    MutexLocker locker(guidMutex());    return guidToVersionMap().get(m_guid).copy();}void Database::deliverPendingCallback(void* context){    SQLTransaction* transaction = static_cast<SQLTransaction*>(context);    transaction->performPendingCallback();    transaction->deref(); // Was ref'd in scheduleTransactionCallback().}Vector<String> Database::tableNames(){    if (!m_document->databaseThread())        return Vector<String>();    RefPtr<DatabaseTableNamesTask> task = DatabaseTableNamesTask::create(this);    task->lockForSynchronousScheduling();    m_document->databaseThread()->scheduleImmediateTask(task);    task->waitForSynchronousCompletion();    return task->tableNames();}void Database::setExpectedVersion(const String& version){    m_expectedVersion = version.copy();}PassRefPtr<SecurityOrigin> Database::securityOriginCopy() const{    return m_securityOrigin->copy();}String Database::stringIdentifier() const{    // Return a deep copy for ref counting thread safety    return m_name.copy();}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -