1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "ActorsParentCommon.h"
11 #include "IndexedDBCommon.h"
14 #include "ErrorList.h"
15 #include "js/StructuredClone.h"
16 #include "mozIStorageConnection.h"
17 #include "mozilla/dom/quota/Assertions.h"
18 #include "mozilla/dom/quota/QuotaCommon.h"
19 #include "mozilla/dom/quota/ResultExtensions.h"
20 #include "mozilla/ProfilerLabels.h"
23 #include "nsLiteralString.h"
26 namespace mozilla::dom::indexedDB
{
28 using quota::AssertIsOnIOThread
;
30 // If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
32 static_assert(JS_STRUCTURED_CLONE_VERSION
== 8,
33 "Need to update the major schema version.");
35 nsresult
CreateFileTables(mozIStorageConnection
& aConnection
) {
38 AUTO_PROFILER_LABEL("CreateFileTables", DOM
);
40 constexpr nsLiteralCString commands
[] = {
43 "id INTEGER PRIMARY KEY, "
44 "refcount INTEGER NOT NULL"
46 "CREATE TRIGGER object_data_insert_trigger "
47 "AFTER INSERT ON object_data "
49 "WHEN NEW.file_ids IS NOT NULL "
51 "SELECT update_refcount(NULL, NEW.file_ids); "
53 "CREATE TRIGGER object_data_update_trigger "
54 "AFTER UPDATE OF file_ids ON object_data "
56 "WHEN OLD.file_ids IS NOT NULL OR NEW.file_ids IS NOT NULL "
58 "SELECT update_refcount(OLD.file_ids, NEW.file_ids); "
60 "CREATE TRIGGER object_data_delete_trigger "
61 "AFTER DELETE ON object_data "
62 "FOR EACH ROW WHEN OLD.file_ids IS NOT NULL "
64 "SELECT update_refcount(OLD.file_ids, NULL); "
66 "CREATE TRIGGER file_update_trigger "
67 "AFTER UPDATE ON file "
68 "FOR EACH ROW WHEN NEW.refcount = 0 "
70 "DELETE FROM file WHERE id = OLD.id; "
73 QM_TRY(MOZ_TO_RESULT(ExecuteSimpleSQLSequence(aConnection
, commands
)));
78 nsresult
CreateTables(mozIStorageConnection
& aConnection
) {
81 AUTO_PROFILER_LABEL("CreateTables", DOM
);
83 constexpr nsLiteralCString commands
[] = {
86 // There are two reasons for having the origin column.
87 // First, we can ensure that we don't have collisions in the origin hash
89 // use for the path because when we open the db we can make sure that the
90 // origins exactly match. Second, chrome code crawling through the idb
91 // directory can figure out the origin of every db without having to
92 // reverse-engineer our hash scheme.
93 "CREATE TABLE database"
94 "( name TEXT PRIMARY KEY"
95 ", origin TEXT NOT NULL"
96 ", version INTEGER NOT NULL DEFAULT 0"
97 ", last_vacuum_time INTEGER NOT NULL DEFAULT 0"
98 ", last_analyze_time INTEGER NOT NULL DEFAULT 0"
99 ", last_vacuum_size INTEGER NOT NULL DEFAULT 0"
100 ") WITHOUT ROWID;"_ns
,
101 // Table `object_store`
102 "CREATE TABLE object_store"
103 "( id INTEGER PRIMARY KEY"
104 ", auto_increment INTEGER NOT NULL DEFAULT 0"
105 ", name TEXT NOT NULL"
108 // Table `object_store_index`
109 "CREATE TABLE object_store_index"
110 "( id INTEGER PRIMARY KEY"
111 ", object_store_id INTEGER NOT NULL"
112 ", name TEXT NOT NULL"
113 ", key_path TEXT NOT NULL"
114 ", unique_index INTEGER NOT NULL"
115 ", multientry INTEGER NOT NULL"
117 ", is_auto_locale BOOLEAN NOT NULL"
118 ", FOREIGN KEY (object_store_id) "
119 "REFERENCES object_store(id) "
121 // Table `object_data`
122 "CREATE TABLE object_data"
123 "( object_store_id INTEGER NOT NULL"
124 ", key BLOB NOT NULL"
125 ", index_data_values BLOB DEFAULT NULL"
127 ", data BLOB NOT NULL"
128 ", PRIMARY KEY (object_store_id, key)"
129 ", FOREIGN KEY (object_store_id) "
130 "REFERENCES object_store(id) "
131 ") WITHOUT ROWID;"_ns
,
132 // Table `index_data`
133 "CREATE TABLE index_data"
134 "( index_id INTEGER NOT NULL"
135 ", value BLOB NOT NULL"
136 ", object_data_key BLOB NOT NULL"
137 ", object_store_id INTEGER NOT NULL"
138 ", value_locale BLOB"
139 ", PRIMARY KEY (index_id, value, object_data_key)"
140 ", FOREIGN KEY (index_id) "
141 "REFERENCES object_store_index(id) "
142 ", FOREIGN KEY (object_store_id, object_data_key) "
143 "REFERENCES object_data(object_store_id, key) "
144 ") WITHOUT ROWID;"_ns
,
145 "CREATE INDEX index_data_value_locale_index "
146 "ON index_data (index_id, value_locale, object_data_key, value) "
147 "WHERE value_locale IS NOT NULL;"_ns
,
148 // Table `unique_index_data`
149 "CREATE TABLE unique_index_data"
150 "( index_id INTEGER NOT NULL"
151 ", value BLOB NOT NULL"
152 ", object_store_id INTEGER NOT NULL"
153 ", object_data_key BLOB NOT NULL"
154 ", value_locale BLOB"
155 ", PRIMARY KEY (index_id, value)"
156 ", FOREIGN KEY (index_id) "
157 "REFERENCES object_store_index(id) "
158 ", FOREIGN KEY (object_store_id, object_data_key) "
159 "REFERENCES object_data(object_store_id, key) "
160 ") WITHOUT ROWID;"_ns
,
161 "CREATE INDEX unique_index_data_value_locale_index "
162 "ON unique_index_data (index_id, value_locale, object_data_key, value) "
163 "WHERE value_locale IS NOT NULL;"_ns
};
165 QM_TRY(MOZ_TO_RESULT(ExecuteSimpleSQLSequence(aConnection
, commands
)));
167 QM_TRY(MOZ_TO_RESULT(CreateFileTables(aConnection
)));
169 QM_TRY(MOZ_TO_RESULT(aConnection
.SetSchemaVersion(kSQLiteSchemaVersion
)));
174 } // namespace mozilla::dom::indexedDB