From 1fa80e31d1c855041939b49ce78e7c510f2affea Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Sat, 19 Oct 2024 10:40:17 -0700 Subject: [PATCH 1/5] Add: migrations for authors, series, and podcast episodes --- server/migrations/v2.15.2-index-creation.js | 78 +++++++++++++++++++++ server/models/BookAuthor.js | 8 ++- server/models/BookSeries.js | 8 ++- server/models/PodcastEpisode.js | 2 +- 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 server/migrations/v2.15.2-index-creation.js diff --git a/server/migrations/v2.15.2-index-creation.js b/server/migrations/v2.15.2-index-creation.js new file mode 100644 index 00000000..8f5b9d52 --- /dev/null +++ b/server/migrations/v2.15.2-index-creation.js @@ -0,0 +1,78 @@ +/** + * @typedef MigrationContext + * @property {import('sequelize').QueryInterface} queryInterface - a suquelize QueryInterface object. + * @property {import('../Logger')} logger - a Logger object. + * + * @typedef MigrationOptions + * @property {MigrationContext} context - an object containing the migration context. + */ + +/** + * This upward migration script adds indexes to speed up queries on the `BookAuthor`, `BookSeries`, and `PodcastEpisode` tables. + * + * @param {MigrationOptions} options - an object containing the migration context. + * @returns {Promise} - A promise that resolves when the migration is complete. + */ +async function up({ context: { queryInterface, logger } }) { + // Upwards migration script + logger.info('[2.15.2 migration] UPGRADE BEGIN: 2.15.2-index-creation') + + // Create index for bookAuthors + logger.info('[2.15.2 migration] Creating index for bookAuthors') + await queryInterface.addIndex('BookAuthor', ['authorId'], { + name: 'bookAuthor_authorId' + }) + + // Create index for bookSeries + logger.info('[2.15.2 migration] Creating index for bookSeries') + await queryInterface.addIndex('BookSeries', ['seriesId'], { + name: 'bookSeries_seriesId' + }) + + // Delete existing podcastEpisode index + logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') + await queryInterface.removeIndex('PodcastEpisode', 'podcast_episode_created_at') + + // Create index for podcastEpisode and createdAt + logger.info('[2.15.2 migration] Creating index for podcastEpisode and createdAt') + await queryInterface.addIndex('PodcastEpisode', ['createdAt', 'podcastId'], { + name: 'podcastEpisode_createdAt_podcastId' + }) + + // Completed migration + logger.info('[2.15.2 migration] UPGRADE END: 2.15.2-index-creation') +} + +/** + * This downward migration script removes the newly created indexes and re-adds the old index on the `PodcastEpisode` table. + * + * @param {MigrationOptions} options - an object containing the migration context. + * @returns {Promise} - A promise that resolves when the migration is complete. + */ +async function down({ context: { queryInterface, logger } }) { + // Downward migration script + logger.info('[2.15.2 migration] DOWNGRADE BEGIN: 2.15.2-index-creation') + + // Remove index for bookAuthors + logger.info('[2.15.2 migration] Removing index for bookAuthors') + await queryInterface.removeIndex('BookAuthor', 'bookAuthor_authorId') + + // Remove index for bookSeries + logger.info('[2.15.2 migration] Removing index for bookSeries') + await queryInterface.removeIndex('BookSeries', 'bookSeries_seriesId') + + // Delete existing podcastEpisode index + logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') + await queryInterface.removeIndex('PodcastEpisode', 'podcastEpisode_createdAt_podcastId') + + // Create index for podcastEpisode and createdAt + logger.info('[2.15.2 migration] Creating index for podcastEpisode createdAt') + await queryInterface.addIndex('PodcastEpisode', ['createdAt'], { + name: 'podcast_episode_created_at' + }) + + // Finished migration + logger.info('[2.15.2 migration] DOWNGRADE END: 2.15.2-index-creation') +} + +module.exports = { up, down } diff --git a/server/models/BookAuthor.js b/server/models/BookAuthor.js index 8e093671..d7d65728 100644 --- a/server/models/BookAuthor.js +++ b/server/models/BookAuthor.js @@ -54,7 +54,13 @@ class BookAuthor extends Model { sequelize, modelName: 'bookAuthor', timestamps: true, - updatedAt: false + updatedAt: false, + indexes: [ + { + name: 'bookAuthor_authorId', + fields: ['authorId'] + } + ] } ) diff --git a/server/models/BookSeries.js b/server/models/BookSeries.js index fad54718..31eccb9f 100644 --- a/server/models/BookSeries.js +++ b/server/models/BookSeries.js @@ -43,7 +43,13 @@ class BookSeries extends Model { sequelize, modelName: 'bookSeries', timestamps: true, - updatedAt: false + updatedAt: false, + indexes: [ + { + name: 'bookSeries_seriesId', + fields: ['seriesId'] + } + ] } ) diff --git a/server/models/PodcastEpisode.js b/server/models/PodcastEpisode.js index 1707fbd5..937e0b31 100644 --- a/server/models/PodcastEpisode.js +++ b/server/models/PodcastEpisode.js @@ -157,7 +157,7 @@ class PodcastEpisode extends Model { modelName: 'podcastEpisode', indexes: [ { - fields: ['createdAt'] + fields: ['createdAt', 'podcastId'] } ] } From ea6882d9aba1ee5dcb1f1de98dc9036ee962d19b Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Sat, 19 Oct 2024 11:20:22 -0700 Subject: [PATCH 2/5] Update changelog --- server/migrations/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/server/migrations/changelog.md b/server/migrations/changelog.md index 92be2cd5..3623300f 100644 --- a/server/migrations/changelog.md +++ b/server/migrations/changelog.md @@ -6,3 +6,4 @@ Please add a record of every database migration that you create to this file. Th | -------------- | ---------------------------- | ------------------------------------------------------------------------------------ | | v2.15.0 | v2.15.0-series-column-unique | Series must have unique names in the same library | | v2.15.1 | v2.15.1-reindex-nocase | Fix potential db corruption issues due to bad sqlite extension introduced in v2.12.0 | +| v2.15.2 | v2.15.2-index-creation | Creates author, series, and podcast episode indexes | From e8a1ea3b541888f49c9809f40bb341f193dc085e Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Sat, 19 Oct 2024 11:20:29 -0700 Subject: [PATCH 3/5] Fix: table naming --- server/migrations/v2.15.2-index-creation.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/server/migrations/v2.15.2-index-creation.js b/server/migrations/v2.15.2-index-creation.js index 8f5b9d52..b4490b3e 100644 --- a/server/migrations/v2.15.2-index-creation.js +++ b/server/migrations/v2.15.2-index-creation.js @@ -8,7 +8,7 @@ */ /** - * This upward migration script adds indexes to speed up queries on the `BookAuthor`, `BookSeries`, and `PodcastEpisode` tables. + * This upward migration script adds indexes to speed up queries on the `BookAuthor`, `BookSeries`, and `podcastEpisodes` tables. * * @param {MigrationOptions} options - an object containing the migration context. * @returns {Promise} - A promise that resolves when the migration is complete. @@ -19,23 +19,23 @@ async function up({ context: { queryInterface, logger } }) { // Create index for bookAuthors logger.info('[2.15.2 migration] Creating index for bookAuthors') - await queryInterface.addIndex('BookAuthor', ['authorId'], { + await queryInterface.addIndex('bookAuthors', ['authorId'], { name: 'bookAuthor_authorId' }) // Create index for bookSeries logger.info('[2.15.2 migration] Creating index for bookSeries') - await queryInterface.addIndex('BookSeries', ['seriesId'], { + await queryInterface.addIndex('bookSeries', ['seriesId'], { name: 'bookSeries_seriesId' }) // Delete existing podcastEpisode index logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') - await queryInterface.removeIndex('PodcastEpisode', 'podcast_episode_created_at') + await queryInterface.removeIndex('podcastEpisodes', 'podcast_episode_created_at') // Create index for podcastEpisode and createdAt logger.info('[2.15.2 migration] Creating index for podcastEpisode and createdAt') - await queryInterface.addIndex('PodcastEpisode', ['createdAt', 'podcastId'], { + await queryInterface.addIndex('podcastEpisodes', ['createdAt', 'podcastId'], { name: 'podcastEpisode_createdAt_podcastId' }) @@ -44,7 +44,7 @@ async function up({ context: { queryInterface, logger } }) { } /** - * This downward migration script removes the newly created indexes and re-adds the old index on the `PodcastEpisode` table. + * This downward migration script removes the newly created indexes and re-adds the old index on the `podcastEpisodes` table. * * @param {MigrationOptions} options - an object containing the migration context. * @returns {Promise} - A promise that resolves when the migration is complete. @@ -55,19 +55,19 @@ async function down({ context: { queryInterface, logger } }) { // Remove index for bookAuthors logger.info('[2.15.2 migration] Removing index for bookAuthors') - await queryInterface.removeIndex('BookAuthor', 'bookAuthor_authorId') + await queryInterface.removeIndex('bookAuthors', 'bookAuthor_authorId') // Remove index for bookSeries logger.info('[2.15.2 migration] Removing index for bookSeries') - await queryInterface.removeIndex('BookSeries', 'bookSeries_seriesId') + await queryInterface.removeIndex('bookSeries', 'bookSeries_seriesId') // Delete existing podcastEpisode index logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') - await queryInterface.removeIndex('PodcastEpisode', 'podcastEpisode_createdAt_podcastId') + await queryInterface.removeIndex('podcastEpisodes', 'podcastEpisode_createdAt_podcastId') // Create index for podcastEpisode and createdAt logger.info('[2.15.2 migration] Creating index for podcastEpisode createdAt') - await queryInterface.addIndex('PodcastEpisode', ['createdAt'], { + await queryInterface.addIndex('podcastEpisodes', ['createdAt'], { name: 'podcast_episode_created_at' }) From 84012d9090221da442ef1d6cf9b271ef31db92a9 Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Sat, 19 Oct 2024 11:38:34 -0700 Subject: [PATCH 4/5] Fix: podcast episode index name --- server/migrations/v2.15.2-index-creation.js | 6 +++--- server/models/PodcastEpisode.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/migrations/v2.15.2-index-creation.js b/server/migrations/v2.15.2-index-creation.js index b4490b3e..4e9915c2 100644 --- a/server/migrations/v2.15.2-index-creation.js +++ b/server/migrations/v2.15.2-index-creation.js @@ -31,7 +31,7 @@ async function up({ context: { queryInterface, logger } }) { // Delete existing podcastEpisode index logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') - await queryInterface.removeIndex('podcastEpisodes', 'podcast_episode_created_at') + await queryInterface.removeIndex('podcastEpisodes', 'podcast_episodes_created_at') // Create index for podcastEpisode and createdAt logger.info('[2.15.2 migration] Creating index for podcastEpisode and createdAt') @@ -66,9 +66,9 @@ async function down({ context: { queryInterface, logger } }) { await queryInterface.removeIndex('podcastEpisodes', 'podcastEpisode_createdAt_podcastId') // Create index for podcastEpisode and createdAt - logger.info('[2.15.2 migration] Creating index for podcastEpisode createdAt') + logger.info('[2.15.2 migration] Creating original index for podcastEpisode createdAt') await queryInterface.addIndex('podcastEpisodes', ['createdAt'], { - name: 'podcast_episode_created_at' + name: 'podcast_episodes_created_at' }) // Finished migration diff --git a/server/models/PodcastEpisode.js b/server/models/PodcastEpisode.js index 937e0b31..1f99361a 100644 --- a/server/models/PodcastEpisode.js +++ b/server/models/PodcastEpisode.js @@ -157,6 +157,7 @@ class PodcastEpisode extends Model { modelName: 'podcastEpisode', indexes: [ { + name: 'podcastEpisode_createdAt_podcastId', fields: ['createdAt', 'podcastId'] } ] From 35e2681ea9d1193b259e5a73b3643dc876b8a48c Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 19 Oct 2024 15:45:14 -0500 Subject: [PATCH 5/5] Update index creation migration to be idempotent --- server/migrations/v2.15.2-index-creation.js | 33 +++++++++++++++------ 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/server/migrations/v2.15.2-index-creation.js b/server/migrations/v2.15.2-index-creation.js index 4e9915c2..f1302dd2 100644 --- a/server/migrations/v2.15.2-index-creation.js +++ b/server/migrations/v2.15.2-index-creation.js @@ -19,15 +19,25 @@ async function up({ context: { queryInterface, logger } }) { // Create index for bookAuthors logger.info('[2.15.2 migration] Creating index for bookAuthors') - await queryInterface.addIndex('bookAuthors', ['authorId'], { - name: 'bookAuthor_authorId' - }) + const bookAuthorsIndexes = await queryInterface.showIndex('bookAuthors') + if (!bookAuthorsIndexes.some((index) => index.name === 'bookAuthor_authorId')) { + await queryInterface.addIndex('bookAuthors', ['authorId'], { + name: 'bookAuthor_authorId' + }) + } else { + logger.info('[2.15.2 migration] Index bookAuthor_authorId already exists') + } // Create index for bookSeries logger.info('[2.15.2 migration] Creating index for bookSeries') - await queryInterface.addIndex('bookSeries', ['seriesId'], { - name: 'bookSeries_seriesId' - }) + const bookSeriesIndexes = await queryInterface.showIndex('bookSeries') + if (!bookSeriesIndexes.some((index) => index.name === 'bookSeries_seriesId')) { + await queryInterface.addIndex('bookSeries', ['seriesId'], { + name: 'bookSeries_seriesId' + }) + } else { + logger.info('[2.15.2 migration] Index bookSeries_seriesId already exists') + } // Delete existing podcastEpisode index logger.info('[2.15.2 migration] Deleting existing podcastEpisode index') @@ -35,9 +45,14 @@ async function up({ context: { queryInterface, logger } }) { // Create index for podcastEpisode and createdAt logger.info('[2.15.2 migration] Creating index for podcastEpisode and createdAt') - await queryInterface.addIndex('podcastEpisodes', ['createdAt', 'podcastId'], { - name: 'podcastEpisode_createdAt_podcastId' - }) + const podcastEpisodesIndexes = await queryInterface.showIndex('podcastEpisodes') + if (!podcastEpisodesIndexes.some((index) => index.name === 'podcastEpisode_createdAt_podcastId')) { + await queryInterface.addIndex('podcastEpisodes', ['createdAt', 'podcastId'], { + name: 'podcastEpisode_createdAt_podcastId' + }) + } else { + logger.info('[2.15.2 migration] Index podcastEpisode_createdAt_podcastId already exists') + } // Completed migration logger.info('[2.15.2 migration] UPGRADE END: 2.15.2-index-creation')