Skip to content

Instantly share code, notes, and snippets.

@jtwebman
Created November 1, 2020 22:17
Show Gist options
  • Save jtwebman/9a4987f41813812609ad69e9a3337137 to your computer and use it in GitHub Desktop.
Save jtwebman/9a4987f41813812609ad69e9a3337137 to your computer and use it in GitHub Desktop.
/*
This is a simple script that reads files in the patches folder under the folder this file is in and runs then
getDBConnection = just pg-promise gets a pg-promise pool db object connected to the DB.
*/
'use strict';
const config = require('config');
const fs = require('fs');
const path = require('path');
const { QueryFile } = require('pg-promise');
const getDBConnection = require('../server/data/get-db-connection');
const db = getDBConnection(config);
const patchFolder = path.join(__dirname, 'patches');
const migrationTableExistsSql = `SELECT EXISTS (
SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'migrations'
)`;
const createMigrationTableSql = `
CREATE TABLE IF NOT EXISTS migrations (
filename TEXT PRIMARY KEY NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()
)`;
const getCurrentMigrationsSql = 'SELECT filename FROM migrations';
const insertPatchRanSql = `INSERT INTO migrations (filename) VALUES ($1)`;
async function migrationTableExists(context) {
const results = await context.db.one(migrationTableExistsSql);
context.migrationTableExists = results.exists;
return context;
}
async function createMigrationTableIfNeeded(context) {
if (context.migrationTableExists) return context;
await context.db.query(createMigrationTableSql);
return context;
}
async function getCurrentAppliedPatches(context) {
const results = await context.db.query(getCurrentMigrationsSql);
context.currentAppliedPatches = results.map((f) => f.filename);
return context;
}
async function getPatchesToRun(context) {
context.patchesToRun = fs
.readdirSync(patchFolder)
.filter((name) => name.charAt(0) !== '.' && !context.currentAppliedPatches.includes(name))
.sort();
return context;
}
async function runPatches(context) {
context.results = [];
for (let i = 0, len = context.patchesToRun.length; i < len; i++) {
const filename = context.patchesToRun[i];
console.log(`Running ${filename}.`);
const sql = new QueryFile(path.join(patchFolder, filename));
const results = await context.db.none(sql);
await context.db.none(insertPatchRanSql, filename);
context.results.push(results);
}
return context;
}
migrationTableExists({ db })
.then(createMigrationTableIfNeeded)
.then(getCurrentAppliedPatches)
.then(getPatchesToRun)
.then(runPatches)
.then((context) => context.db.$pool.end());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment