-- CableGUI v3 initial schema. See docs/design.md §2. -- A project IS a drawing. LOFT and OFFICE are separate projects. -- One project ↔ one .excalidraw file in mExDraw. CREATE TABLE projects ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, drawing_name TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); -- Cable types: GLOBAL legend, shared across all projects. -- Seeded once below with the 5 defaults. CREATE TABLE cable_types ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, color TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE frames ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, name TEXT NOT NULL, x REAL NOT NULL DEFAULT 0, y REAL NOT NULL DEFAULT 0, width REAL NOT NULL DEFAULT 1200, height REAL NOT NULL DEFAULT 800, excalidraw_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (project_id, name), UNIQUE (project_id, excalidraw_id) ); CREATE INDEX frames_project_idx ON frames(project_id); CREATE TABLE devices ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, frame_id INTEGER REFERENCES frames(id) ON DELETE SET NULL, name TEXT NOT NULL, color TEXT NOT NULL DEFAULT '#1e1e1e', x REAL NOT NULL, y REAL NOT NULL, width REAL NOT NULL, height REAL NOT NULL, excalidraw_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (project_id, name), UNIQUE (project_id, excalidraw_id) ); CREATE INDEX devices_project_idx ON devices(project_id); CREATE INDEX devices_frame_idx ON devices(frame_id); CREATE TABLE ports ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE, type_id INTEGER NOT NULL REFERENCES cable_types(id) ON DELETE RESTRICT, label TEXT, x_offset REAL NOT NULL, y_offset REAL NOT NULL, excalidraw_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (project_id, excalidraw_id) ); CREATE INDEX ports_project_idx ON ports(project_id); CREATE INDEX ports_device_idx ON ports(device_id); CREATE INDEX ports_type_idx ON ports(type_id); CREATE TABLE io_markers ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, frame_id INTEGER REFERENCES frames(id) ON DELETE SET NULL, label TEXT NOT NULL DEFAULT 'IO', x REAL NOT NULL, y REAL NOT NULL, excalidraw_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (project_id, excalidraw_id) ); CREATE INDEX io_markers_project_idx ON io_markers(project_id); CREATE INDEX io_markers_frame_idx ON io_markers(frame_id); CREATE TABLE cables ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, type_id INTEGER NOT NULL REFERENCES cable_types(id) ON DELETE RESTRICT, label TEXT, from_port_id INTEGER REFERENCES ports(id) ON DELETE SET NULL, from_device_id INTEGER REFERENCES devices(id) ON DELETE SET NULL, from_io_id INTEGER REFERENCES io_markers(id) ON DELETE SET NULL, to_port_id INTEGER REFERENCES ports(id) ON DELETE SET NULL, to_device_id INTEGER REFERENCES devices(id) ON DELETE SET NULL, to_io_id INTEGER REFERENCES io_markers(id) ON DELETE SET NULL, excalidraw_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), CHECK ( (from_port_id IS NOT NULL) + (from_device_id IS NOT NULL) + (from_io_id IS NOT NULL) = 1 ), CHECK ( (to_port_id IS NOT NULL) + (to_device_id IS NOT NULL) + (to_io_id IS NOT NULL) = 1 ), UNIQUE (project_id, excalidraw_id) ); CREATE INDEX cables_project_idx ON cables(project_id); CREATE INDEX cables_from_port_idx ON cables(from_port_id); CREATE INDEX cables_to_port_idx ON cables(to_port_id); CREATE INDEX cables_from_device_idx ON cables(from_device_id); CREATE INDEX cables_to_device_idx ON cables(to_device_id); CREATE INDEX cables_type_idx ON cables(type_id); CREATE TABLE bundles ( id INTEGER PRIMARY KEY, project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, name TEXT NOT NULL, auto INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE (project_id, name) ); CREATE INDEX bundles_project_idx ON bundles(project_id); CREATE TABLE bundle_cables ( bundle_id INTEGER NOT NULL REFERENCES bundles(id) ON DELETE CASCADE, cable_id INTEGER NOT NULL REFERENCES cables(id) ON DELETE CASCADE, PRIMARY KEY (bundle_id, cable_id) ); CREATE INDEX bundle_cables_cable_idx ON bundle_cables(cable_id); -- Seed the 5 default cable types, once. INSERT INTO cable_types (name, color) VALUES ('Power', '#e03131'), ('USB', '#2f9e44'), ('HDMI', '#1971c2'), ('DP', '#9c36b5'), ('RJ45', '#ffd500');