Set up database migrations to run automatically on server startup
This commit is contained in:
parent
a272c420cd
commit
5a8613c701
3 changed files with 44 additions and 9 deletions
|
@ -2,15 +2,16 @@ import path from 'path';
|
|||
import sqlite3 from 'sqlite3';
|
||||
import * as migrations from './migrations';
|
||||
|
||||
|
||||
export function db(dataDir: string): sqlite3.Database {
|
||||
const db = new sqlite3.Database(path.join(dataDir, "twigs.db"), (err) => {
|
||||
const dbPath = path.join(dataDir, "twigs.db");
|
||||
console.log(`Initializing database at ${dbPath}`)
|
||||
const db = new sqlite3.Database(dbPath, (err?: Error) => {
|
||||
if (err != null) {
|
||||
console.error("Failed to open db");
|
||||
console.error(err);
|
||||
throw 'Failed to open db';
|
||||
}
|
||||
|
||||
migrations.migrate(db);
|
||||
});
|
||||
return db
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
import sqlite3 from 'sqlite3';
|
||||
import path from 'path';
|
||||
|
||||
function migrate_0_1(db: sqlite3.Database) {
|
||||
db.serialize(() => {
|
||||
/**
|
||||
* The current desired database version. Used to run migrations
|
||||
*/
|
||||
const DESIRED_DB_VERSION = 1;
|
||||
|
||||
const migrations: Record<number, (db: sqlite3.Database) => void> = {
|
||||
0: (db: sqlite3.Database) => {
|
||||
db.serialize(() => {
|
||||
db.run(`
|
||||
CREATE TABLE user (
|
||||
id TEXT PRIMARY KEY,
|
||||
|
@ -9,14 +16,18 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
username TEXT NOT NULL UNIQUE,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE budget (
|
||||
id TEXT PRIMARY KEY,
|
||||
currency_code TEXT DEFAULT NULL,
|
||||
description TEXT DEFAULT NULL,
|
||||
name TEXT DEFAULT NULL
|
||||
);
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE category (
|
||||
id TEXT PRIMARY KEY,
|
||||
amount UNSIGNED BIG INT NOT NULL,
|
||||
|
@ -27,7 +38,9 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
archived BOOLEAN NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (budget_id) REFERENCES budget(id)
|
||||
);
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE password_reset_request (
|
||||
id TEXT PRIMARY KEY,
|
||||
date DATETIME DEFAULT NULL,
|
||||
|
@ -35,7 +48,9 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
user_id TEXT NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES user(id)
|
||||
);
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE session (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
|
@ -43,7 +58,9 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
expiration date NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES user(id)
|
||||
);
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE 'transaction' (
|
||||
id TEXT PRIMARY KEY,
|
||||
amount UNSIGNED BIG INT NOT NULL,
|
||||
|
@ -58,7 +75,9 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
FOREIGN KEY (category_id) REFERENCES category(id),
|
||||
FOREIGN KEY (created_by_id) REFERENCES user(id)
|
||||
);
|
||||
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE user_permission (
|
||||
budget_id TEXT NOT NULL,
|
||||
user_id TEXT NOT NULL,
|
||||
|
@ -69,5 +88,19 @@ function migrate_0_1(db: sqlite3.Database) {
|
|||
);
|
||||
`);
|
||||
db.run('PRAGMA user_version = 1');
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
export function migrate(db: sqlite3.Database) {
|
||||
db.get('PRAGMA user_version;', (err?: Error, row?: any) => {
|
||||
let dbVersion = row.user_version;
|
||||
while (dbVersion < DESIRED_DB_VERSION) {
|
||||
console.log(`Migrating database from ${dbVersion} to ${dbVersion + 1}...`);
|
||||
migrations[dbVersion](db);
|
||||
console.log(`Completed database migration from ${dbVersion} to ${dbVersion + 1}`)
|
||||
dbVersion++;
|
||||
}
|
||||
console.log(`Database is up to date`)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@ import { router as categoryRouter } from './categories/controller'
|
|||
import { router as permissionsRouter } from './permissions/controller'
|
||||
import { router as transactionRouter } from './transactions/controller'
|
||||
import { router as userRouter } from './users/controller'
|
||||
import { db as _db } from './db';
|
||||
|
||||
const port = process.env.PORT || 3000;
|
||||
const app = express();
|
||||
|
||||
const dataDir = process.env.TWIGS_DATA || __dirname;
|
||||
const db = _db(dataDir);
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
|
@ -27,7 +29,6 @@ app.get('/*', (req, res) => {
|
|||
res.sendFile(__dirname + '/public/index.html');
|
||||
});
|
||||
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Twigs server listening at http://localhost:${port}`)
|
||||
console.log(`Serving static content from ${__dirname}/public`)
|
||||
|
|
Loading…
Reference in a new issue