UNPKG

test-easy-psql

Version:

Welcome to the test-easy-psql documentation! test-easy-psql is a simple intermediary for querying data in PostgreSQL databases. Whether you're a beginner or an experienced developer, this documentation will help you get started with test-easy-psql and lev

124 lines (123 loc) 3.53 kB
"use strict"; const fs = require("fs"); const path = require("path"); const prompt = require("prompt-sync")({ sigint: true }); const DBManager = require("./DBManager"); const { Query } = require("pg"); const { v4 } = require("uuid"); class Migrations { static migrationsFolder = "migrations"; static migrationsFolderExists() { return fs.existsSync(Migrations.resolvePath(Migrations.migrationsFolder)); } static resolvePath(...entries) { return path.join(process.cwd(), ...entries); } static createMigrationsFolder() { if (Migrations.migrationsFolderExists()) { return; } fs.mkdirSync(Migrations.resolvePath(Migrations.migrationsFolder)); } static setMigrationsFolder(name) { Migrations.migrationsFolder = name; } static async runNewMigration(cb) { const { up, down, args = [] } = await cb(); const filename = `${new Date().getTime()}__migration.json`; fs.writeFileSync(Migrations.resolvePath(Migrations.migrationsFolder, filename), JSON.stringify({ filename, up, down, timestamp: new Date().toUTCString(), id: v4(), applied: true, args })); } static readMigrationFiles() { const files = []; fs.readdirSync(Migrations.resolvePath(Migrations.migrationsFolder)).forEach(file => { files.push(Migrations.resolvePath(Migrations.migrationsFolder, file)); }); return files.map(file => JSON.parse(fs.readFileSync(file, { encoding: "utf8" }).toString())); } static async applyMigrations() { Migrations.createMigrationsFolder(); const notApplied = Migrations.readMigrationFiles().filter(x => !x.applied); for (const migration of notApplied) { await DBManager.exec(migration.up, migration.args); fs.writeFileSync(Migrations.resolvePath(Migrations.migrationsFolder, migration.filename), JSON.stringify({ ...migration, applied: true })); } } static async rollbackToMigration(id) { const files = Migrations.readMigrationFiles(); const migrationIndex = files.findIndex(file => file.id === id); if (migrationIndex === -1) { console.log(`No such migration: ${id}`); return; } const rollbackItems = files.slice(migrationIndex); for (let i = rollbackItems.length - 1; i >= 0; i--) { await DBManager.exec(rollbackItems[i].down); fs.writeFileSync(Migrations.resolvePath(Migrations.migrationsFolder, rollbackItems[i].filename), JSON.stringify({ ...rollbackItems[i], applied: false })); } } static async createMigration({ up, down }) { await Migrations.runNewMigration(async () => { new Query(up); new Query(down); await DBManager.exec(up); return { up, down }; }); } static async bashMigrationInput() { const up = prompt("Enter New SQL Statement: "); const down = prompt("Enter The opposite SQL Action: "); if (!up || !down) { console.log("please provide up and down properties!"); process.exit(1); } await Migrations.runNewMigration(async () => { new Query(up); new Query(down); await DBManager.exec(up); return { up, down }; }); console.log("completed!!"); const continueMig = prompt("Press 1 to continue"); if (continueMig.trim() !== "1") { console.log("BYE!"); process.exit(0); } await Migrations.bashMigrationInput(); } } module.exports = Migrations;