0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Fixed the add/drop foreign key on sqlite

issue https://github.com/TryGhost/Ghost/pull/12713
ref https://github.com/knex/knex/issues/4155
This commit is contained in:
Thibaut Patel 2021-03-02 15:06:24 +01:00 committed by Thibaut Patel
parent 0843ab6a37
commit 8b7d7ba1f1
2 changed files with 41 additions and 8 deletions

View file

@ -21,7 +21,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
fromColumn: 'member_id',
toTable: 'members',
toColumn: 'id',
cascade: true,
cascadeDelete: true,
transaction: knex
});
@ -37,7 +37,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
fromColumn: 'label_id',
toTable: 'labels',
toColumn: 'id',
cascade: true,
cascadeDelete: true,
transaction: knex
});
@ -53,7 +53,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
fromColumn: 'member_id',
toTable: 'members',
toColumn: 'id',
cascade: true,
cascadeDelete: true,
transaction: knex
});
@ -69,7 +69,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
fromColumn: 'customer_id',
toTable: 'members_stripe_customers',
toColumn: 'id',
cascade: true,
cascadeDelete: true,
transaction: knex
});
});

View file

@ -191,21 +191,38 @@ async function hasForeign({fromTable, fromColumn, toTable, toColumn, transaction
* @param {string} configuration.fromColumn - column of the table to add the foreign key to
* @param {string} configuration.toTableName - name of the table to point the foreign key to
* @param {string} configuration.toColumn - column of the table to point the foreign key to
* @param {Boolean} configuration.cascadeDelete - adds the "on delete cascade" option if true
* @param {Object} configuration.transaction - connection object containing knex reference
* @param {Object} configuration.transaction.knex - knex instance
*/
async function addForeign({fromTable, fromColumn, toTable, toColumn, cascade = false, transaction}) {
async function addForeign({fromTable, fromColumn, toTable, toColumn, cascadeDelete = false, transaction}) {
const hasForeignKey = await hasForeign({fromTable, fromColumn, toTable, toColumn, transaction});
if (!hasForeignKey) {
logging.info(`Adding foreign key for: ${fromColumn} in ${fromTable} to ${toColumn} in ${toTable}`);
return (transaction || db.knex).schema.table(fromTable, function (table) {
if (cascade) {
//disable and re-enable foreign key checks on sqlite because of https://github.com/knex/knex/issues/4155
let foreignKeysEnabled;
if (db.knex.client.config.client === 'sqlite3') {
foreignKeysEnabled = await db.knex.raw('PRAGMA foreign_keys;');
if (foreignKeysEnabled[0].foreign_keys) {
await db.knex.raw('PRAGMA foreign_keys = OFF;');
}
}
await (transaction || db.knex).schema.table(fromTable, function (table) {
if (cascadeDelete) {
table.foreign(fromColumn).references(`${toTable}.${toColumn}`).onDelete('CASCADE');
} else {
table.foreign(fromColumn).references(`${toTable}.${toColumn}`);
}
});
if (db.knex.client.config.client === 'sqlite3') {
if (foreignKeysEnabled[0].foreign_keys) {
await db.knex.raw('PRAGMA foreign_keys = ON;');
}
}
} else {
logging.warn(`Skipped adding foreign key for ${fromColumn} in ${fromTable} to ${toColumn} in ${toTable} - foreign key already exists`);
}
@ -227,9 +244,25 @@ async function dropForeign({fromTable, fromColumn, toTable, toColumn, transactio
if (hasForeignKey) {
logging.info(`Dropping foreign key for: ${fromColumn} in ${fromTable} to ${toColumn} in ${toTable}`);
return (transaction || db.knex).schema.table(fromTable, function (table) {
//disable and re-enable foreign key checks on sqlite because of https://github.com/knex/knex/issues/4155
let foreignKeysEnabled;
if (db.knex.client.config.client === 'sqlite3') {
foreignKeysEnabled = await db.knex.raw('PRAGMA foreign_keys;');
if (foreignKeysEnabled[0].foreign_keys) {
await db.knex.raw('PRAGMA foreign_keys = OFF;');
}
}
await (transaction || db.knex).schema.table(fromTable, function (table) {
table.dropForeign(fromColumn);
});
if (db.knex.client.config.client === 'sqlite3') {
if (foreignKeysEnabled[0].foreign_keys) {
await db.knex.raw('PRAGMA foreign_keys = ON;');
}
}
} else {
logging.warn(`Skipped dropping foreign key for ${fromColumn} in ${fromTable} to ${toColumn} in ${toTable} - foreign key does not exist`);
}