(databaseArg?: IDatabase)
| 103 | } |
| 104 | |
| 105 | export async function cleanupOrphanedSyncRows(databaseArg?: IDatabase): Promise<void> { |
| 106 | const database = databaseArg ?? (await getDB()); |
| 107 | |
| 108 | const cleanupStatements = [ |
| 109 | "DELETE FROM highlights WHERE book_id NOT IN (SELECT id FROM books)", |
| 110 | "DELETE FROM notes WHERE book_id NOT IN (SELECT id FROM books)", |
| 111 | "DELETE FROM bookmarks WHERE book_id NOT IN (SELECT id FROM books)", |
| 112 | "DELETE FROM reading_sessions WHERE book_id NOT IN (SELECT id FROM books)", |
| 113 | "DELETE FROM book_tags WHERE book_id NOT IN (SELECT id FROM books) OR tag_id NOT IN (SELECT id FROM tags)", |
| 114 | "UPDATE books SET group_id = NULL WHERE group_id IS NOT NULL AND group_id NOT IN (SELECT id FROM book_groups)", |
| 115 | "DELETE FROM messages WHERE thread_id NOT IN (SELECT id FROM threads)", |
| 116 | ]; |
| 117 | |
| 118 | for (const sql of cleanupStatements) { |
| 119 | try { |
| 120 | await database.execute(sql); |
| 121 | } catch { |
| 122 | // Ignore partial cleanup failures on older schema variants. |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | export async function getDB(): Promise<IDatabase> { |
| 128 | if (db) return db; |
no test coverage detected