made tiny updates

This commit is contained in:
SinachPat
2026-05-04 12:30:56 +01:00
parent 3f029e15c2
commit 5b2d918c13
47 changed files with 2597 additions and 521 deletions
+52 -39
View File
@@ -1,46 +1,59 @@
-- Origin Graph — Artboard Ancestry Materialized View
-- Migration: 002
-- Pre-computes all ancestor/descendant relationships so the app never needs
-- recursive CTEs at query time. Updated automatically on artboards INSERT.
-- ── Migration 002: Artboard Ancestry Guard ───────────────────────────────────
-- The artboard_ancestry closure table and its maintenance trigger are already
-- created in migration 001 (initial schema). This migration is a safe, idempotent
-- guard that ensures the trigger function and trigger exist as expected.
--
-- IMPORTANT: An earlier draft of this file attempted to create a MATERIALIZED
-- VIEW named artboard_ancestry, which would conflict with the table created in
-- 001. That approach has been superseded: the trigger-based closure table from
-- 001 is maintained incrementally (O(depth) per INSERT) which is far cheaper
-- than a full REFRESH MATERIALIZED VIEW CONCURRENTLY on every artboard insert.
-- Do NOT re-introduce the materialized view approach.
CREATE MATERIALIZED VIEW artboard_ancestry AS
WITH RECURSIVE ancestry(artboard_id, ancestor_id, depth) AS (
-- Base: each artboard is at depth 0 relative to itself
SELECT id AS artboard_id, id AS ancestor_id, 0 AS depth
FROM artboards
-- ── Ensure the ancestry maintenance trigger function exists ───────────────────
-- Uses CREATE OR REPLACE so the migration is idempotent; safe to re-run.
UNION ALL
-- Recurse: walk up the parent chain
SELECT a.id AS artboard_id, anc.ancestor_id, anc.depth + 1
FROM artboards a
JOIN ancestry anc ON a.parent_artboard_id = anc.artboard_id
)
SELECT artboard_id, ancestor_id, depth
FROM ancestry
WHERE artboard_id <> ancestor_id -- exclude self-reference
ORDER BY artboard_id, depth;
CREATE UNIQUE INDEX artboard_ancestry_pk
ON artboard_ancestry(artboard_id, ancestor_id);
CREATE INDEX artboard_ancestry_ancestor_idx
ON artboard_ancestry(ancestor_id);
-- ── Refresh trigger ───────────────────────────────────────────────────────────
-- Refreshes the materialized view concurrently whenever an artboard is
-- inserted. CONCURRENTLY requires the unique index above — it allows reads
-- to continue during refresh.
CREATE OR REPLACE FUNCTION refresh_artboard_ancestry()
CREATE OR REPLACE FUNCTION maintain_artboard_ancestry()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY artboard_ancestry;
RETURN NULL;
-- Self-row: every artboard is its own ancestor at depth 0.
INSERT INTO artboard_ancestry (artboard_id, ancestor_id, depth)
VALUES (NEW.id, NEW.id, 0)
ON CONFLICT DO NOTHING;
-- Inherit all ancestors of the parent at depth + 1.
IF NEW.parent_artboard_id IS NOT NULL THEN
INSERT INTO artboard_ancestry (artboard_id, ancestor_id, depth)
SELECT NEW.id, ancestor_id, depth + 1
FROM artboard_ancestry
WHERE artboard_id = NEW.parent_artboard_id
ON CONFLICT DO NOTHING;
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER trg_artboard_ancestry_refresh
AFTER INSERT OR UPDATE OF parent_artboard_id ON artboards
FOR EACH STATEMENT
EXECUTE FUNCTION refresh_artboard_ancestry();
-- ── Ensure the trigger is attached ───────────────────────────────────────────
-- DROP + recreate is the idempotent way to ensure the trigger is attached
-- exactly once; IF NOT EXISTS for triggers requires PG 17+ so use this pattern.
DROP TRIGGER IF EXISTS artboards_ancestry_insert ON artboards;
CREATE TRIGGER artboards_ancestry_insert
AFTER INSERT ON artboards
FOR EACH ROW EXECUTE FUNCTION maintain_artboard_ancestry();
-- ── RPC helper: get all descendants of an artboard ───────────────────────────
-- Complements getArtboardAncestors() in origin-graph/queries.ts.
-- Returns direct + transitive descendants, ordered nearest-first.
CREATE OR REPLACE FUNCTION get_artboard_descendants(p_artboard_id UUID)
RETURNS TABLE (artboard_id UUID, depth INTEGER)
LANGUAGE SQL STABLE AS $$
SELECT artboard_id, depth
FROM artboard_ancestry
WHERE ancestor_id = p_artboard_id
AND artboard_id <> p_artboard_id -- exclude self
ORDER BY depth, artboard_id;
$$;