2021-06-15 19:01:22 +03:00
|
|
|
const debug = require('@tryghost/debug')('test:dbUtils');
|
2021-02-16 19:22:58 +03:00
|
|
|
|
|
|
|
// Utility Packages
|
2021-12-06 15:50:35 +03:00
|
|
|
const fs = require('fs-extra');
|
2021-02-16 19:22:58 +03:00
|
|
|
const Promise = require('bluebird');
|
|
|
|
const KnexMigrator = require('knex-migrator');
|
|
|
|
const knexMigrator = new KnexMigrator();
|
|
|
|
|
|
|
|
// Ghost Internals
|
|
|
|
const config = require('../../core/shared/config');
|
|
|
|
const db = require('../../core/server/data/db');
|
|
|
|
const schema = require('../../core/server/data/schema').tables;
|
|
|
|
const schemaTables = Object.keys(schema);
|
|
|
|
|
2021-02-17 20:36:27 +03:00
|
|
|
// Other Test Utilities
|
|
|
|
const urlServiceUtils = require('./url-service-utils');
|
2021-02-16 19:22:58 +03:00
|
|
|
|
2021-12-06 15:50:35 +03:00
|
|
|
const dbHash = Date.now();
|
|
|
|
|
|
|
|
module.exports.reset = async () => {
|
|
|
|
// Only run this copy in CI until it gets fleshed out
|
|
|
|
if (process.env.CI && config.get('database:client') === 'sqlite3') {
|
|
|
|
const filename = config.get('database:connection:filename');
|
|
|
|
const filenameOrig = `${filename}.${dbHash}-orig`;
|
|
|
|
|
|
|
|
const dbExists = await fs.pathExists(filenameOrig);
|
|
|
|
|
|
|
|
if (dbExists) {
|
|
|
|
await fs.copyFile(filenameOrig, filename);
|
|
|
|
} else {
|
|
|
|
await knexMigrator.reset({force: true});
|
|
|
|
|
|
|
|
// Do a full database initialisation
|
|
|
|
await knexMigrator.init();
|
|
|
|
|
|
|
|
await fs.copyFile(filename, filenameOrig);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
await knexMigrator.reset({force: true});
|
|
|
|
|
|
|
|
// Do a full database initialisation
|
|
|
|
await knexMigrator.init();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-02-17 23:37:49 +03:00
|
|
|
module.exports.initData = async () => {
|
|
|
|
await knexMigrator.init();
|
2021-02-22 17:09:39 +03:00
|
|
|
await urlServiceUtils.reset();
|
|
|
|
await urlServiceUtils.init();
|
2021-02-17 23:37:49 +03:00
|
|
|
await urlServiceUtils.isFinished();
|
2021-02-16 19:22:58 +03:00
|
|
|
};
|
|
|
|
|
2021-02-17 23:37:49 +03:00
|
|
|
module.exports.truncate = async (tableName) => {
|
2021-02-16 19:22:58 +03:00
|
|
|
if (config.get('database:client') === 'sqlite3') {
|
2021-03-01 21:19:24 +03:00
|
|
|
const [foreignKeysEnabled] = await db.knex.raw('PRAGMA foreign_keys;');
|
|
|
|
if (foreignKeysEnabled.foreign_keys) {
|
|
|
|
await db.knex.raw('PRAGMA foreign_keys = OFF;');
|
|
|
|
}
|
2021-02-17 23:37:49 +03:00
|
|
|
await db.knex(tableName).truncate();
|
2021-03-01 21:19:24 +03:00
|
|
|
if (foreignKeysEnabled.foreign_keys) {
|
|
|
|
await db.knex.raw('PRAGMA foreign_keys = ON;');
|
|
|
|
}
|
2021-02-17 23:37:49 +03:00
|
|
|
return;
|
2021-02-16 19:22:58 +03:00
|
|
|
}
|
|
|
|
|
2021-02-17 23:37:49 +03:00
|
|
|
await db.knex.raw('SET FOREIGN_KEY_CHECKS=0;');
|
|
|
|
await db.knex(tableName).truncate();
|
|
|
|
await db.knex.raw('SET FOREIGN_KEY_CHECKS=1;');
|
2021-02-16 19:22:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// we must always try to delete all tables
|
2021-02-17 23:37:49 +03:00
|
|
|
module.exports.clearData = async () => {
|
2021-02-16 19:22:58 +03:00
|
|
|
debug('Database reset');
|
2021-02-17 23:37:49 +03:00
|
|
|
await knexMigrator.reset({force: true});
|
|
|
|
urlServiceUtils.reset();
|
2021-02-16 19:22:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Has to run in a transaction for MySQL, otherwise the foreign key check does not work.
|
|
|
|
* Sqlite3 has no truncate command.
|
|
|
|
*/
|
|
|
|
module.exports.teardown = () => {
|
|
|
|
debug('Database teardown');
|
2021-02-17 20:36:27 +03:00
|
|
|
urlServiceUtils.reset();
|
2021-02-16 19:22:58 +03:00
|
|
|
|
|
|
|
const tables = schemaTables.concat(['migrations']);
|
|
|
|
|
|
|
|
if (config.get('database:client') === 'sqlite3') {
|
|
|
|
return Promise
|
|
|
|
.mapSeries(tables, function createTable(table) {
|
2021-03-01 21:19:24 +03:00
|
|
|
return (async function () {
|
|
|
|
const [foreignKeysEnabled] = await db.knex.raw('PRAGMA foreign_keys;');
|
|
|
|
if (foreignKeysEnabled.foreign_keys) {
|
|
|
|
await db.knex.raw('PRAGMA foreign_keys = OFF;');
|
|
|
|
}
|
|
|
|
await db.knex.raw('DELETE FROM ' + table + ';');
|
|
|
|
if (foreignKeysEnabled.foreign_keys) {
|
|
|
|
await db.knex.raw('PRAGMA foreign_keys = ON;');
|
|
|
|
}
|
|
|
|
})();
|
2021-02-16 19:22:58 +03:00
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
// CASE: table does not exist
|
|
|
|
if (err.errno === 1) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw err;
|
2021-11-18 18:28:46 +03:00
|
|
|
})
|
|
|
|
.finally(() => {
|
|
|
|
debug('Database teardown end');
|
2021-02-16 19:22:58 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return db.knex.transaction(function (trx) {
|
|
|
|
return db.knex.raw('SET FOREIGN_KEY_CHECKS=0;').transacting(trx)
|
|
|
|
.then(function () {
|
|
|
|
return Promise
|
|
|
|
.each(tables, function createTable(table) {
|
|
|
|
return db.knex.raw('TRUNCATE ' + table + ';').transacting(trx);
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.then(function () {
|
|
|
|
return db.knex.raw('SET FOREIGN_KEY_CHECKS=1;').transacting(trx);
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
// CASE: table does not exist
|
|
|
|
if (err.errno === 1146) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|