alter table login rename to old_login; alter table token rename to old_token; alter table invite rename to old_invite; alter table channel rename to old_channel; alter table channel_deleted rename to old_channel_deleted; alter table message rename to old_message; alter table message_deleted rename to old_message_deleted; create table login ( id text not null primary key, display_name text not null, canonical_name text not null unique, password_hash text not null, created_sequence bigint unique not null, created_at text not null ); insert into login (id, display_name, canonical_name, password_hash, created_sequence, created_at) select id, -- This isn't strictly correct, as existing names are not guaranteed to be -- normalized, and as sqlite's built-in `lower` only operates on ASCII, but -- without any way to do case folding and normalization in sqlite3, and -- without any way to call out into Rust to do the work, this is the best we -- can do. Normalization issues will produce errors at runtime when the -- relevant rows are loaded. name as display_name, lower(name) as canonical_name, password_hash, created_sequence, created_at from old_login; create table token ( id text not null primary key, secret text not null unique, login text not null references login (id), issued_at text not null, last_used_at text not null ); insert into token (id, secret, login, issued_at, last_used_at) select id, secret, login, issued_at, last_used_at from old_token; create table invite ( id text primary key not null, issuer text not null references login (id), issued_at text not null ); insert into invite (id, issuer, issued_at) select id, issuer, issued_at from old_invite; create table channel ( id text not null primary key, created_sequence bigint unique not null, created_at text not null ); create table channel_name ( id text not null primary key references channel (id), display_name not null, canonical_name not null unique ); insert into channel (id, created_sequence, created_at) select id, created_sequence, created_at from old_channel; insert into channel_name (id, display_name, canonical_name) select id, -- This isn't strictly correct, for the same reasons as above. name as display_name, name as canonical_name from old_channel where name is not null; create table channel_deleted ( id text not null primary key references channel (id), deleted_sequence bigint unique not null, deleted_at text not null ); insert into channel_deleted (id, deleted_sequence, deleted_at) select id, deleted_sequence, deleted_at from old_channel_deleted; create table message ( id text not null primary key, -- Starting from the code changes in this rev, values in this column will be -- in NFC. However, we don't actually need to normalize historical values; -- they're delivered to clients "verbatim" with respect to how they were sent, -- which causes no harm. channel text not null references channel (id), sender text not null references login (id), sent_sequence bigint unique not null, sent_at text not null, body text null ); insert into message (id, channel, sender, sent_sequence, sent_at, body) select id, channel, sender, sent_sequence, sent_at, body from old_message; create table message_deleted ( id text not null primary key references message (id), deleted_sequence bigint unique not null, deleted_at text not null ); insert into message_deleted (id, deleted_sequence, deleted_at) select id, deleted_sequence, deleted_at from old_message_deleted; drop table old_message_deleted; drop table old_message; drop table old_channel_deleted; drop table old_channel; drop table old_invite; drop table old_token; drop table old_login; create index token_issued_at on token (issued_at); create index message_sent_at on message (sent_at);