Setup for postgres database & schema for blogposts.

This commit is contained in:
2021-01-03 18:16:52 +01:00
parent 5b9d9aeca8
commit 3aef0862ec
8 changed files with 374 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
const path = require("path");
const fs = require("fs");
const fsPromises = require("fs/promises");
if (global.__base == undefined)
global.__base = path.join(__dirname, "../..");
const db = require("../index.js");
class SeedStep {
constructor(filepath) {
this.filepath = filepath;
this.filename = filepath.split("/").pop();
};
readData() {
this.data = JSON.parse(fs.readFileSync(this.filepath, 'utf-8'));
};
get isApplied() {
const query = `SELECT * FROM seed WHERE filename = $1`;
return db.query(query, [ this.filename ])
.then(resp => resp == 1 ? true : false)
}
commitStepToDb() {
const query = `INSERT INTO seed (filename) VALUES ($1)`;
return db.query(query, [ this.filename ]);
}
async applySeedData() {
if (await this.isApplied) {
console.log(`⚠️ Step: ${this.filename}, already applied.`);
return
}
console.log(`Seeding ${this.filename}:`);
const seedSteps = this.data.map(data => {
const { model, pk, fields } = data;
const columns = Object.keys(fields);
const values = Object.values(fields);
const parameterKeys = Array.from({length: values.length}, (v, k) => `$${k + 1}`);
const query = `INSERT INTO ${ model }
(${ columns.join(',') })
VALUES
(${ parameterKeys.join(',') })`;
return db.query(query, values)
});
const table = this.data[0].model;
return Promise.all(seedSteps)
.then(objects => console.log(`🌱 ${objects.length} object(s) applied to ${ table }.`))
.then(_ => this.commitStepToDb());
}
}
/**
* UTILS
*/
const readSeedFiles = () => {
const seedFolder = path.join(__base, "database/seeds/");
console.log(`Reading seeds from folder: ${seedFolder}\n`);
return fsPromises.readdir(seedFolder)
.then(files => files.map(filePath => {
const seedStep = new SeedStep(path.join(seedFolder, filePath));
seedStep.readData();
return seedStep;
}))
.catch(console.log)
};
const runAllSteps = (seedSteps) => {
return seedSteps.reduce(async (prevPromise, step) => {
await prevPromise;
return step.applySeedData();
}, Promise.resolve());
return Promise.all(promises);
}
/**
* Runner
*/
readSeedFiles()
.then(seedSteps => runAllSteps(seedSteps))
.finally(_ => process.exit(0));

View File

@@ -0,0 +1,69 @@
const path = require("path");
const fs = require("fs");
const fsPromises = require("fs/promises");
if (global.__base == undefined)
global.__base = path.join(__dirname, "../..");
const db = require("../index.js");
const posts = `posts.sql`;
const seed = `seed.sql`;
// TODO this is not used
const schemas = [
posts,
seed
];
const handleExit = (error=undefined) => {
if (error != undefined) {
console.log(`🚫 Exited with error: ${error}`);
process.exit(1);
}
console.log("✅ Exited setup successfully!");
process.exit(0);
};
const readSchemaFiles = () => {
const schemaFolder = path.join(__base, "database/schemas");
console.log("Reading schemas from folder:", schemaFolder);
return fsPromises.readdir(schemaFolder)
.then(files => files.map(filename => {
const filePath = path.join(schemaFolder, filename);
return fs.readFileSync(filePath, 'utf-8');
}))
}
const applyAll = schemas => {
schemas = schemas.reverse();
return schemas.reduce(async (prevPromise, schema) => {
const tableName = schema.split("CREATE TABLE IF NOT EXISTS ").pop().split(" (")[0];
console.log(`✏️ Applying schema: ${tableName}`);
await prevPromise;
return db.query(schema);
}, Promise.resolve());
}
/**
* Runner
*/
readSchemaFiles()
.then(schemas => applyAll(schemas))
.catch(err => handleExit(err))
.then(_ => process.exit(0))
// db.connect()
// .then(client => setup(client, schemas))
module.exports = db;

View File

@@ -0,0 +1,50 @@
const fs = require("fs");
const path = require("path");
if (global.__base == undefined)
global.__base = path.join(__dirname, "../..");
const db = require("../index.js");
const allTableNames = () => {
const sql = `
SELECT tablename
FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog' AND
schemaname != 'information_schema'
`;
return db.all(sql)
.then(rows => rows.map(row => row.tablename).reverse())
}
const teardown = (tableNames) => {
if (tableNames.length) {
console.log(`Tearing down tables:`)
console.log(` - ${tableNames.join("\n - ")}`)
const sql = `DROP TABLE IF EXISTS ${tableNames.join(",")}`;
return db.query(sql);
} else {
console.log("No tables left to drop.");
return Promise.resolve();
}
}
const handleExit = (error=undefined) => {
if (error != undefined) {
console.log(`🚫 Exited with error: ${error}`);
process.exit(1);
}
console.log("✅ Exited teardown successfully!");
process.exit(0);
};
db.connect()
.then(() => allTableNames())
.then(tableNames => teardown(tableNames))
.catch(console.log)
.finally(handleExit)
module.exports = db;