From 61b755c890dcaa66daa35942ca87cc00269b0fe9 Mon Sep 17 00:00:00 2001
From: cel 🌸 <cel@bunny.garden>
Date: Thu, 17 Apr 2025 17:30:22 +0100
Subject: feat(filamento): full wasm support by switching to rusqlite

---
 filamento/migrations/1.sql | 141 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)
 create mode 100644 filamento/migrations/1.sql

(limited to 'filamento/migrations/1.sql')

diff --git a/filamento/migrations/1.sql b/filamento/migrations/1.sql
new file mode 100644
index 0000000..502c5a9
--- /dev/null
+++ b/filamento/migrations/1.sql
@@ -0,0 +1,141 @@
+PRAGMA foreign_keys = on;
+
+-- a user jid will never change, only a chat user will change
+-- TODO: avatar, nick, etc.
+create table if not exists users(
+    -- TODO: enforce bare jid
+    jid text primary key not null,
+    nick text,
+    avatar text,
+    -- can receive presence status from non-contacts
+    cached_status_message text
+    -- TODO: last_seen
+);
+
+-- -- links to messages, jabber users, stores jid history, etc.
+-- create table identities(
+--     id text primary key not null
+-- );
+
+-- create table identities_users(
+--     id text not null,
+--     jid text not null,
+--     -- whichever has the newest timestamp is the active one.
+--     -- what to do when somebody moves, but then the old jid is used again without having explicitly moved back? create new identity to assign ownership to?
+--     -- merging of identities?
+--     activated_timestamp not null,
+--     foreign key(id) references identities(id),
+--     foreign key(jid) references users(jid),
+--     primary key(activated timestamp, id, jid)
+-- );
+
+create table if not exists resources(
+    bare_jid text not null,
+    resource text not null,
+    foreign key(bare_jid) references users(jid),
+    primary key(bare_jid, resource)
+);
+
+-- enum for subscription state
+create table if not exists subscription(
+    state text primary key not null
+);
+
+insert into subscription ( state ) values ('none'), ('pending-out'), ('pending-in'), ('pending-in-pending-out'), ('only-out'), ('only-in'), ('out-pending-in'), ('in-pending-out'), ('buddy') on conflict do nothing;
+
+-- a roster contains users, with client-set nickname
+CREATE TABLE if not exists roster( 
+    user_jid text primary key not null,
+    name TEXT,
+    subscription text not null,
+    foreign key(subscription) references subscription(state),
+    foreign key(user_jid) references users(jid)
+);
+
+create table if not exists groups(
+    group_name text primary key not null
+);
+
+create table if not exists groups_roster(
+    group_name text not null,
+    contact_jid text not null,
+    foreign key(group_name) references groups(group_name),
+    foreign key(contact_jid) references roster(user_jid) on delete cascade,
+    primary key(group_name, contact_jid)
+);
+
+-- chat includes reference to user jid chat is with
+-- specifically for dms, groups should be different
+-- can send chat message to user (creating a new chat if not already exists)
+create table if not exists chats (
+    id text primary key not null,
+    have_chatted bool not null,
+    correspondent text not null unique,
+    foreign key(correspondent) references users(jid)
+);
+
+-- enum for subscription state
+create table if not exists delivery(
+    state text primary key not null
+);
+
+insert into delivery ( state ) values ('sending'), ('written'), ('sent'), ('delivered'), ('read'), ('failed'), ('queued') on conflict do nothing;
+
+-- messages include reference to chat they are in, and who sent them.
+create table if not exists messages (
+    id text primary key not null,
+    body text,
+    -- delivery is nullable as only messages sent by the user are markable
+    delivery text,
+    chat_id text not null,
+    -- TODO: channel stuff 
+    -- channel_id uuid,
+    -- check ((chat_id == null) <> (channel_id == null)),
+    -- check ((chat_id == null) or (channel_id == null)),
+    -- user is the current "owner" of the message
+    -- TODO: queued messages offline
+    -- TODO: timestamp
+    timestamp text not null,
+
+    -- TODO: icky
+    -- the user to show it coming from (not necessarily the original sender)
+    -- from_identity text not null,
+    -- original sender details (only from jabber supported for now)
+    from_jid text not null,
+    -- resource can be null
+    from_resource text,
+    -- check (from_jid != original_sender),
+
+    foreign key(delivery) references delivery(state),
+    -- TODO: from can be either a jid, a moved jid (for when a contact moves, save original sender jid/user but link to new user), or imported (from another service (save details), linked to new user)
+    -- TODO: read bool not null,
+    foreign key(chat_id) references chats(id) on delete cascade,
+    -- foreign key(from_identity) references identities(id),
+    foreign key(from_jid) references users(jid),
+    foreign key(from_jid, from_resource) references resources(bare_jid, resource)
+);
+
+-- enum for subscription state
+create table if not exists show (
+    state text primary key not null
+);
+
+insert into show ( state ) values ('away'), ('chat'), ('do-not-disturb'), ('extended-away') on conflict do nothing;
+
+create table if not exists cached_status (
+    id integer primary key not null,
+    show text,
+    message text,
+    foreign key(show) references show(state)
+);
+
+insert into cached_status (id) values (0) on conflict do nothing;
+
+create table if not exists capability_hash_nodes (
+    node text primary key not null,
+    timestamp text,
+    -- TODO: normalization
+    capabilities text not null
+);
+
+insert into capability_hash_nodes ( node, capabilities ) values ('https://bunny.garden/filamento#mSavc/SLnHm8zazs5RlcbD/iXoc=', 'aHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvY2Fwcx9odHRwOi8vamFiYmVyLm9yZy9wcm90b2NvbC9kaXNjbyNpbmZvH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2Rpc2NvI2l0ZW1zH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL25pY2sfaHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvbmljaytub3RpZnkfHGNsaWVudB9wYx8fZmlsYW1lbnRvIDAuMS4wHx4cHA==') on conflict do nothing;
-- 
cgit 

