diff --git a/migrations/20210612_initial.sql b/migrations/20210612_initial.sql index daf04bf76..27b8c5108 100644 --- a/migrations/20210612_initial.sql +++ b/migrations/20210612_initial.sql @@ -15,13 +15,13 @@ CREATE TABLE users ( active_user INTEGER NOT NULL DEFAULT 0, -- 1 for active user FOREIGN KEY (user_id, local_display_name) REFERENCES display_names (user_id, local_display_name) - ON DELETE RESTRICT + ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED ); CREATE TABLE display_names ( - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, local_display_name TEXT NOT NULL, ldn_base TEXT NOT NULL, ldn_suffix INTEGER NOT NULL DEFAULT 0, @@ -31,15 +31,15 @@ CREATE TABLE display_names ( CREATE TABLE contacts ( contact_id INTEGER PRIMARY KEY, - contact_profile_id INTEGER REFERENCES contact_profiles, -- NULL if it's an incognito profile - user_id INTEGER NOT NULL REFERENCES users, + contact_profile_id INTEGER REFERENCES contact_profiles ON DELETE SET NULL, -- NULL if it's an incognito profile + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, local_display_name TEXT NOT NULL, is_user INTEGER NOT NULL DEFAULT 0, -- 1 if this contact is a user via_group INTEGER REFERENCES groups (group_id) ON DELETE SET NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), FOREIGN KEY (user_id, local_display_name) REFERENCES display_names (user_id, local_display_name) - ON DELETE RESTRICT + ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE (user_id, local_display_name), UNIQUE (user_id, contact_profile_id) @@ -49,7 +49,7 @@ CREATE TABLE sent_probes ( sent_probe_id INTEGER PRIMARY KEY, contact_id INTEGER NOT NULL UNIQUE REFERENCES contacts ON DELETE CASCADE, probe BLOB NOT NULL, - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, UNIQUE (user_id, probe) ); @@ -57,7 +57,7 @@ CREATE TABLE sent_probe_hashes ( sent_probe_hash_id INTEGER PRIMARY KEY, sent_probe_id INTEGER NOT NULL REFERENCES sent_probes ON DELETE CASCADE, contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, UNIQUE (sent_probe_id, contact_id) ); @@ -66,7 +66,7 @@ CREATE TABLE received_probes ( contact_id INTEGER NOT NULL REFERENCES contacts ON DELETE CASCADE, probe BLOB, probe_hash BLOB NOT NULL, - user_id INTEGER NOT NULL REFERENCES users + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE ); CREATE TABLE known_servers( @@ -74,7 +74,7 @@ CREATE TABLE known_servers( host TEXT NOT NULL, port TEXT NOT NULL, key_hash BLOB, - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, UNIQUE (user_id, host, port) ) WITHOUT ROWID; @@ -87,42 +87,42 @@ CREATE TABLE group_profiles ( -- shared group profiles CREATE TABLE groups ( group_id INTEGER PRIMARY KEY, -- local group ID - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, local_display_name TEXT NOT NULL, -- local group name without spaces - group_profile_id INTEGER REFERENCES group_profiles, -- shared group profile + group_profile_id INTEGER REFERENCES group_profiles ON DELETE SET NULL, -- shared group profile inv_queue_info BLOB, -- received FOREIGN KEY (user_id, local_display_name) REFERENCES display_names (user_id, local_display_name) - ON DELETE RESTRICT + ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE (user_id, local_display_name), UNIQUE (user_id, group_profile_id) ); +CREATE INDEX idx_groups_inv_queue_info ON groups (inv_queue_info); + CREATE TABLE group_members ( -- group members, excluding the local user group_member_id INTEGER PRIMARY KEY, - group_id INTEGER NOT NULL REFERENCES groups ON DELETE RESTRICT, + group_id INTEGER NOT NULL REFERENCES groups ON DELETE CASCADE, member_id BLOB NOT NULL, -- shared member ID, unique per group member_role TEXT NOT NULL, -- owner, admin, member member_category TEXT NOT NULL, -- see GroupMemberCategory member_status TEXT NOT NULL, -- see GroupMemberStatus - invited_by INTEGER REFERENCES contacts (contact_id) ON DELETE RESTRICT, -- NULL for the members who joined before the current user and for the group creator + invited_by INTEGER REFERENCES contacts (contact_id) ON DELETE SET NULL, -- NULL for the members who joined before the current user and for the group creator sent_inv_queue_info BLOB, -- sent group_queue_info BLOB, -- received direct_queue_info BLOB, -- received - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, local_display_name TEXT NOT NULL, -- should be the same as contact - contact_profile_id INTEGER NOT NULL REFERENCES contact_profiles ON DELETE RESTRICT, - contact_id INTEGER REFERENCES contacts ON DELETE RESTRICT, + contact_profile_id INTEGER NOT NULL REFERENCES contact_profiles ON DELETE CASCADE, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, FOREIGN KEY (user_id, local_display_name) REFERENCES display_names (user_id, local_display_name) - ON DELETE RESTRICT + ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE (group_id, member_id) ); -CREATE INDEX idx_groups_inv_queue_info ON groups (inv_queue_info); - CREATE TABLE group_member_intros ( group_member_intro_id INTEGER PRIMARY KEY, re_group_member_id INTEGER NOT NULL REFERENCES group_members (group_member_id) ON DELETE CASCADE, @@ -135,28 +135,28 @@ CREATE TABLE group_member_intros ( CREATE TABLE files ( file_id INTEGER PRIMARY KEY, - contact_id INTEGER REFERENCES contacts ON DELETE RESTRICT, - group_id INTEGER REFERENCES groups ON DELETE RESTRICT, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_id INTEGER REFERENCES groups ON DELETE CASCADE, file_name TEXT NOT NULL, file_path TEXT, file_size INTEGER NOT NULL, chunk_size INTEGER NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), - user_id INTEGER NOT NULL REFERENCES users + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE ); CREATE TABLE snd_files ( - file_id INTEGER NOT NULL REFERENCES files ON DELETE RESTRICT, - connection_id INTEGER NOT NULL REFERENCES connections ON DELETE RESTRICT, + file_id INTEGER NOT NULL REFERENCES files ON DELETE CASCADE, + connection_id INTEGER NOT NULL REFERENCES connections ON DELETE CASCADE, file_status TEXT NOT NULL, -- new, accepted, connected, completed - group_member_id INTEGER REFERENCES group_members ON DELETE RESTRICT, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, PRIMARY KEY (file_id, connection_id) ) WITHOUT ROWID; CREATE TABLE rcv_files ( - file_id INTEGER PRIMARY KEY REFERENCES files ON DELETE RESTRICT, + file_id INTEGER PRIMARY KEY REFERENCES files ON DELETE CASCADE, file_status TEXT NOT NULL, -- new, accepted, connected, completed - group_member_id INTEGER REFERENCES group_members ON DELETE RESTRICT, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, file_queue_info BLOB ); @@ -171,7 +171,7 @@ CREATE TABLE snd_file_chunks ( ) WITHOUT ROWID; CREATE TABLE rcv_file_chunks ( - file_id INTEGER NOT NULL REFERENCES rcv_files, + file_id INTEGER NOT NULL REFERENCES rcv_files ON DELETE CASCADE, chunk_number INTEGER NOT NULL, chunk_agent_msg_id INTEGER NOT NULL, chunk_stored INTEGER NOT NULL DEFAULT 0, -- 0 (received), 1 (appended to file) @@ -182,19 +182,19 @@ CREATE TABLE connections ( -- all SMP agent connections connection_id INTEGER PRIMARY KEY, agent_conn_id BLOB NOT NULL UNIQUE, conn_level INTEGER NOT NULL DEFAULT 0, - via_contact INTEGER REFERENCES contacts (contact_id), + via_contact INTEGER REFERENCES contacts (contact_id) ON DELETE SET NULL, conn_status TEXT NOT NULL, conn_type TEXT NOT NULL, -- contact, member, rcv_file, snd_file - user_contact_link_id INTEGER REFERENCES user_contact_links ON DELETE RESTRICT, - contact_id INTEGER REFERENCES contacts ON DELETE RESTRICT, - group_member_id INTEGER REFERENCES group_members ON DELETE RESTRICT, + user_contact_link_id INTEGER REFERENCES user_contact_links ON DELETE CASCADE, + contact_id INTEGER REFERENCES contacts ON DELETE CASCADE, + group_member_id INTEGER REFERENCES group_members ON DELETE CASCADE, snd_file_id INTEGER, - rcv_file_id INTEGER REFERENCES rcv_files (file_id) ON DELETE RESTRICT, + rcv_file_id INTEGER REFERENCES rcv_files (file_id) ON DELETE CASCADE, created_at TEXT NOT NULL DEFAULT (datetime('now')), - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, FOREIGN KEY (snd_file_id, connection_id) REFERENCES snd_files (file_id, connection_id) - ON DELETE RESTRICT + ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED ); @@ -203,7 +203,7 @@ CREATE TABLE user_contact_links ( conn_req_contact BLOB NOT NULL, local_display_name TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL DEFAULT (datetime('now')), - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, UNIQUE (user_id, local_display_name) ); @@ -213,13 +213,15 @@ CREATE TABLE contact_requests ( ON UPDATE CASCADE ON DELETE CASCADE, agent_invitation_id BLOB NOT NULL, contact_profile_id INTEGER REFERENCES contact_profiles - DEFERRABLE INITIALLY DEFERRED, -- NULL if it's an incognito profile + ON DELETE SET NULL -- NULL if it's an incognito profile + DEFERRABLE INITIALLY DEFERRED, local_display_name TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), - user_id INTEGER NOT NULL REFERENCES users, + user_id INTEGER NOT NULL REFERENCES users ON DELETE CASCADE, FOREIGN KEY (user_id, local_display_name) REFERENCES display_names (user_id, local_display_name) ON UPDATE CASCADE + ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, UNIQUE (user_id, local_display_name), UNIQUE (user_id, contact_profile_id) diff --git a/tests/ChatTests.hs b/tests/ChatTests.hs index dfbc9ebcc..2a4d4e05b 100644 --- a/tests/ChatTests.hs +++ b/tests/ChatTests.hs @@ -295,6 +295,8 @@ testGroup2 = ] dan #> "#club how is it going?" dan <## "you are no longer a member of the group" + dan ##> "/d #club" + dan <## "#club: you deleted the group" dan <##> cath dan <##> alice -- member leaves @@ -316,6 +318,8 @@ testGroup2 = (bob "#club how is it going?" bob <## "you are no longer a member of the group" + bob ##> "/d #club" + bob <## "#club: you deleted the group" bob <##> cath bob <##> alice @@ -338,6 +342,8 @@ testGroupDelete = bob <## "#team: you deleted the group" cath #> "#team hi" cath <## "you are no longer a member of the group" + cath ##> "/d #team" + cath <## "#team: you deleted the group" testGroupDeleteWhenInvited :: IO () testGroupDeleteWhenInvited =