audiobookshelf/server/migrations/v2.25.2-add-book-ratings.js
2025-07-01 13:55:33 +02:00

174 lines
5.7 KiB
JavaScript

const { DataTypes } = require('sequelize')
const migrationName = 'v2.25.2-add-book-ratings'
const loggerPrefix = `[${migrationName} migration]`
module.exports = {
up: async ({ context: { queryInterface, logger } }) => {
logger.info(`${loggerPrefix} UPGRADE BEGIN: ${migrationName}`)
const transaction = await queryInterface.sequelize.transaction()
try {
const booksTable = await queryInterface.describeTable('books')
logger.info(`${loggerPrefix} adding columns to books table`)
if (!booksTable.providerRating) {
await queryInterface.addColumn(
'books',
'providerRating',
{
type: DataTypes.FLOAT
},
{ transaction }
)
}
if (!booksTable.provider) {
await queryInterface.addColumn(
'books',
'provider',
{
type: DataTypes.STRING
},
{ transaction }
)
}
if (!booksTable.providerId) {
await queryInterface.addColumn(
'books',
'providerId',
{
type: DataTypes.STRING
},
{ transaction }
)
}
logger.info(`${loggerPrefix} added columns to books table`)
const tables = await queryInterface.showAllTables()
if (!tables.includes('userBookRatings')) {
logger.info(`${loggerPrefix} creating userBookRatings table`)
await queryInterface.createTable(
'userBookRatings',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
userId: {
type: DataTypes.STRING,
allowNull: false,
references: { model: 'users', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
bookId: {
type: DataTypes.STRING,
allowNull: false,
references: { model: 'books', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
rating: {
type: DataTypes.FLOAT,
allowNull: false
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
},
{ transaction }
)
await queryInterface.addConstraint('userBookRatings', {
fields: ['userId', 'bookId'],
type: 'unique',
name: 'user_book_ratings_unique_constraint',
transaction
})
logger.info(`${loggerPrefix} created userBookRatings table`)
}
if (!tables.includes('userBookExplicitRatings')) {
logger.info(`${loggerPrefix} creating userBookExplicitRatings table`)
await queryInterface.createTable(
'userBookExplicitRatings',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
userId: {
type: DataTypes.STRING,
allowNull: false,
references: { model: 'users', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
bookId: {
type: DataTypes.STRING,
allowNull: false,
references: { model: 'books', key: 'id' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE'
},
rating: {
type: DataTypes.FLOAT,
allowNull: false
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
},
{ transaction }
)
await queryInterface.addConstraint('userBookExplicitRatings', {
fields: ['userId', 'bookId'],
type: 'unique',
name: 'user_book_explicit_ratings_unique_constraint',
transaction
})
logger.info(`${loggerPrefix} created userBookExplicitRatings table`)
}
await transaction.commit()
logger.info(`${loggerPrefix} UPGRADE END: ${migrationName}`)
} catch (err) {
await transaction.rollback()
logger.error(`${loggerPrefix} UPGRADE FAILED: ${migrationName}`, { error: err })
throw err
}
},
down: async ({ context: { queryInterface, logger } }) => {
logger.info(`${loggerPrefix} DOWNGRADE BEGIN: ${migrationName}`)
const transaction = await queryInterface.sequelize.transaction()
try {
logger.info(`${loggerPrefix} removing columns from books table`)
await queryInterface.removeColumn('books', 'providerRating', { transaction })
await queryInterface.removeColumn('books', 'provider', { transaction })
await queryInterface.removeColumn('books', 'providerId', { transaction })
logger.info(`${loggerPrefix} removed columns from books table`)
logger.info(`${loggerPrefix} dropping userBookRatings table`)
await queryInterface.dropTable('userBookRatings', { transaction })
logger.info(`${loggerPrefix} dropped userBookRatings table`)
logger.info(`${loggerPrefix} dropping userBookExplicitRatings table`)
await queryInterface.dropTable('userBookExplicitRatings', { transaction })
logger.info(`${loggerPrefix} dropped userBookExplicitRatings table`)
await transaction.commit()
logger.info(`${loggerPrefix} DOWNGRADE END: ${migrationName}`)
} catch (err) {
await transaction.rollback()
logger.error(`${loggerPrefix} DOWNGRADE FAILED: ${migrationName}`, { error: err })
throw err
}
}
}