Add more validation and better database emptyness tests

This commit is contained in:
Alexandre Bodin 2019-07-08 15:39:08 +02:00
parent 49adc5746a
commit 67ca0a42a7
5 changed files with 67 additions and 37 deletions

View File

@ -24,7 +24,7 @@ module.exports = async scope => {
);
});
console.log('Creating a project with custom database options');
console.log('Creating a project with custom database options.');
await trackUsage({ event: 'didConnectDatabase', scope });
return createProject(scope, configuration);
};
@ -47,6 +47,17 @@ async function askDbInfosAndTest(scope) {
scope,
configuration,
})
.then(result => {
if (
result &&
result.shouldRetry === true &&
retries < MAX_RETRIES - 1
) {
console.log('Retrying...');
retries++;
return loop();
}
})
.then(
() => fse.remove(scope.tmpPath),
err => {

View File

@ -38,7 +38,7 @@ module.exports = async scope => {
if (files.length > 1) {
await trackError({ scope, error: 'Directory is not empty' });
stopProcess(
`⛔️ You can only create a Strapi app in an empty directory\nMake sure ${chalk.green(
`⛔️ You can only create a Strapi app in an empty directory.\nMake sure ${chalk.green(
scope.rootPath
)} is empty.`
);

View File

@ -25,6 +25,6 @@ module.exports = ({ scope, client }) => {
'strapi-hook-mongoose': scope.strapiVersion,
};
default:
throw new Error(`Invalid client ${client}`);
throw new Error(`Invalid client "${client}"`);
}
};

View File

@ -1,8 +1,9 @@
'use strict';
const chalk = require('chalk');
const stopProcess = require('./stop-process');
const dbArguments = [
const DB_ARGS = [
'dbclient',
'dbhost',
'dbport',
@ -11,20 +12,26 @@ const dbArguments = [
'dbpassword',
];
const VALID_CLIENTS = ['sqlite', 'mysql', 'postgres', 'mongo'];
module.exports = function parseDatabaseArguments({ scope, args }) {
const argKeys = Object.keys(args);
const matchingDbArguments = dbArguments.filter(key => argKeys.includes(key));
const matchingArgs = DB_ARGS.filter(key => argKeys.includes(key));
const missingArgs = DB_ARGS.filter(key => !argKeys.includes(key));
if (matchingDbArguments.length === 0) return;
if (matchingArgs.length === 0) return;
if (
matchingDbArguments.length !== dbArguments.length &&
args.dbclient !== 'sqlite'
) {
if (matchingArgs.length !== DB_ARGS.length && args.dbclient !== 'sqlite') {
return stopProcess(
`⛔️ Some of the database arguments are missing. Required arguments: ${dbArguments.join(
', '
)}.`
`Required database arguments are missing: ${missingArgs.join(', ')}.`
);
}
if (!VALID_CLIENTS.includes(args.dbclient)) {
return stopProcess(
`Invalid client ${chalk.yellow(
args.dbclient
)}. Possible choices: ${VALID_CLIENTS.join(', ')}.`
);
}

View File

@ -3,10 +3,31 @@
// Public node modules
const inquirer = require('inquirer');
const selectQueries = {
postgres: "SELECT tablename FROM pg_tables WHERE schemaname='public'",
mysql: 'SELECT * FROM information_schema.tables',
sqlite: 'select * from sqlite_master',
const hasResults = rows => {
if (!rows || rows.length === 0) return true;
return false;
};
const checkDatabaseIsEmpty = {
postgres: client =>
client
.select('tablename')
.from('pg_tables')
.where('schemaname', 'public')
.then(hasResults),
mysql: (client, { database }) =>
client
.select()
.from('information_schema.tables')
.where('table_schema', database)
.then(hasResults),
sqlite: client =>
client
.select()
.from('sqlite_master')
.then(hasResults),
};
module.exports = async ({ scope, connection }) => {
@ -34,19 +55,14 @@ module.exports = async ({ scope, connection }) => {
await client.raw('select 1+1 as result').catch(destroyClientAndThrow);
return client
.raw(selectQueries[settings.client])
.then(tables => {
if (tables.rows && tables.rows.length === 0) {
return;
}
return checkDatabaseIsEmpty[settings.client](client, settings)
.then(isEmpty => {
if (isEmpty) return;
if (scope.dbforce) return;
if (scope.dbforce) {
return;
}
console.log(
'🤔 It seems that your database is not empty. Be aware that Strapi is going to automatically creates tables & columns, and might update columns which can corrupt data or cause data loss.'
console.log();
console.error(
'It seems that your database is not empty.\nStrapi automatically creates tables and columns which might corrupt the data already present in your database.'
);
return inquirer
@ -54,18 +70,14 @@ module.exports = async ({ scope, connection }) => {
{
type: 'confirm',
name: 'confirm',
message: `Are you sure you want to continue with the ${
settings.database
} database:`,
message: `Are you sure you want to continue with the ${settings.database} database:`,
},
])
.then(({ confirm }) => {
if (!confirm) {
// TODO: cancel somehow
throw new Error('Not confirmed');
}
// send restart flag to retry
if (!confirm) return { shouldRetry: true };
});
})
.then(() => client.destroy())
.then(res => client.destroy().then(() => res))
.catch(destroyClientAndThrow);
};