mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Add more validation and better database emptyness tests
This commit is contained in:
parent
49adc5746a
commit
67ca0a42a7
@ -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 => {
|
||||
|
||||
@ -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.`
|
||||
);
|
||||
|
||||
@ -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}"`);
|
||||
}
|
||||
};
|
||||
|
||||
@ -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(', ')}.`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user