mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-11-04 10:47:32 +00:00
store: add the names tables migration
This commit is contained in:
1 parent
917b94b50b
commit
32685b6d9a
2 files changed
+349
-2
No files matched your search
@@ -18,7 +18,8 @@ storeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations
|
||||
schemaMigrations :: [(String, Text, Maybe Text)]
|
||||
schemaMigrations =
|
||||
[ ("20260915_badge_service_schema", m20260915_badge_service_schema, Just down_m20260915_badge_service_schema),
|
||||
("20260918_badge_group_ops", m20260918_badge_group_ops, Just down_m20260918_badge_group_ops)
|
||||
("20260918_badge_group_ops", m20260918_badge_group_ops, Just down_m20260918_badge_group_ops),
|
||||
("20261010_names", m20261010_names, Just down_m20261010_names)
|
||||
]
|
||||
|
||||
-- | The client tables share this database, so the service tables are the same names behind a prefix.
|
||||
@@ -152,6 +153,178 @@ ALTER TABLE @badge_codes DROP COLUMN redeem_limit;
|
||||
DROP TABLE @group;
|
||||
|]
|
||||
|
||||
-- A registration is live while its invoice is open, or past unpaid and not taken or code_issued.
|
||||
-- reserved_by is added after the registrations table, which references the codes table.
|
||||
m20261010_names :: Text
|
||||
m20261010_names =
|
||||
withPrefix
|
||||
servicePrefix
|
||||
[r|
|
||||
CREATE TABLE @name_prepaid_codes(
|
||||
name_prepaid_code_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
code_hash BYTEA NOT NULL,
|
||||
min_length INTEGER NOT NULL,
|
||||
years INTEGER NOT NULL,
|
||||
code_payment_status TEXT NOT NULL,
|
||||
reserved_at TIMESTAMPTZ,
|
||||
spent_at TIMESTAMPTZ,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
expires_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
UNIQUE(code_hash)
|
||||
);
|
||||
|
||||
CREATE TABLE @name_registrations(
|
||||
registration_id TEXT NOT NULL PRIMARY KEY,
|
||||
version BIGINT NOT NULL,
|
||||
label_hash BYTEA NOT NULL,
|
||||
length INTEGER NOT NULL,
|
||||
duration BIGINT NOT NULL,
|
||||
owner BYTEA NOT NULL,
|
||||
commitment BYTEA NOT NULL,
|
||||
sealed TEXT NOT NULL,
|
||||
phase TEXT NOT NULL,
|
||||
years INTEGER NOT NULL,
|
||||
price INTEGER NOT NULL,
|
||||
method TEXT,
|
||||
name_prepaid_code_id BIGINT REFERENCES @name_prepaid_codes,
|
||||
label TEXT,
|
||||
secret BYTEA,
|
||||
contact_link TEXT,
|
||||
channel_link TEXT,
|
||||
intent_nonce BIGINT,
|
||||
intent_deadline BIGINT,
|
||||
intent_signature BYTEA,
|
||||
commit_tx BYTEA,
|
||||
commit_block BIGINT,
|
||||
register_tx BYTEA,
|
||||
register_block BIGINT,
|
||||
reveal_after BIGINT,
|
||||
reveal_before BIGINT,
|
||||
expires_at BIGINT,
|
||||
issued_code_id BIGINT REFERENCES @name_prepaid_codes,
|
||||
registered_at TIMESTAMPTZ,
|
||||
failed_at TIMESTAMPTZ,
|
||||
error TEXT,
|
||||
live SMALLINT NOT NULL,
|
||||
order_hash BYTEA NOT NULL,
|
||||
moves INTEGER NOT NULL DEFAULT 0,
|
||||
links_refused_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE @name_prepaid_codes ADD COLUMN reserved_by TEXT REFERENCES @name_registrations;
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_prepaid_codes_reserved_by ON @name_prepaid_codes(reserved_by);
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_registrations_live_commitment ON @name_registrations(commitment) WHERE live = 1;
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_registrations_live_owner_label ON @name_registrations(owner, label_hash) WHERE live = 1;
|
||||
|
||||
CREATE INDEX @idx_name_registrations_label_phase ON @name_registrations(label_hash, phase);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_owner ON @name_registrations(owner, created_at);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_phase ON @name_registrations(phase, created_at);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_order_hash ON @name_registrations(order_hash);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_prepaid_code ON @name_registrations(name_prepaid_code_id);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_issued_code ON @name_registrations(issued_code_id);
|
||||
|
||||
CREATE TABLE @name_invoices(
|
||||
invoice_id TEXT NOT NULL PRIMARY KEY REFERENCES @invoices ON DELETE CASCADE,
|
||||
registration_id TEXT NOT NULL REFERENCES @name_registrations ON DELETE CASCADE,
|
||||
provider_ref TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_invoices_registration ON @name_invoices(registration_id);
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_invoices_provider_ref ON @name_invoices(provider_ref);
|
||||
|
||||
CREATE TABLE @name_record_edits(
|
||||
name_record_edit_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
label_hash BYTEA NOT NULL,
|
||||
owner BYTEA NOT NULL,
|
||||
nonce BIGINT NOT NULL,
|
||||
record_key TEXT,
|
||||
record_value TEXT,
|
||||
deadline BIGINT NOT NULL,
|
||||
signature BYTEA NOT NULL,
|
||||
body_hash BYTEA NOT NULL,
|
||||
state TEXT NOT NULL,
|
||||
revert TEXT,
|
||||
mined_tx BYTEA,
|
||||
created_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
||||
-- A reverted edit keeps its row for its repeats while a new body reuses the nonce.
|
||||
CREATE UNIQUE INDEX @idx_name_record_edits_owner_nonce ON @name_record_edits(owner, nonce) WHERE state IN ('pending', 'mined');
|
||||
|
||||
CREATE INDEX @idx_name_record_edits_body_hash ON @name_record_edits(body_hash);
|
||||
|
||||
CREATE INDEX @idx_name_record_edits_label_created ON @name_record_edits(label_hash, created_at);
|
||||
|
||||
CREATE TABLE @name_transactions(
|
||||
name_transaction_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
registration_id TEXT REFERENCES @name_registrations,
|
||||
name_record_edit_id BIGINT REFERENCES @name_record_edits,
|
||||
kind TEXT NOT NULL,
|
||||
raw BYTEA NOT NULL,
|
||||
tx_hash BYTEA NOT NULL,
|
||||
registrar_nonce BIGINT NOT NULL,
|
||||
sent_at TIMESTAMPTZ NOT NULL,
|
||||
mined_block BIGINT,
|
||||
status TEXT NOT NULL,
|
||||
CHECK ((registration_id IS NULL) <> (name_record_edit_id IS NULL)),
|
||||
UNIQUE(tx_hash)
|
||||
);
|
||||
|
||||
CREATE INDEX @idx_name_transactions_registration ON @name_transactions(registration_id);
|
||||
|
||||
CREATE INDEX @idx_name_transactions_edit ON @name_transactions(name_record_edit_id);
|
||||
|
||||
CREATE INDEX @idx_name_transactions_status ON @name_transactions(status, registrar_nonce);
|
||||
|]
|
||||
|
||||
-- A table another table's foreign key references cannot be dropped, so reserved_by goes first.
|
||||
down_m20261010_names :: Text
|
||||
down_m20261010_names =
|
||||
withPrefix
|
||||
servicePrefix
|
||||
[r|
|
||||
DROP INDEX @idx_name_transactions_status;
|
||||
DROP INDEX @idx_name_transactions_edit;
|
||||
DROP INDEX @idx_name_transactions_registration;
|
||||
DROP TABLE @name_transactions;
|
||||
|
||||
DROP INDEX @idx_name_record_edits_label_created;
|
||||
DROP INDEX @idx_name_record_edits_body_hash;
|
||||
DROP INDEX @idx_name_record_edits_owner_nonce;
|
||||
DROP TABLE @name_record_edits;
|
||||
|
||||
DROP INDEX @idx_name_invoices_provider_ref;
|
||||
DROP INDEX @idx_name_invoices_registration;
|
||||
DROP TABLE @name_invoices;
|
||||
|
||||
DROP INDEX @idx_name_registrations_issued_code;
|
||||
DROP INDEX @idx_name_registrations_prepaid_code;
|
||||
DROP INDEX @idx_name_registrations_order_hash;
|
||||
DROP INDEX @idx_name_registrations_phase;
|
||||
DROP INDEX @idx_name_registrations_owner;
|
||||
DROP INDEX @idx_name_registrations_label_phase;
|
||||
DROP INDEX @idx_name_registrations_live_owner_label;
|
||||
DROP INDEX @idx_name_registrations_live_commitment;
|
||||
DROP INDEX @idx_name_prepaid_codes_reserved_by;
|
||||
ALTER TABLE @name_prepaid_codes DROP COLUMN reserved_by;
|
||||
DROP TABLE @name_registrations;
|
||||
|
||||
DROP TABLE @name_prepaid_codes;
|
||||
|]
|
||||
|
||||
{- TODO [badges] deferred with the draft in M20260915_user_badges, service only.
|
||||
|
||||
ALTER TABLE @payments ADD COLUMN receipt_hash BYTEA;
|
||||
|
||||
@@ -19,7 +19,8 @@ storeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations
|
||||
schemaMigrations :: [(String, Query, Maybe Query)]
|
||||
schemaMigrations =
|
||||
[ ("20260915_badge_service_schema", m20260915_badge_service_schema, Just down_m20260915_badge_service_schema),
|
||||
("20260918_badge_group_ops", m20260918_badge_group_ops, Just down_m20260918_badge_group_ops)
|
||||
("20260918_badge_group_ops", m20260918_badge_group_ops, Just down_m20260918_badge_group_ops),
|
||||
("20261010_names", m20261010_names, Just down_m20261010_names)
|
||||
]
|
||||
|
||||
-- | The client tables share this database, so the service tables are the same names behind a prefix.
|
||||
@@ -153,6 +154,179 @@ ALTER TABLE @badge_codes DROP COLUMN redeem_limit;
|
||||
DROP TABLE @group;
|
||||
|]
|
||||
|
||||
-- A registration is live while its invoice is open, or past unpaid and not taken or code_issued.
|
||||
-- reserved_by is added after the registrations table, which references the codes table.
|
||||
m20261010_names :: Query
|
||||
m20261010_names =
|
||||
withPrefix
|
||||
servicePrefix
|
||||
[sql|
|
||||
CREATE TABLE @name_prepaid_codes(
|
||||
name_prepaid_code_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
code_hash BLOB NOT NULL,
|
||||
min_length INTEGER NOT NULL,
|
||||
years INTEGER NOT NULL,
|
||||
code_payment_status TEXT NOT NULL,
|
||||
reserved_at TEXT,
|
||||
spent_at TEXT,
|
||||
revoked_at TEXT,
|
||||
expires_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(code_hash)
|
||||
) STRICT;
|
||||
|
||||
CREATE TABLE @name_registrations(
|
||||
registration_id TEXT NOT NULL PRIMARY KEY,
|
||||
version INTEGER NOT NULL,
|
||||
label_hash BLOB NOT NULL,
|
||||
length INTEGER NOT NULL,
|
||||
duration INTEGER NOT NULL,
|
||||
owner BLOB NOT NULL,
|
||||
commitment BLOB NOT NULL,
|
||||
sealed TEXT NOT NULL,
|
||||
phase TEXT NOT NULL,
|
||||
years INTEGER NOT NULL,
|
||||
price INTEGER NOT NULL,
|
||||
method TEXT,
|
||||
name_prepaid_code_id INTEGER REFERENCES @name_prepaid_codes,
|
||||
label TEXT,
|
||||
secret BLOB,
|
||||
contact_link TEXT,
|
||||
channel_link TEXT,
|
||||
intent_nonce INTEGER,
|
||||
intent_deadline INTEGER,
|
||||
intent_signature BLOB,
|
||||
commit_tx BLOB,
|
||||
commit_block INTEGER,
|
||||
register_tx BLOB,
|
||||
register_block INTEGER,
|
||||
reveal_after INTEGER,
|
||||
reveal_before INTEGER,
|
||||
expires_at INTEGER,
|
||||
issued_code_id INTEGER REFERENCES @name_prepaid_codes,
|
||||
registered_at TEXT,
|
||||
failed_at TEXT,
|
||||
error TEXT,
|
||||
live INTEGER NOT NULL,
|
||||
order_hash BLOB NOT NULL,
|
||||
moves INTEGER NOT NULL DEFAULT 0,
|
||||
links_refused_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
) STRICT;
|
||||
|
||||
ALTER TABLE @name_prepaid_codes ADD COLUMN reserved_by TEXT REFERENCES @name_registrations;
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_prepaid_codes_reserved_by ON @name_prepaid_codes(reserved_by);
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_registrations_live_commitment ON @name_registrations(commitment) WHERE live = 1;
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_registrations_live_owner_label ON @name_registrations(owner, label_hash) WHERE live = 1;
|
||||
|
||||
CREATE INDEX @idx_name_registrations_label_phase ON @name_registrations(label_hash, phase);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_owner ON @name_registrations(owner, created_at);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_phase ON @name_registrations(phase, created_at);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_order_hash ON @name_registrations(order_hash);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_prepaid_code ON @name_registrations(name_prepaid_code_id);
|
||||
|
||||
CREATE INDEX @idx_name_registrations_issued_code ON @name_registrations(issued_code_id);
|
||||
|
||||
CREATE TABLE @name_invoices(
|
||||
invoice_id TEXT NOT NULL PRIMARY KEY REFERENCES @invoices ON DELETE CASCADE,
|
||||
registration_id TEXT NOT NULL REFERENCES @name_registrations ON DELETE CASCADE,
|
||||
provider_ref TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
) STRICT;
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_invoices_registration ON @name_invoices(registration_id);
|
||||
|
||||
CREATE UNIQUE INDEX @idx_name_invoices_provider_ref ON @name_invoices(provider_ref);
|
||||
|
||||
CREATE TABLE @name_record_edits(
|
||||
name_record_edit_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
label_hash BLOB NOT NULL,
|
||||
owner BLOB NOT NULL,
|
||||
nonce INTEGER NOT NULL,
|
||||
record_key TEXT,
|
||||
record_value TEXT,
|
||||
deadline INTEGER NOT NULL,
|
||||
signature BLOB NOT NULL,
|
||||
body_hash BLOB NOT NULL,
|
||||
state TEXT NOT NULL,
|
||||
revert TEXT,
|
||||
mined_tx BLOB,
|
||||
created_at TEXT NOT NULL
|
||||
) STRICT;
|
||||
|
||||
-- A reverted edit keeps its row for its repeats while a new body reuses the nonce.
|
||||
CREATE UNIQUE INDEX @idx_name_record_edits_owner_nonce ON @name_record_edits(owner, nonce) WHERE state IN ('pending', 'mined');
|
||||
|
||||
CREATE INDEX @idx_name_record_edits_body_hash ON @name_record_edits(body_hash);
|
||||
|
||||
CREATE INDEX @idx_name_record_edits_label_created ON @name_record_edits(label_hash, created_at);
|
||||
|
||||
CREATE TABLE @name_transactions(
|
||||
name_transaction_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
registration_id TEXT REFERENCES @name_registrations,
|
||||
name_record_edit_id INTEGER REFERENCES @name_record_edits,
|
||||
kind TEXT NOT NULL,
|
||||
raw BLOB NOT NULL,
|
||||
tx_hash BLOB NOT NULL,
|
||||
registrar_nonce INTEGER NOT NULL,
|
||||
sent_at TEXT NOT NULL,
|
||||
mined_block INTEGER,
|
||||
status TEXT NOT NULL,
|
||||
CHECK ((registration_id IS NULL) <> (name_record_edit_id IS NULL)),
|
||||
UNIQUE(tx_hash)
|
||||
) STRICT;
|
||||
|
||||
CREATE INDEX @idx_name_transactions_registration ON @name_transactions(registration_id);
|
||||
|
||||
CREATE INDEX @idx_name_transactions_edit ON @name_transactions(name_record_edit_id);
|
||||
|
||||
CREATE INDEX @idx_name_transactions_status ON @name_transactions(status, registrar_nonce);
|
||||
|]
|
||||
|
||||
-- SQLite refuses to drop a column in a foreign key, and dropping a table deletes its rows first,
|
||||
-- so the codes' references to registrations are cleared before the registrations go.
|
||||
down_m20261010_names :: Query
|
||||
down_m20261010_names =
|
||||
withPrefix
|
||||
servicePrefix
|
||||
[sql|
|
||||
DROP INDEX @idx_name_transactions_status;
|
||||
DROP INDEX @idx_name_transactions_edit;
|
||||
DROP INDEX @idx_name_transactions_registration;
|
||||
DROP TABLE @name_transactions;
|
||||
|
||||
DROP INDEX @idx_name_record_edits_label_created;
|
||||
DROP INDEX @idx_name_record_edits_body_hash;
|
||||
DROP INDEX @idx_name_record_edits_owner_nonce;
|
||||
DROP TABLE @name_record_edits;
|
||||
|
||||
DROP INDEX @idx_name_invoices_provider_ref;
|
||||
DROP INDEX @idx_name_invoices_registration;
|
||||
DROP TABLE @name_invoices;
|
||||
|
||||
DROP INDEX @idx_name_registrations_issued_code;
|
||||
DROP INDEX @idx_name_registrations_prepaid_code;
|
||||
DROP INDEX @idx_name_registrations_order_hash;
|
||||
DROP INDEX @idx_name_registrations_phase;
|
||||
DROP INDEX @idx_name_registrations_owner;
|
||||
DROP INDEX @idx_name_registrations_label_phase;
|
||||
DROP INDEX @idx_name_registrations_live_owner_label;
|
||||
DROP INDEX @idx_name_registrations_live_commitment;
|
||||
DROP INDEX @idx_name_prepaid_codes_reserved_by;
|
||||
UPDATE @name_prepaid_codes SET reserved_by = NULL;
|
||||
DROP TABLE @name_registrations;
|
||||
|
||||
DROP TABLE @name_prepaid_codes;
|
||||
|]
|
||||
|
||||
{- TODO [badges] deferred with the draft in M20260915_user_badges, service only.
|
||||
|
||||
ALTER TABLE @payments ADD COLUMN receipt_hash BLOB;
|
||||
|
||||
Reference in new issue
Block a user