Skip to main content

mail4agent_server/
dag_schema.rs

1//! Tables of the room DAG layer (see `f3.rs`): events with their edges, forward extremities and
2//! state groups. Created together with the rest of the messenger schema, always (they are empty
3//! unless the `f3-hash-ids` feature has made a room a DAG room), idempotently, inside the single
4//! writer's boot step, so a database can switch the feature on or off without a migration.
5//!
6//! * `dag_rooms`: rooms that are DAG rooms. Every other room is legacy and never appears here.
7//! * `dag_events`: one row per event the room knows (accepted, soft-failed, or imported as an
8//!   outlier). `pdu` is the signed wire JSON, or its skeleton once the content was erased.
9//! * `dag_edges` / `dag_auth`: `prev_events` and `auth_events` of each event.
10//! * `dag_extremities`: the room's forward extremities.
11//! * `dag_state_groups` + `dag_state_group_entries`: full state snapshots; `dag_event_state` maps
12//!   an event to the snapshot of the room state after it. A message shares its parent's group.
13
14use rusqlite::Connection;
15
16pub fn create_dag_schema(conn: &Connection) -> rusqlite::Result<()> {
17    conn.execute_batch(
18        r#"
19        CREATE TABLE IF NOT EXISTS dag_rooms (
20            room_id      TEXT PRIMARY KEY,
21            room_version TEXT NOT NULL DEFAULT '11'
22        );
23        CREATE TABLE IF NOT EXISTS dag_events (
24            event_id         TEXT PRIMARY KEY,
25            room_id          TEXT NOT NULL,
26            depth            INTEGER NOT NULL,
27            event_type       TEXT NOT NULL,
28            sender           TEXT NOT NULL,
29            state_key        TEXT,
30            origin_server_ts INTEGER NOT NULL,
31            pdu              TEXT NOT NULL,
32            outlier          INTEGER NOT NULL DEFAULT 0,
33            soft_failed      INTEGER NOT NULL DEFAULT 0,
34            skeleton         INTEGER NOT NULL DEFAULT 0
35        );
36        CREATE INDEX IF NOT EXISTS dag_events_room ON dag_events (room_id, depth);
37        CREATE TABLE IF NOT EXISTS dag_edges (
38            event_id      TEXT NOT NULL,
39            prev_event_id TEXT NOT NULL,
40            PRIMARY KEY (event_id, prev_event_id)
41        );
42        CREATE TABLE IF NOT EXISTS dag_auth (
43            event_id      TEXT NOT NULL,
44            auth_event_id TEXT NOT NULL,
45            PRIMARY KEY (event_id, auth_event_id)
46        );
47        CREATE TABLE IF NOT EXISTS dag_extremities (
48            room_id  TEXT NOT NULL,
49            event_id TEXT NOT NULL,
50            PRIMARY KEY (room_id, event_id)
51        );
52        CREATE TABLE IF NOT EXISTS dag_state_groups (
53            group_id INTEGER PRIMARY KEY AUTOINCREMENT,
54            room_id  TEXT NOT NULL
55        );
56        CREATE TABLE IF NOT EXISTS dag_state_group_entries (
57            group_id   INTEGER NOT NULL,
58            event_type TEXT NOT NULL,
59            state_key  TEXT NOT NULL,
60            event_id   TEXT NOT NULL,
61            PRIMARY KEY (group_id, event_type, state_key)
62        );
63        CREATE TABLE IF NOT EXISTS dag_event_state (
64            event_id TEXT PRIMARY KEY,
65            group_id INTEGER NOT NULL
66        );
67        "#,
68    )
69}