Delete a bot file's chunks with the file

ON DELETE CASCADE only fires when PRAGMA foreign_keys is on, and only
src/server.ts turns it on. A script or CLI process deleting a bot file
therefore left every bot_file_chunks row behind, and the next
`bun run db:schema` failed with

    Foreign key violations after schema sync: bot_file_chunks -> bot_files

deleteBotFile and purgeStorage now delete the chunks themselves, so the
cascade is no longer load-bearing and a maintenance script behaves like
the server.
This commit is contained in:
2026-10-22 07:37:24 +01:00
parent de863618ba
commit 43e70de983
2 changed files with 18 additions and 0 deletions
@@ -33,6 +33,13 @@ export default async function deleteBotFile({ scopes, file_id }: Params) {
} }
await BunSQLite.sql({ sql: `DELETE FROM bot_file_vectors WHERE file_id = ?`, values: [file.id] }); await BunSQLite.sql({ sql: `DELETE FROM bot_file_vectors WHERE file_id = ?`, values: [file.id] });
/**
* Deleted here rather than left to the schema's cascade: SQLite has
* foreign keys off per connection unless `enableForeignKeys` ran, and
* a script or CLI process that deletes a file would otherwise leave
* its chunks behind, which then fail the next schema sync.
*/
await BunSQLite.sql({ sql: `DELETE FROM bot_file_chunks WHERE file_id = ?`, values: [file.id] });
await BunSQLite.sql({ sql: `DELETE FROM bot_files WHERE id = ?`, values: [file.id] }); await BunSQLite.sql({ sql: `DELETE FROM bot_files WHERE id = ?`, values: [file.id] });
/** /**
* Its pending ingestion would only find nothing left. * Its pending ingestion would only find nothing left.
@@ -59,6 +59,17 @@ export default async function purgeStorage({ scope, owner_id, media_ids }: Param
values: [scope, owner_id], values: [scope, owner_id],
}).catch(() => {}); }).catch(() => {});
/**
* Deleted here rather than left to the cascade, since SQLite has
* foreign keys off per connection unless `enableForeignKeys` ran (a
* script or CLI process never does), and a chunk left behind fails
* the next schema sync.
*/
await BunSQLite.sql({
sql: `DELETE FROM bot_file_chunks WHERE scope = ? AND owner_id = ?`,
values: [scope, owner_id],
}).catch(() => {});
/** /**
* Usually gone already, with the bot or workspace (the cascade). * Usually gone already, with the bot or workspace (the cascade).
*/ */