mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-11-04 22:33:43 -05:00
external_id was the full relative path on every record and UNIQUE(type, external_id) held a second copy, which on a 2.1M record store was 518 MB of a 1.01 GB file. The old library stored a path once per directory and found everything else through parent_id and name. external_id is nullable now. A filesystem directory keeps its path, a file stores nothing and is addressed by (parent_uuid, title), and an adapter record is untouched because a Notion page has no tree to be found through. NULLs are distinct under a SQLite unique index, so UNIQUE(type, external_id) still catches two records claiming one key. UNIQUE(parent_uuid, title) is added, which is the constraint that was always true and never stated, and it replaces idx_record_parent since it covers the same prefix. Lookup stays two probes. SourceDb::resolve_path takes directory_path for the parent and then the name beneath it, and producing a path is the same in reverse. Nothing walks the tree in either direction. Ledger::load rebuilds a file's path from its parent's. The ledger still holds full paths in memory because resolution asks about one per observation and a join per question is not a trade worth making for a table read once. Renaming a directory rewrites directory_path for the directories under it rather than every record under it, in the same transaction as the batch, and Ledger::rename_tree does the same in memory. Records inside a renamed directory do not change at all: they keep their parent and their name and are simply reached a different way. An index built against the old shape is dropped and rebuilt on open, since RECORD_SCHEMA is IF NOT EXISTS throughout and would otherwise keep a NOT NULL external_id and never gain directory_path. record_overlay survives, which is why it has no foreign key to record, and rebind_overlays now resolves a path when the direct key lookup misses. The store tests grew a walk() helper that observes every directory on the way to a file, because writing a file with no parent was never what a walk does and it is now the difference between a record that can be addressed and one that cannot.