@trap_stevo/liveql
Version:
Supercharge your database workflow with a visually clean, ultra-intuitive SQL layer. Chain elegant queries, trigger instant real-time events, and manage schemas effortlessly — all without ORM overhead while blending raw SQL power with modern developer erg
75 lines (74 loc) • 3.65 kB
JavaScript
;
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const path = require("path");
const fs = require("fs");
var _client = /*#__PURE__*/new WeakMap();
var _MigrationEngine_brand = /*#__PURE__*/new WeakSet();
class MigrationEngine {
constructor(client) {
_classPrivateMethodInitSpec(this, _MigrationEngine_brand);
_classPrivateFieldInitSpec(this, _client, void 0);
_classPrivateFieldSet(_client, this, client);
}
async run({
up = [],
down = []
}) {
for (const migration of up) {
await _classPrivateFieldGet(_client, this).query(migration);
}
for (const migration of down) {
await _classPrivateFieldGet(_client, this).query(migration);
}
}
async runFromFolder(migrationsDir, direction = "up") {
await _assertClassBrand(_MigrationEngine_brand, this, _ensureMigrationsTable).call(this);
const allFiles = fs.readdirSync(migrationsDir).filter(f => f.endsWith(`.${direction}.sql`)).sort();
const applied = await _assertClassBrand(_MigrationEngine_brand, this, _getAppliedMigrations).call(this);
if (direction === "up") {
for (const file of allFiles) {
const migrationName = path.basename(file);
if (applied.includes(migrationName)) continue;
const sql = fs.readFileSync(path.join(migrationsDir, file), "utf8");
console.log(`Applying migration: ${migrationName}`);
await _classPrivateFieldGet(_client, this).query(sql);
await _assertClassBrand(_MigrationEngine_brand, this, _recordMigration).call(this, migrationName);
}
} else if (direction === "down") {
const appliedReversed = applied.slice().reverse();
for (const file of allFiles.reverse()) {
const migrationName = path.basename(file);
if (!appliedReversed.includes(migrationName)) continue;
const sql = fs.readFileSync(path.join(migrationsDir, file), "utf8");
console.log(`Reverting migration: ${migrationName}`);
await _classPrivateFieldGet(_client, this).query(sql);
await _assertClassBrand(_MigrationEngine_brand, this, _removeMigrationRecord).call(this, migrationName);
}
}
}
}
async function _ensureMigrationsTable() {
await _classPrivateFieldGet(_client, this).query(`
CREATE TABLE IF NOT EXISTS migrations (
id SERIAL PRIMARY KEY,
name TEXT UNIQUE NOT NULL,
run_on TIMESTAMP DEFAULT NOW()
);
`);
}
async function _getAppliedMigrations() {
const res = await _classPrivateFieldGet(_client, this).query(`SELECT name FROM migrations ORDER BY id ASC;`);
return res.rows.map(r => r.name);
}
async function _recordMigration(name) {
await _classPrivateFieldGet(_client, this).query(`INSERT INTO migrations (name) VALUES ($1);`, [name]);
}
async function _removeMigrationRecord(name) {
await _classPrivateFieldGet(_client, this).query(`DELETE FROM migrations WHERE name = $1;`, [name]);
}
module.exports = MigrationEngine;