|
| 1 | +CREATE TABLE "blob_deletion" ( |
| 2 | + "id" uuid PRIMARY KEY DEFAULT uuidv7(), |
| 3 | + "prefix" text NOT NULL, |
| 4 | + "queued_at" timestamp with time zone DEFAULT now() NOT NULL |
| 5 | +); |
| 6 | +--> statement-breakpoint |
| 7 | +CREATE TABLE "thread_file" ( |
| 8 | + "id" uuid PRIMARY KEY DEFAULT uuidv7(), |
| 9 | + "thread_id" uuid NOT NULL, |
| 10 | + "tool_call_id" uuid, |
| 11 | + "content_type" text NOT NULL, |
| 12 | + "size" integer NOT NULL, |
| 13 | + "created_at" timestamp with time zone DEFAULT now() NOT NULL |
| 14 | +); |
| 15 | +--> statement-breakpoint |
| 16 | +CREATE INDEX "thread_file_thread_idx" ON "thread_file" ("thread_id");--> statement-breakpoint |
| 17 | +ALTER TABLE "thread_file" ADD CONSTRAINT "thread_file_thread_id_thread_id_fkey" FOREIGN KEY ("thread_id") REFERENCES "thread"("id") ON DELETE CASCADE;--> statement-breakpoint |
| 18 | +ALTER TABLE "thread_file" ADD CONSTRAINT "thread_file_tool_call_id_tool_call_id_fkey" FOREIGN KEY ("tool_call_id") REFERENCES "tool_call"("id") ON DELETE SET NULL;--> statement-breakpoint |
| 19 | + |
| 20 | +-- A thread is deleted by its workspace's, pod's or host agent's cascade as well as directly, and only the database sees every route. Queues the thread's blob folder, `threads/<id>` (see `thread-files.ts`), once per statement however many threads it deleted. |
| 21 | +CREATE FUNCTION queue_deleted_thread_blobs() RETURNS trigger |
| 22 | +LANGUAGE plpgsql AS $$ |
| 23 | +BEGIN |
| 24 | + INSERT INTO "blob_deletion" ("prefix") |
| 25 | + SELECT 'threads/' || "id"::text FROM deleted_threads; |
| 26 | + RETURN NULL; |
| 27 | +END; |
| 28 | +$$;--> statement-breakpoint |
| 29 | + |
| 30 | +CREATE TRIGGER thread_blob_deletion |
| 31 | +AFTER DELETE ON "thread" |
| 32 | +REFERENCING OLD TABLE AS deleted_threads |
| 33 | +FOR EACH STATEMENT EXECUTE FUNCTION queue_deleted_thread_blobs(); |
0 commit comments