diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/webext-storage/sql | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/webext-storage/sql')
3 files changed, 180 insertions, 0 deletions
diff --git a/third_party/rust/webext-storage/sql/create_schema.sql b/third_party/rust/webext-storage/sql/create_schema.sql new file mode 100644 index 0000000000..fd02115cdd --- /dev/null +++ b/third_party/rust/webext-storage/sql/create_schema.sql @@ -0,0 +1,54 @@ +-- 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/. + +-- This is a very simple schema for a chrome.storage.* implementation. At time +-- of writing, only chrome.storage.sync is supported, but this can be trivially +-- enhanced to support chrome.storage.local (the api is identical, it's just a +-- different "bucket" and doesn't sync). +-- +-- Even though the spec allows for a single extension to have any number of +-- "keys", we've made the decision to store all keys for a given extension in a +-- single row as a JSON representation of all keys and values. +-- We've done this primarily due to: +-- * The shape of the API is very JSON, and it almost encourages multiple keys +-- to be fetched at one time. +-- * The defined max sizes that extensions are allowed to store using this API +-- is sufficiently small that we don't have many concerns around record sizes. +-- * We'd strongly prefer to keep one record per extension when syncing this +-- data, so having the local store in this shape makes syncing easier. + +CREATE TABLE IF NOT EXISTS storage_sync_data ( + ext_id TEXT NOT NULL PRIMARY KEY, + + /* The JSON payload. NULL means it's a tombstone */ + data TEXT, + + /* Same "sync change counter" strategy used by other components. */ + sync_change_counter INTEGER NOT NULL DEFAULT 1 +); + +CREATE TABLE IF NOT EXISTS storage_sync_mirror ( + guid TEXT NOT NULL PRIMARY KEY, + + /* The extension_id is explicitly not the GUID used on the server. + It can't be a regular foreign-key relationship back to storage_sync_data + as items with no data on the server (ie, deleted items) will not appear + in storage_sync_data, and the guid isn't in that table either. + It must allow NULL as tombstones do not carry the ext_id, so we have + an additional CHECK constraint. + */ + ext_id TEXT UNIQUE, + + /* The JSON payload. We *do* allow NULL here - it means "deleted" */ + data TEXT + + /* tombstones have no ext_id and no data. Non tombstones must have both */ + CHECK((ext_id IS NULL AND data IS NULL) OR (ext_id IS NOT NULL AND data IS NOT NULL)) +); + +-- This table holds key-value metadata - primarily for sync. +CREATE TABLE IF NOT EXISTS meta ( + key TEXT PRIMARY KEY, + value NOT NULL +) WITHOUT ROWID; diff --git a/third_party/rust/webext-storage/sql/create_sync_temp_tables.sql b/third_party/rust/webext-storage/sql/create_sync_temp_tables.sql new file mode 100644 index 0000000000..24c9a21fbc --- /dev/null +++ b/third_party/rust/webext-storage/sql/create_sync_temp_tables.sql @@ -0,0 +1,69 @@ +-- 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/. + +-- Temp tables used by Sync. +-- Note that this is executed both before and after a sync. + +CREATE TEMP TABLE IF NOT EXISTS storage_sync_staging ( + guid TEXT NOT NULL PRIMARY KEY, + + /* The extension_id is explicitly not the GUID used on the server. + It can't be a regular foreign-key relationship back to storage_sync_data, + nor can it be NOT NULL, as the ext_id for incoming items may not appear + in storage_sync_data at the time we populate this table, and also + because incoming tombstones have no extension ID. + */ + ext_id TEXT UNIQUE, + + /* The JSON payload. We *do* allow NULL here - it means "deleted" */ + data TEXT +); + +DELETE FROM temp.storage_sync_staging; + +-- We record the changes we are making via sync in this table, so that at the +-- end of the sync extensions can find out via notifications what changes +-- were applied. +CREATE TEMP TABLE IF NOT EXISTS storage_sync_applied ( + ext_id TEXT NOT NULL UNIQUE, + + /* A StorageChanges value serialized as JSON. */ + changes TEXT NOT NULL +); + +DELETE FROM temp.storage_sync_applied; + +-- We store metadata about items we are uploading in this temp table. After +-- we get told the upload was successful we use this to update the local +-- tables. +CREATE TEMP TABLE IF NOT EXISTS storage_sync_outgoing_staging ( + guid TEXT NOT NULL PRIMARY KEY DEFAULT(generate_guid()), + ext_id TEXT NOT NULL UNIQUE, + data TEXT, + sync_change_counter INTEGER NOT NULL, + was_uploaded BOOLEAN NOT NULL DEFAULT 0 +); + +CREATE TEMP TRIGGER IF NOT EXISTS record_uploaded +AFTER UPDATE OF was_uploaded ON storage_sync_outgoing_staging +WHEN NEW.was_uploaded +BEGIN + -- Decrement the local change counter for uploaded items. If any local items + -- changed while we were uploading, their change counters will remain > 0, + -- and we'll merge them again on the next sync. + UPDATE storage_sync_data SET + sync_change_counter = sync_change_counter - NEW.sync_change_counter + WHERE NEW.ext_id IS NOT NULL AND ext_id = NEW.ext_id; + + -- Delete uploaded tombstones entirely; they're only kept in the mirror. + DELETE FROM storage_sync_data WHERE data IS NULL AND sync_change_counter = 0 AND ext_id = NEW.ext_id; + + -- And write the uploaded item back to the mirror. + INSERT OR REPLACE INTO storage_sync_mirror (guid, ext_id, data) + -- Our mirror has a constraint for tombstones, so handle that - if data is + -- null we want a null ext_id (as that's whats on the server) + VALUES (NEW.guid, CASE WHEN NEW.data IS NULL THEN NULL ELSE NEW.ext_id END, NEW.data); +END; + +DELETE FROM temp.storage_sync_outgoing_staging; diff --git a/third_party/rust/webext-storage/sql/tests/create_schema_v1.sql b/third_party/rust/webext-storage/sql/tests/create_schema_v1.sql new file mode 100644 index 0000000000..fba07d2084 --- /dev/null +++ b/third_party/rust/webext-storage/sql/tests/create_schema_v1.sql @@ -0,0 +1,57 @@ +-- 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/. + +-- This is a very simple schema for a chrome.storage.* implementation. At time +-- of writing, only chrome.storage.sync is supported, but this can be trivially +-- enhanced to support chrome.storage.local (the api is identical, it's just a +-- different "bucket" and doesn't sync). +-- +-- Even though the spec allows for a single extension to have any number of +-- "keys", we've made the decision to store all keys for a given extension in a +-- single row as a JSON representation of all keys and values. +-- We've done this primarily due to: +-- * The shape of the API is very JSON, and it almost encourages multiple keys +-- to be fetched at one time. +-- * The defined max sizes that extensions are allowed to store using this API +-- is sufficiently small that we don't have many concerns around record sizes. +-- * We'd strongly prefer to keep one record per extension when syncing this +-- data, so having the local store in this shape makes syncing easier. + +CREATE TABLE IF NOT EXISTS storage_sync_data ( + ext_id TEXT NOT NULL PRIMARY KEY, + + /* The JSON payload. NULL means it's a tombstone */ + data TEXT, + + /* Same "sync change counter" strategy used by other components. */ + sync_change_counter INTEGER NOT NULL DEFAULT 1 +); + +CREATE TABLE IF NOT EXISTS storage_sync_mirror ( + guid TEXT NOT NULL PRIMARY KEY, + + /* The extension_id is explicitly not the GUID used on the server. + It can't be a regular foreign-key relationship back to storage_sync_data + as items with no data on the server (ie, deleted items) will not appear + in storage_sync_data. + */ + ext_id TEXT NOT NULL UNIQUE, + + /* The JSON payload. We *do* allow NULL here - it means "deleted" */ + data TEXT +); + +-- This table holds key-value metadata - primarily for sync. +CREATE TABLE IF NOT EXISTS meta ( + key TEXT PRIMARY KEY, + value NOT NULL +) WITHOUT ROWID; + +-- Insert a couple test rows +INSERT INTO storage_sync_mirror(guid, ext_id, data) +VALUES + ('guid-1', 'ext-id-1', 'data-1'), + ('guid-2', 'ext-id-2', 'data-2'); + +PRAGMA user_version = 1; |