nsresult DOMStorageDBThread::InitDatabase() { Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_INIT_DATABASE_MS> timer; nsresult rv; // Here we are on the worker thread. This opens the worker connection. MOZ_ASSERT(!NS_IsMainThread()); rv = OpenDatabaseConnection(); NS_ENSURE_SUCCESS(rv, rv); rv = TryJournalMode(); NS_ENSURE_SUCCESS(rv, rv); // Create a read-only clone (void)mWorkerConnection->Clone(true, getter_AddRefs(mReaderConnection)); NS_ENSURE_TRUE(mReaderConnection, NS_ERROR_FAILURE); rv = DOMStorageDBUpdater::Update(mWorkerConnection); NS_ENSURE_SUCCESS(rv, rv); // Database open and all initiation operation are done. Switching this flag // to true allow main thread to read directly from the database. // If we would allow this sooner, we would have opened a window where main thread // read might operate on a totaly broken and incosistent database. mDBReady = true; // List scopes having any stored data nsCOMPtr<mozIStorageStatement> stmt; // Note: result of this select must match DOMStorageManager::CreateOrigin() rv = mWorkerConnection->CreateStatement(NS_LITERAL_CSTRING( "SELECT DISTINCT originAttributes || ':' || originKey FROM webappsstore2"), getter_AddRefs(stmt)); NS_ENSURE_SUCCESS(rv, rv); mozStorageStatementScoper scope(stmt); bool exists; while (NS_SUCCEEDED(rv = stmt->ExecuteStep(&exists)) && exists) { nsAutoCString foundOrigin; rv = stmt->GetUTF8String(0, foundOrigin); NS_ENSURE_SUCCESS(rv, rv); MonitorAutoLock monitor(mThreadObserver->GetMonitor()); mOriginsHavingData.PutEntry(foundOrigin); } return NS_OK; }
nsresult StorageDBThread::OpenAndUpdateDatabase() { nsresult rv; // Here we are on the worker thread. This opens the worker connection. MOZ_ASSERT(!NS_IsMainThread()); rv = OpenDatabaseConnection(); NS_ENSURE_SUCCESS(rv, rv); rv = TryJournalMode(); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
nsresult DOMStorageDBThread::InitDatabase() { Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_INIT_DATABASE_MS> timer; nsresult rv; // Here we are on the worker thread. This opens the worker connection. MOZ_ASSERT(!NS_IsMainThread()); rv = OpenDatabaseConnection(); NS_ENSURE_SUCCESS(rv, rv); rv = TryJournalMode(); NS_ENSURE_SUCCESS(rv, rv); // Create a read-only clone (void)mWorkerConnection->Clone(true, getter_AddRefs(mReaderConnection)); NS_ENSURE_TRUE(mReaderConnection, NS_ERROR_FAILURE); mozStorageTransaction transaction(mWorkerConnection, false); // Ensure Goanna 1.9.1 storage table rv = mWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "CREATE TABLE IF NOT EXISTS webappsstore2 (" "scope TEXT, " "key TEXT, " "value TEXT, " "secure INTEGER, " "owner TEXT)")); NS_ENSURE_SUCCESS(rv, rv); rv = mWorkerConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING( "CREATE UNIQUE INDEX IF NOT EXISTS scope_key_index" " ON webappsstore2(scope, key)")); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<mozIStorageFunction> function1(new nsReverseStringSQLFunction()); NS_ENSURE_TRUE(function1, NS_ERROR_OUT_OF_MEMORY); rv = mWorkerConnection->CreateFunction(NS_LITERAL_CSTRING("REVERSESTRING"), 1, function1); NS_ENSURE_SUCCESS(rv, rv); bool exists; // Check if there is storage of Goanna 1.9.0 and if so, upgrade that storage // to actual webappsstore2 table and drop the obsolete table. First process // this newer table upgrade to priority potential duplicates from older // storage table. rv = mWorkerConnection->TableExists(NS_LITERAL_CSTRING("webappsstore"), &exists); NS_ENSURE_SUCCESS(rv, rv); if (exists) { rv = mWorkerConnection->ExecuteSimpleSQL( NS_LITERAL_CSTRING("INSERT OR IGNORE INTO " "webappsstore2(scope, key, value, secure, owner) " "SELECT REVERSESTRING(domain) || '.:', key, value, secure, owner " "FROM webappsstore")); NS_ENSURE_SUCCESS(rv, rv); rv = mWorkerConnection->ExecuteSimpleSQL( NS_LITERAL_CSTRING("DROP TABLE webappsstore")); NS_ENSURE_SUCCESS(rv, rv); } // Check if there is storage of Goanna 1.8 and if so, upgrade that storage // to actual webappsstore2 table and drop the obsolete table. Potential // duplicates will be ignored. rv = mWorkerConnection->TableExists(NS_LITERAL_CSTRING("moz_webappsstore"), &exists); NS_ENSURE_SUCCESS(rv, rv); if (exists) { rv = mWorkerConnection->ExecuteSimpleSQL( NS_LITERAL_CSTRING("INSERT OR IGNORE INTO " "webappsstore2(scope, key, value, secure, owner) " "SELECT REVERSESTRING(domain) || '.:', key, value, secure, domain " "FROM moz_webappsstore")); NS_ENSURE_SUCCESS(rv, rv); rv = mWorkerConnection->ExecuteSimpleSQL( NS_LITERAL_CSTRING("DROP TABLE moz_webappsstore")); NS_ENSURE_SUCCESS(rv, rv); } rv = transaction.Commit(); NS_ENSURE_SUCCESS(rv, rv); // Database open and all initiation operation are done. Switching this flag // to true allow main thread to read directly from the database. // If we would allow this sooner, we would have opened a window where main thread // read might operate on a totaly broken and incosistent database. mDBReady = true; // List scopes having any stored data nsCOMPtr<mozIStorageStatement> stmt; rv = mWorkerConnection->CreateStatement(NS_LITERAL_CSTRING("SELECT DISTINCT scope FROM webappsstore2"), getter_AddRefs(stmt)); NS_ENSURE_SUCCESS(rv, rv); mozStorageStatementScoper scope(stmt); while (NS_SUCCEEDED(rv = stmt->ExecuteStep(&exists)) && exists) { nsAutoCString foundScope; rv = stmt->GetUTF8String(0, foundScope); NS_ENSURE_SUCCESS(rv, rv); MonitorAutoLock monitor(mThreadObserver->GetMonitor()); mScopesHavingData.PutEntry(foundScope); } return NS_OK; }