mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update: remove the same book if occurs multiple times in duplicate series
This commit is contained in:
		
							parent
							
								
									999ada03d1
								
							
						
					
					
						commit
						836d772cd4
					
				| @ -20,7 +20,15 @@ async function up({ context: { queryInterface, logger } }) { | |||||||
|   // Upwards migration script
 |   // Upwards migration script
 | ||||||
|   logger.info('UPGRADE BEGIN: 2.13.5-series-column-unique ') |   logger.info('UPGRADE BEGIN: 2.13.5-series-column-unique ') | ||||||
| 
 | 
 | ||||||
|   // Use the queryInterface to get the series table and find duplicates in the `name` column
 |   // The steps taken to deduplicate the series are as follows:
 | ||||||
|  |   // 1. Find all duplicate series in the `Series` table.
 | ||||||
|  |   // 2. Iterate over the duplicate series and find all book IDs that are associated with the duplicate series in `bookSeries` table.
 | ||||||
|  |   //    2.a For each book ID, check if the ID occurs multiple times for the duplicate series.
 | ||||||
|  |   //    2.b If so, keep only one of the rows that has this bookId and seriesId.
 | ||||||
|  |   // 3. Update `bookSeries` table to point to the most recent series.
 | ||||||
|  |   // 4. Delete the older series.
 | ||||||
|  | 
 | ||||||
|  |   // Use the queryInterface to get the series table and find duplicates in the `name` and `libraryId` column
 | ||||||
|   const [duplicates] = await queryInterface.sequelize.query(` |   const [duplicates] = await queryInterface.sequelize.query(` | ||||||
|     SELECT name, libraryId, MAX(updatedAt) AS latestUpdatedAt, COUNT(name) AS count |     SELECT name, libraryId, MAX(updatedAt) AS latestUpdatedAt, COUNT(name) AS count | ||||||
|     FROM Series |     FROM Series | ||||||
| @ -36,6 +44,70 @@ async function up({ context: { queryInterface, logger } }) { | |||||||
|     // Report the series name that is being deleted
 |     // Report the series name that is being deleted
 | ||||||
|     logger.info(`[2.13.5 migration] Deduplicating series "${duplicate.name}" in library ${duplicate.libraryId}`) |     logger.info(`[2.13.5 migration] Deduplicating series "${duplicate.name}" in library ${duplicate.libraryId}`) | ||||||
| 
 | 
 | ||||||
|  |     // Determine any duplicate book IDs in the `bookSeries` table for the same series
 | ||||||
|  |     const [duplicateBookIds] = await queryInterface.sequelize.query( | ||||||
|  |       ` | ||||||
|  |         SELECT bookId, COUNT(bookId) AS count | ||||||
|  |         FROM BookSeries | ||||||
|  |         WHERE seriesId IN ( | ||||||
|  |           SELECT id | ||||||
|  |           FROM Series | ||||||
|  |           WHERE name = :name AND libraryId = :libraryId | ||||||
|  |         ) | ||||||
|  |         GROUP BY bookId | ||||||
|  |         HAVING COUNT(bookId) > 1 | ||||||
|  |         `,
 | ||||||
|  |       { | ||||||
|  |         replacements: { | ||||||
|  |           name: duplicate.name, | ||||||
|  |           libraryId: duplicate.libraryId | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     // Iterate over the duplicate book IDs if there is at least one and only keep the first row that has this bookId and seriesId
 | ||||||
|  |     for (const { bookId } of duplicateBookIds) { | ||||||
|  |       // Get all rows of `BookSeries` table that have the same `bookId` and `seriesId`. Sort by `sequence` with nulls sorted last
 | ||||||
|  |       const [duplicateBookSeries] = await queryInterface.sequelize.query( | ||||||
|  |         ` | ||||||
|  |             SELECT id | ||||||
|  |             FROM BookSeries | ||||||
|  |             WHERE bookId = :bookId | ||||||
|  |             AND seriesId IN ( | ||||||
|  |               SELECT id | ||||||
|  |               FROM Series | ||||||
|  |               WHERE name = :name AND libraryId = :libraryId | ||||||
|  |             ) | ||||||
|  |             ORDER BY sequence NULLS LAST | ||||||
|  |             `,
 | ||||||
|  |         { | ||||||
|  |           replacements: { | ||||||
|  |             bookId, | ||||||
|  |             name: duplicate.name, | ||||||
|  |             libraryId: duplicate.libraryId | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       ) | ||||||
|  | 
 | ||||||
|  |       // remove the first element from the array
 | ||||||
|  |       duplicateBookSeries.shift() | ||||||
|  | 
 | ||||||
|  |       // Delete the remaining duplicate rows
 | ||||||
|  |       if (duplicateBookSeries.length > 0) { | ||||||
|  |         const [deletedBookSeries] = await queryInterface.sequelize.query( | ||||||
|  |           ` | ||||||
|  |               DELETE FROM BookSeries | ||||||
|  |               WHERE id IN (:ids) | ||||||
|  |               `,
 | ||||||
|  |           { | ||||||
|  |             replacements: { | ||||||
|  |               ids: duplicateBookSeries.map((row) => row.id) | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // Get all the most recent series which matches the `name` and `libraryId`
 |     // Get all the most recent series which matches the `name` and `libraryId`
 | ||||||
|     const [mostRecentSeries] = await queryInterface.sequelize.query( |     const [mostRecentSeries] = await queryInterface.sequelize.query( | ||||||
|       ` |       ` | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user