From ce5f55e43fbef90b1c3da204757b936d12d9d6b8 Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Tue, 26 Apr 2022 11:22:07 +0200 Subject: [PATCH] Fixed created_at newsletter migration (#14568) refs https://github.com/TryGhost/Team/issues/1551 - Updated existing migration to insert a nullable created_at column - Added a migration to update all the created_at values to now - Added a migration to drop nullable - Also includes new helper methods to set and drop nullable --- core/server/data/migrations/utils.js | 40 +++++++++++++++++++ ...-04-13-12-00-add-created-at-newsletters.js | 2 +- ...04-13-12-02-fill-created-at-newsletters.js | 19 +++++++++ ...03-drop-nullable-created-at-newsletters.js | 3 ++ core/server/data/schema/commands.js | 14 +++++++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 core/server/data/migrations/versions/4.46/2022-04-13-12-02-fill-created-at-newsletters.js create mode 100644 core/server/data/migrations/versions/4.46/2022-04-13-12-03-drop-nullable-created-at-newsletters.js diff --git a/core/server/data/migrations/utils.js b/core/server/data/migrations/utils.js index 6cda3a354e..db52461720 100644 --- a/core/server/data/migrations/utils.js +++ b/core/server/data/migrations/utils.js @@ -440,6 +440,44 @@ function createDropColumnMigration(table, column, columnDefinition) { ); } +/** + * @param {string} table + * @param {string} column + * + * @returns {Migration} + */ +function createSetNullableMigration(table, column) { + return createNonTransactionalMigration( + async function up(knex) { + logging.info(`Setting nullable: ${table}.${column}`); + await commands.setNullable(table, column, knex); + }, + async function down(knex) { + logging.info(`Dropping nullable: ${table}.${column}`); + await commands.dropNullable(table, column, knex); + } + ); +} + +/** + * @param {string} table + * @param {string} column + * + * @returns {Migration} + */ +function createDropNullableMigration(table, column) { + return createNonTransactionalMigration( + async function up(knex) { + logging.info(`Dropping nullable: ${table}.${column}`); + await commands.dropNullable(table, column, knex); + }, + async function down(knex) { + logging.info(`Setting nullable: ${table}.${column}`); + await commands.setNullable(table, column, knex); + } + ); +} + /** * Creates a migration which will insert a new setting in settings table * @param {object} settingSpec - setting key, value, group and type @@ -505,6 +543,8 @@ module.exports = { combineNonTransactionalMigrations, createAddColumnMigration, createDropColumnMigration, + createSetNullableMigration, + createDropNullableMigration, meta: { MIGRATION_USER } diff --git a/core/server/data/migrations/versions/4.46/2022-04-13-12-00-add-created-at-newsletters.js b/core/server/data/migrations/versions/4.46/2022-04-13-12-00-add-created-at-newsletters.js index 4f26c451b1..543e2dddcc 100644 --- a/core/server/data/migrations/versions/4.46/2022-04-13-12-00-add-created-at-newsletters.js +++ b/core/server/data/migrations/versions/4.46/2022-04-13-12-00-add-created-at-newsletters.js @@ -2,5 +2,5 @@ const {createAddColumnMigration} = require('../../utils'); module.exports = createAddColumnMigration('newsletters', 'created_at', { type: 'dateTime', - nullable: false + nullable: true }); diff --git a/core/server/data/migrations/versions/4.46/2022-04-13-12-02-fill-created-at-newsletters.js b/core/server/data/migrations/versions/4.46/2022-04-13-12-02-fill-created-at-newsletters.js new file mode 100644 index 0000000000..ddc9885682 --- /dev/null +++ b/core/server/data/migrations/versions/4.46/2022-04-13-12-02-fill-created-at-newsletters.js @@ -0,0 +1,19 @@ +const logging = require('@tryghost/logging'); + +const {createTransactionalMigration} = require('../../utils'); + +module.exports = createTransactionalMigration( + async function up(knex) { + logging.info('Setting missing created_at values for existing newsletters'); + + const now = knex.raw('CURRENT_TIMESTAMP'); + const updatedRows = await knex('newsletters') + .where('created_at', null) + .update('created_at', now); + + logging.info(`Updated ${updatedRows} newsletters with created_at = now`); + }, + async function down() { + // Not required: we would lose information here. + } +); diff --git a/core/server/data/migrations/versions/4.46/2022-04-13-12-03-drop-nullable-created-at-newsletters.js b/core/server/data/migrations/versions/4.46/2022-04-13-12-03-drop-nullable-created-at-newsletters.js new file mode 100644 index 0000000000..9de51857cb --- /dev/null +++ b/core/server/data/migrations/versions/4.46/2022-04-13-12-03-drop-nullable-created-at-newsletters.js @@ -0,0 +1,3 @@ +const {createDropNullableMigration} = require('../../utils'); + +module.exports = createDropNullableMigration('newsletters', 'created_at'); diff --git a/core/server/data/schema/commands.js b/core/server/data/schema/commands.js index 82b676b318..310baded22 100644 --- a/core/server/data/schema/commands.js +++ b/core/server/data/schema/commands.js @@ -59,6 +59,18 @@ function addTableColumn(tableName, table, columnName, columnSpec = schema[tableN } } +function setNullable(tableName, column, transaction = db.knex) { + return transaction.schema.table(tableName, function (table) { + table.setNullable(column); + }); +} + +function dropNullable(tableName, column, transaction = db.knex) { + return transaction.schema.table(tableName, function (table) { + table.dropNullable(column); + }); +} + function addColumn(tableName, column, transaction = db.knex, columnSpec) { return transaction.schema.table(tableName, function (table) { addTableColumn(tableName, table, column, columnSpec); @@ -412,6 +424,8 @@ module.exports = { dropForeign: dropForeign, addColumn: addColumn, dropColumn: dropColumn, + setNullable: setNullable, + dropNullable: dropNullable, getColumns: getColumns, createColumnMigration, // NOTE: below are exposed for testing purposes only