Skip to content

Commit

Permalink
feat: allow db:drop with force for PostgreSQL > v13
Browse files Browse the repository at this point in the history
  • Loading branch information
john committed Apr 17, 2024
1 parent 36ad390 commit 4defed1
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 14 deletions.
56 changes: 42 additions & 14 deletions src/commands/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ exports.builder = (yargs) =>
.option('template', {
describe: 'Pass template option to dialect, PostgreSQL only',
type: 'string',
})
.option('force', {
describe:
'Pass force option to dialect with db:drop, PostgreSQL > v13 only',
type: 'boolean',
}).argv;

exports.handler = async function (args) {
Expand All @@ -45,18 +50,16 @@ exports.handler = async function (args) {
'encoding',
'ctype',
'template',
'force',
]);

const queryInterface = sequelize.getQueryInterface();
const queryGenerator =
queryInterface.queryGenerator || queryInterface.QueryGenerator;

const query = getCreateDatabaseQuery(sequelize, config, options);
const createQuery = getCreateDatabaseQuery(sequelize, config, options);
const dropQuery = getDropDatabaseQuery(sequelize, config, options);

switch (command) {
case 'db:create':
await sequelize
.query(query, {
.query(createQuery, {
type: sequelize.QueryTypes.RAW,
})
.catch((e) => helpers.view.error(e));
Expand All @@ -66,14 +69,9 @@ exports.handler = async function (args) {
break;
case 'db:drop':
await sequelize
.query(
`DROP DATABASE IF EXISTS ${queryGenerator.quoteIdentifier(
config.database
)}`,
{
type: sequelize.QueryTypes.RAW,
}
)
.query(dropQuery, {
type: sequelize.QueryTypes.RAW,
})
.catch((e) => helpers.view.error(e));

helpers.view.log('Database', clc.blueBright(config.database), 'dropped.');
Expand Down Expand Up @@ -145,6 +143,36 @@ function getCreateDatabaseQuery(sequelize, config, options) {
}
}

function getDropDatabaseQuery(sequelize, config, options) {
const queryInterface = sequelize.getQueryInterface();
const queryGenerator =
queryInterface.queryGenerator || queryInterface.QueryGenerator;

switch (config.dialect) {
// Adds the force option for WITH(FORCE) to drop a database that has connected users, fallback to default drop if version lower
// for postgres v13 and above see manual https://www.postgresql.org/docs/current/sql-dropdatabase.html
case 'postgres':
if (options.force) {
helpers.view.log(
clc.redBright(
`WARNING :: Dropping database with force for v13 and above only (this will drop regardless of connected users) `
)
);
return `DROP DATABASE IF EXISTS ${queryGenerator.quoteIdentifier(
config.database
)} WITH (FORCE)`;
} else
return `DROP DATABASE IF EXISTS ${queryGenerator.quoteIdentifier(
config.database
)}`;

default:
return `DROP DATABASE IF EXISTS ${queryGenerator.quoteIdentifier(
config.database
)}`;
}
}

function getDatabaseLessSequelize() {
let config = null;

Expand Down
24 changes: 24 additions & 0 deletions test/db/db-drop.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@ describe(Support.getTestDialectTeaser('db:drop'), () => {
}
);
});
it('correctly drops database with force', function (done) {
const databaseName = `my_test_db_${_.random(10000, 99999)}`;
prepare(
'db:drop --force',
() => {
this.sequelize
.query(
`SELECT 1 as exists FROM pg_database WHERE datname = '${databaseName}';`,
{
type: this.sequelize.QueryTypes.SELECT,
}
)
.then((result) => {
expect(result).to.be.empty;
done();
});
},
{
config: {
database: databaseName,
},
}
);
});
}

if (Support.dialectIsMySQL()) {
Expand Down

0 comments on commit 4defed1

Please sign in to comment.