Add database install / migrate commands

This commit is contained in:
rijkvanzanten
2020-09-17 17:25:56 -04:00
parent 9ffc056bd3
commit a409b9cb9a
8 changed files with 137 additions and 8 deletions

View File

@@ -3,6 +3,12 @@ import run from '../../../database/seeds/run';
export default async function start() {
const database = require('../../../database/index').default as Knex;
await run(database);
database.destroy();
try {
await run(database);
} catch (err) {
console.log(err);
process.exit(1);
} finally {
database.destroy();
}
}

View File

@@ -0,0 +1,14 @@
import run from '../../../database/migrations/run';
export default async function migrate(direction: 'latest' | 'up' | 'down') {
const database = require('../../../database').default;
try {
await run(database, direction);
} catch(err) {
console.log(err);
process.exit(1);
} finally {
database.destroy();
}
}

View File

@@ -1,10 +1,9 @@
import logger from '../../logger';
export default async function start() {
const { default: env, validateEnv } = require('../../env');
const { default: env } = require('../../env');
const { validateDBConnection } = require('../../database');
validateEnv();
await validateDBConnection();
const app = require('../../app').default;

View File

@@ -7,13 +7,19 @@ const pkg = require('../../package.json');
import start from './commands/start';
import init from './commands/init';
import dbInstall from './commands/database/install';
program.version(pkg.version, '-v, --version');
import dbMigrate from './commands/database/migrate';
program.name('directus').usage('[command] [options]');
program.version(pkg.version, '-v, --version');
program.command('start').description('Start the Directus API').action(start);
program.command('init').description('Create a new Directus Project').action(init);
program.command('database install').description('Install the database').action(dbInstall);
program.parseAsync(process.argv);
const dbCommand = program.command('database');
dbCommand.command('install').description('Install the database').action(dbInstall);
dbCommand.command('migrate:latest').description('Upgrade the database').action(() => dbMigrate('latest'));
dbCommand.command('migrate:up').description('Upgrade the database').action(() => dbMigrate('up'));
dbCommand.command('migrate:down').description('Downgrade the database').action(() => dbMigrate('down'));
program.parse(process.argv);

View File

@@ -0,0 +1,84 @@
import fse from 'fs-extra';
import Knex from 'knex';
import path from 'path';
import formatTitle from '@directus/format-title';
type Migration = {
version: string;
name: string;
timestamp: Date;
}
export default async function run(database: Knex, direction: 'up' | 'down' | 'latest') {
let migrationFiles = await fse.readdir(__dirname);
migrationFiles = migrationFiles.filter((file: string) => file !== 'run.ts');
const completedMigrations = await database.select<Migration[]>('*').from('directus_migrations').orderBy('version');
const migrations = migrationFiles.map((migrationFile) => {
const version = migrationFile.split('-')[0];
const name = formatTitle(migrationFile.split('-').slice(1).join('_').split('.')[0]);
const completed = !!completedMigrations.find((migration) => migration.version === version);
return {
file: migrationFile,
version,
name,
completed
};
});
if (direction === 'up') await up();
if (direction === 'down') await down();
if (direction === 'latest') await latest();
async function up() {
const currentVersion = completedMigrations[completedMigrations.length - 1];
let nextVersion: any;
if (!currentVersion) {
nextVersion = migrations[0];
} else {
nextVersion = migrations.find((migration) => {
return migration.version > currentVersion.version && migration.completed === false;
});
}
if (!nextVersion) {
throw Error('Nothing to upgrade');
}
const { up } = require(path.join(__dirname, nextVersion.file));
await up(database);
await database.insert({ version: nextVersion.version, name: nextVersion.name }).into('directus_migrations');
}
async function down() {
const currentVersion = completedMigrations[completedMigrations.length - 1];
if (!currentVersion) {
throw Error('Nothing to downgrade');
}
const migration = migrations.find((migration) => migration.version === currentVersion.version);
if (!migration) {
throw new Error('Couldnt find migration');
}
const { down } = require(path.join(__dirname, migration.file));
await down(database);
await database('directus_migrations').delete().where({ version: migration.version });
}
async function latest() {
for (const migration of migrations) {
if (migration.completed === false) {
const { up } = require(path.join(__dirname, migration.file));
await up(database);
await database.insert({ version: migration.version, name: migration.name }).into('directus_migrations');
}
}
}
}

View File

@@ -0,0 +1,14 @@
table: directus_migrations
columns:
version:
type: string
primary: true
nullable: false
name:
type: string
length: 255
nullable: false
timestamp:
type: timestamp
default: $now

View File

@@ -53,6 +53,12 @@ type FieldSeed = {
}
export default async function runSeed(database: Knex) {
const exists = await database.schema.hasTable('directus_collections');
if (exists) {
throw new Error('Database is already installed');
}
await createTables(database);
await insertRows(database);
await insertFields(database);