Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Bolt's Journal

## 2024-05-23 - Composite Index for Playlist Thumbnails
**Learning:** SQLite query optimizer needs explicit composite indexes for `WHERE x = ? ORDER BY y` clauses to avoid in-memory sorting, especially when used in correlated subqueries.
**Action:** Always check `ORDER BY` clauses in frequently run queries (like startup routines) and ensure covering indexes exist.
6 changes: 6 additions & 0 deletions src/main/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,19 @@ function initialize(app, customPath = null) {
table.integer('sortOrder');
table.primary(['playlistId', 'videoId']);
table.index('playlistId');
table.index(['playlistId', 'sortOrder'], 'idx_playlist_video_sort');
});
} else {
try {
await db.schema.alterTable('playlist_videos', (t) =>
t.index('playlistId')
);
} catch (e) {}
try {
await db.schema.alterTable('playlist_videos', (t) =>
t.index(['playlistId', 'sortOrder'], 'idx_playlist_video_sort')
);
} catch (e) {}
}

if (!(await db.schema.hasTable('artists'))) {
Expand Down
7 changes: 7 additions & 0 deletions test/integration/database_advanced.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,11 @@ describe('Advanced Database Logic', () => {
expect(all.length).toBe(1);
expect(all[0].name).toBe('Busy Artist');
});

test('should have composite index on playlist_videos', async () => {
const db = database.getDB();
const indexes = await db.raw("PRAGMA index_list('playlist_videos')");
const hasIndex = indexes.some(idx => idx.name === 'idx_playlist_video_sort');
expect(hasIndex).toBe(true);
});
});