UNPKG

node-red-contrib-chatbot

Version:

REDBot a Chat bot for a full featured chat bot for Telegram, Facebook Messenger and Slack. Almost no coding skills required

83 lines (79 loc) 3.71 kB
/* eslint-disable no-console */ const Sequelize = require('sequelize'); const fs = require('fs'); const lcd = require('../lcd'); const { tableExists, isEmptyDatabase } = require('./database'); const getMigrations = (migrationsDir) => { // eslint-disable-next-line security/detect-non-literal-fs-filename return fs.readdirSync(migrationsDir) .map(migration => parseInt(migration.replace('.sql', ''), 10)) .filter(migration => !isNaN(migration)) .sort((a, b) => a < b ? -1 : 1); }; module.exports = { getMigrations, migrate: async (sequelize, migrationsDir) => { let createdVersionsTable = false; let rowCurrentVersion; // define database version, create if not exists const Version = sequelize.define('version', { version: Sequelize.INTEGER }); // checks if (await isEmptyDatabase(sequelize)) { // if table is empty, then is going to be initialized, no need to apply migrations // they will fail, it will brand new console.log(lcd.timestamp() + 'Database is empty, skipping migrations'); return; } else if (!(await tableExists('versions', sequelize))) { // if versions table is not present, then create and initialize to 0 // means it's an old database, it will receive all migrations await Version.sync({ force: true }); createdVersionsTable = true; rowCurrentVersion = await Version.create({ version: 0 }); } else { // if version is present, then get the latest version, if empty then init to zero rowCurrentVersion = await Version.findOne(); if (rowCurrentVersion == null) { rowCurrentVersion = await Version.create({ version: 0 }); } } // get all migrations, cleanup and sort by most recent const migrations = getMigrations(migrationsDir); console.log(lcd.timestamp() + 'Executing Queue DB migrations'); if (createdVersionsTable) { console.log(lcd.timestamp() + ' ' + lcd.grey('Initialized "versions" table')); } console.log(lcd.timestamp() + ' ' + lcd.grey(`Searching migrations in ${migrationsDir}}`)); console.log(lcd.timestamp() + ' ' + lcd.grey(`Found ${migrations.length} migrations`)); console.log(lcd.timestamp() + ' ' + lcd.grey(`Current DB version: ${rowCurrentVersion != null ? rowCurrentVersion.version : 1}`)); // only install migrations with version > current version let executedMigrations = 0; for(let idx = 0; idx < migrations.length; idx++) { if (migrations[idx] > rowCurrentVersion.version) { console.log(lcd.timestamp() + ' ' + lcd.grey('Executing migration to version: ') + lcd.green(migrations[idx])); // eslint-disable-next-line security/detect-non-literal-fs-filename const query = fs.readFileSync(`${migrationsDir}/${migrations[idx]}.sql`, 'UTF8'); try { const queries = query.split('\n'); for (let i = 0; i < queries.length; i++) { console.log(lcd.timestamp() + ' ' + lcd.green(' - ') + lcd.grey(queries[i])); await sequelize.query(queries[i]); } // update current version rowCurrentVersion.version = migrations[idx]; await rowCurrentVersion.save(); executedMigrations++; } catch(e) { console.log(lcd.timestamp() + ' ' + lcd.orange(`Error executing migration #${migrations[idx]}: ${query}`)); console.log(e); } } } if (executedMigrations !== 0) { console.log(lcd.timestamp() + ' ' + lcd.grey('Migration completed (') + lcd.green(executedMigrations) + lcd.grey(')')); } else { console.log(lcd.timestamp() + ' ' + lcd.grey('No migrations applied. Done.')); } } };