2020-09-09 15:39:33 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "DBSchema.h"
|
|
|
|
|
2020-11-23 19:21:38 +03:00
|
|
|
// local includes
|
|
|
|
#include "ActorsParentCommon.h"
|
|
|
|
#include "IndexedDBCommon.h"
|
|
|
|
|
2020-09-09 15:39:33 +03:00
|
|
|
// global includes
|
|
|
|
#include "ErrorList.h"
|
|
|
|
#include "js/StructuredClone.h"
|
|
|
|
#include "mozIStorageConnection.h"
|
2022-10-28 11:22:49 +03:00
|
|
|
#include "mozilla/dom/quota/Assertions.h"
|
2020-09-09 15:39:33 +03:00
|
|
|
#include "mozilla/dom/quota/QuotaCommon.h"
|
2021-11-30 08:05:51 +03:00
|
|
|
#include "mozilla/dom/quota/ResultExtensions.h"
|
Bug 1691589 - Reduce reliance on GeckoProfiler.h when only labels (and maybe markers) are needed - r=necko-reviewers,geckoview-reviewers,sg,agi,florian
There are no code changes, only #include changes.
It was a fairly mechanical process: Search for all "AUTO_PROFILER_LABEL", and in each file, if only labels are used, convert "GeckoProfiler.h" into "ProfilerLabels.h" (or just add that last one where needed).
In some files, there were also some marker calls but no other profiler-related calls, in these cases "GeckoProfiler.h" was replaced with both "ProfilerLabels.h" and "ProfilerMarkers.h", which still helps in reducing the use of the all-encompassing "GeckoProfiler.h".
Differential Revision: https://phabricator.services.mozilla.com/D104588
2021-02-16 07:44:19 +03:00
|
|
|
#include "mozilla/ProfilerLabels.h"
|
2020-09-09 15:39:33 +03:00
|
|
|
#include "nsDebug.h"
|
|
|
|
#include "nsError.h"
|
|
|
|
#include "nsLiteralString.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
|
|
|
|
namespace mozilla::dom::indexedDB {
|
|
|
|
|
2020-10-20 11:33:20 +03:00
|
|
|
using quota::AssertIsOnIOThread;
|
|
|
|
|
2020-09-09 15:39:33 +03:00
|
|
|
// If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
|
|
|
|
// schema version.
|
|
|
|
static_assert(JS_STRUCTURED_CLONE_VERSION == 8,
|
|
|
|
"Need to update the major schema version.");
|
|
|
|
|
|
|
|
nsresult CreateFileTables(mozIStorageConnection& aConnection) {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
|
|
|
|
AUTO_PROFILER_LABEL("CreateFileTables", DOM);
|
|
|
|
|
2020-10-20 11:33:20 +03:00
|
|
|
constexpr nsLiteralCString commands[] = {
|
|
|
|
// Table `file`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE file ("
|
|
|
|
"id INTEGER PRIMARY KEY, "
|
|
|
|
"refcount INTEGER NOT NULL"
|
2020-10-20 11:33:20 +03:00
|
|
|
");"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TRIGGER object_data_insert_trigger "
|
|
|
|
"AFTER INSERT ON object_data "
|
|
|
|
"FOR EACH ROW "
|
|
|
|
"WHEN NEW.file_ids IS NOT NULL "
|
|
|
|
"BEGIN "
|
|
|
|
"SELECT update_refcount(NULL, NEW.file_ids); "
|
2020-10-20 11:33:20 +03:00
|
|
|
"END;"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TRIGGER object_data_update_trigger "
|
|
|
|
"AFTER UPDATE OF file_ids ON object_data "
|
|
|
|
"FOR EACH ROW "
|
|
|
|
"WHEN OLD.file_ids IS NOT NULL OR NEW.file_ids IS NOT NULL "
|
|
|
|
"BEGIN "
|
|
|
|
"SELECT update_refcount(OLD.file_ids, NEW.file_ids); "
|
2020-10-20 11:33:20 +03:00
|
|
|
"END;"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TRIGGER object_data_delete_trigger "
|
|
|
|
"AFTER DELETE ON object_data "
|
|
|
|
"FOR EACH ROW WHEN OLD.file_ids IS NOT NULL "
|
|
|
|
"BEGIN "
|
|
|
|
"SELECT update_refcount(OLD.file_ids, NULL); "
|
2020-10-20 11:33:20 +03:00
|
|
|
"END;"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TRIGGER file_update_trigger "
|
|
|
|
"AFTER UPDATE ON file "
|
|
|
|
"FOR EACH ROW WHEN NEW.refcount = 0 "
|
|
|
|
"BEGIN "
|
|
|
|
"DELETE FROM file WHERE id = OLD.id; "
|
2020-10-20 11:33:20 +03:00
|
|
|
"END;"_ns};
|
|
|
|
|
2021-09-24 16:08:30 +03:00
|
|
|
QM_TRY(MOZ_TO_RESULT(ExecuteSimpleSQLSequence(aConnection, commands)));
|
2020-09-09 15:39:33 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult CreateTables(mozIStorageConnection& aConnection) {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
|
|
|
|
AUTO_PROFILER_LABEL("CreateTables", DOM);
|
|
|
|
|
2020-10-20 11:33:20 +03:00
|
|
|
constexpr nsLiteralCString commands[] = {
|
|
|
|
// Table `database`
|
2020-09-09 15:39:33 +03:00
|
|
|
|
2020-10-20 11:33:20 +03:00
|
|
|
// There are two reasons for having the origin column.
|
|
|
|
// First, we can ensure that we don't have collisions in the origin hash
|
|
|
|
// we
|
|
|
|
// use for the path because when we open the db we can make sure that the
|
|
|
|
// origins exactly match. Second, chrome code crawling through the idb
|
|
|
|
// directory can figure out the origin of every db without having to
|
|
|
|
// reverse-engineer our hash scheme.
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE database"
|
|
|
|
"( name TEXT PRIMARY KEY"
|
|
|
|
", origin TEXT NOT NULL"
|
|
|
|
", version INTEGER NOT NULL DEFAULT 0"
|
|
|
|
", last_vacuum_time INTEGER NOT NULL DEFAULT 0"
|
|
|
|
", last_analyze_time INTEGER NOT NULL DEFAULT 0"
|
|
|
|
", last_vacuum_size INTEGER NOT NULL DEFAULT 0"
|
2020-10-20 11:33:20 +03:00
|
|
|
") WITHOUT ROWID;"_ns,
|
|
|
|
// Table `object_store`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE object_store"
|
|
|
|
"( id INTEGER PRIMARY KEY"
|
|
|
|
", auto_increment INTEGER NOT NULL DEFAULT 0"
|
|
|
|
", name TEXT NOT NULL"
|
|
|
|
", key_path TEXT"
|
2020-10-20 11:33:20 +03:00
|
|
|
");"_ns,
|
|
|
|
// Table `object_store_index`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE object_store_index"
|
|
|
|
"( id INTEGER PRIMARY KEY"
|
|
|
|
", object_store_id INTEGER NOT NULL"
|
|
|
|
", name TEXT NOT NULL"
|
|
|
|
", key_path TEXT NOT NULL"
|
|
|
|
", unique_index INTEGER NOT NULL"
|
|
|
|
", multientry INTEGER NOT NULL"
|
|
|
|
", locale TEXT"
|
|
|
|
", is_auto_locale BOOLEAN NOT NULL"
|
|
|
|
", FOREIGN KEY (object_store_id) "
|
|
|
|
"REFERENCES object_store(id) "
|
2020-10-20 11:33:20 +03:00
|
|
|
");"_ns,
|
|
|
|
// Table `object_data`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE object_data"
|
|
|
|
"( object_store_id INTEGER NOT NULL"
|
|
|
|
", key BLOB NOT NULL"
|
|
|
|
", index_data_values BLOB DEFAULT NULL"
|
|
|
|
", file_ids TEXT"
|
|
|
|
", data BLOB NOT NULL"
|
|
|
|
", PRIMARY KEY (object_store_id, key)"
|
|
|
|
", FOREIGN KEY (object_store_id) "
|
|
|
|
"REFERENCES object_store(id) "
|
2020-10-20 11:33:20 +03:00
|
|
|
") WITHOUT ROWID;"_ns,
|
|
|
|
// Table `index_data`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE index_data"
|
|
|
|
"( index_id INTEGER NOT NULL"
|
|
|
|
", value BLOB NOT NULL"
|
|
|
|
", object_data_key BLOB NOT NULL"
|
|
|
|
", object_store_id INTEGER NOT NULL"
|
|
|
|
", value_locale BLOB"
|
|
|
|
", PRIMARY KEY (index_id, value, object_data_key)"
|
|
|
|
", FOREIGN KEY (index_id) "
|
|
|
|
"REFERENCES object_store_index(id) "
|
|
|
|
", FOREIGN KEY (object_store_id, object_data_key) "
|
|
|
|
"REFERENCES object_data(object_store_id, key) "
|
2020-10-20 11:33:20 +03:00
|
|
|
") WITHOUT ROWID;"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE INDEX index_data_value_locale_index "
|
|
|
|
"ON index_data (index_id, value_locale, object_data_key, value) "
|
2020-10-20 11:33:20 +03:00
|
|
|
"WHERE value_locale IS NOT NULL;"_ns,
|
|
|
|
// Table `unique_index_data`
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE TABLE unique_index_data"
|
|
|
|
"( index_id INTEGER NOT NULL"
|
|
|
|
", value BLOB NOT NULL"
|
|
|
|
", object_store_id INTEGER NOT NULL"
|
|
|
|
", object_data_key BLOB NOT NULL"
|
|
|
|
", value_locale BLOB"
|
|
|
|
", PRIMARY KEY (index_id, value)"
|
|
|
|
", FOREIGN KEY (index_id) "
|
|
|
|
"REFERENCES object_store_index(id) "
|
|
|
|
", FOREIGN KEY (object_store_id, object_data_key) "
|
|
|
|
"REFERENCES object_data(object_store_id, key) "
|
2020-10-20 11:33:20 +03:00
|
|
|
") WITHOUT ROWID;"_ns,
|
2020-09-09 15:39:33 +03:00
|
|
|
"CREATE INDEX unique_index_data_value_locale_index "
|
|
|
|
"ON unique_index_data (index_id, value_locale, object_data_key, value) "
|
2020-10-20 11:33:20 +03:00
|
|
|
"WHERE value_locale IS NOT NULL;"_ns};
|
|
|
|
|
2021-09-24 16:08:30 +03:00
|
|
|
QM_TRY(MOZ_TO_RESULT(ExecuteSimpleSQLSequence(aConnection, commands)));
|
2020-10-20 11:33:20 +03:00
|
|
|
|
2021-09-24 16:08:30 +03:00
|
|
|
QM_TRY(MOZ_TO_RESULT(CreateFileTables(aConnection)));
|
2020-10-20 11:33:20 +03:00
|
|
|
|
2021-09-24 16:08:30 +03:00
|
|
|
QM_TRY(MOZ_TO_RESULT(aConnection.SetSchemaVersion(kSQLiteSchemaVersion)));
|
2020-09-09 15:39:33 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mozilla::dom::indexedDB
|