Files
narl-workspace/migrations/0019_trash.sql
T
nvrl 8ffad6350f trash: a delete can be undone
`x`, `dd`, `:delete` and `:rmspace` no longer end anything. What they
delete is moved, whole, under one hidden root, and `u` puts the last of it
back where it was. `:trash` lists everything deleted, the last first:
Enter or `r` restores, `x` deletes one for good and `:trash purge` empties
it, each asking first. Something whose folder has gone since comes back to
the root of its space; something whose space is in the trash too waits for
the space. The daily sweep purges what has waited WORKSPACE_TRASH_DAYS (30),
and only then are its files deleted.

While it waits, a trashed node is out of the tree, the search, the agenda,
the mails, the SFTP mount, the export and the readable files/ view, and a
shared document answers 404 until it comes back with the same link. `rm`
over the mount trashes too; a rename onto a taken name still replaces what
was there, so editor saves do not fill the trash.
2026-10-20 18:15:22 +02:00

23 lines
1.2 KiB
SQL

-- A delete puts a node in the trash rather than ending it. The trash is one
-- hidden root: a folder, not a space, so nothing that lists the spaces or
-- walks down from them ever reaches it, and a trashed node — moved under it
-- whole, with everything inside — drops out of the tree, the search, the
-- mount, the export and the readable mirror at once. The slug starts with a
-- dot, which no name ever slugifies to, so no space can take it.
INSERT INTO nodes (parent_id, kind, name, slug, role, created_at, updated_at)
VALUES (NULL, 'folder', 'trash', '.trash', 'trash', strftime('%s', 'now'), strftime('%s', 'now'));
-- One row per thing deleted, not per node under it: a folder comes back with
-- what was in it. Where it came from is kept by id, to go back to, and as the
-- path it had, to show once that folder is gone too. A trashed space has no
-- parent to go back to; it goes back to the root.
CREATE TABLE trash (
node_id INTEGER PRIMARY KEY REFERENCES nodes (id) ON DELETE CASCADE,
from_parent INTEGER,
from_space INTEGER,
from_path TEXT NOT NULL,
deleted_at INTEGER NOT NULL
);
CREATE INDEX idx_trash_deleted ON trash (deleted_at);