Files
CableGUI/internal/db/migrations/007_clamps.sql
mAi 4202d0465f feat(v5 slice 1): clamps schema + store helpers + snapshot
Migration 007 introduces the v5 routing primitive:
- clamps table (project-scoped, optional frame_id, excalidraw_id).
- cable_clamps join (cable_id, clamp_id, ord) with PK on (cable_id, ord)
  and UNIQUE (cable_id, clamp_id) to block a clamp visiting the same
  cable twice.

Store helpers in internal/db/clamps.go:
- CreateClamp / GetClamp / ListClamps / UpdateClamp / DeleteClamp —
  standard project-scoped CRUD. UpdateClamp uses FrameRef tri-state.
- AttachClampToCable — appends or inserts at a given ord. Mid-sequence
  inserts use a two-pass shift (bump by 10000, settle to ord+1) since
  SQLite UPDATE doesn't support ORDER BY and a single bulk +1 would
  collide with the UNIQUE (cable_id, ord) PK.
- DetachClampFromCable — removes the row then closes the gap.
- ReorderCableClamps — replaces the whole sequence in one tx.
- ListClampsForCable / ListCableClamps — read helpers.

Snapshot now carries clamps + cable_clamps arrays so the frontend can
hydrate everything in one call.

Tests cover create / update / cascade-delete / attach (append + insert
+ duplicate-rejected) / detach (gap closes) / reorder / snapshot.
2026-05-16 13:40:53 +02:00

32 lines
1.4 KiB
SQL

-- mCables v5 — cable routing via clamps. See docs/design.md §11.
--
-- A clamp is a physical anchor placed on the canvas. A cable's polyline
-- runs from its `from` endpoint → its clamps in `ord` sequence → its
-- `to` endpoint. Cables that share an ordered pair of consecutive
-- clamps are visibly bundled along that segment (computed live by the
-- frontend; no detection pass).
CREATE TABLE clamps (
id INTEGER PRIMARY KEY,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
x REAL NOT NULL,
y REAL NOT NULL,
label TEXT NOT NULL DEFAULT '',
frame_id INTEGER REFERENCES frames(id) ON DELETE SET 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 clamps_project_idx ON clamps(project_id);
CREATE INDEX clamps_frame_idx ON clamps(frame_id);
CREATE TABLE cable_clamps (
cable_id INTEGER NOT NULL REFERENCES cables(id) ON DELETE CASCADE,
clamp_id INTEGER NOT NULL REFERENCES clamps(id) ON DELETE CASCADE,
ord INTEGER NOT NULL, -- 1-based along from→to
PRIMARY KEY (cable_id, ord),
UNIQUE (cable_id, clamp_id)
);
CREATE INDEX cable_clamps_clamp_idx ON cable_clamps(clamp_id);