Promisify and asyncify db initialization.
This commit is contained in:
parent
732c973145
commit
ddb2f47a9d
|
@ -1,111 +1,83 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async');
|
const util = require('util');
|
||||||
var fs = require('graceful-fs');
|
const fs = require('graceful-fs');
|
||||||
var glob = require('glob');
|
const glob = util.promisify(require('glob'));
|
||||||
var path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
var config = require('../config');
|
const config = require('../config');
|
||||||
var Logger = require('../logger');
|
const Logger = require('../logger');
|
||||||
|
|
||||||
function applyPatch(db, file, callback) {
|
async function applyPatch(db, file) {
|
||||||
Logger.tag('database', 'migration').info('Checking if patch need to be applied: %s', file);
|
Logger.tag('database', 'migration').info('Checking if patch need to be applied: %s', file);
|
||||||
|
|
||||||
fs.readFile(file, function (err, contents) {
|
const contents = await util.promisify(fs.readFile)(file);
|
||||||
if (err) {
|
const version = path.basename(file, '.sql');
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var version = path.basename(file, '.sql');
|
const row = await db.get('SELECT * FROM schema_version WHERE version = ?', version);
|
||||||
|
if (row) {
|
||||||
|
// patch is already applied. skip!
|
||||||
|
Logger.tag('database', 'migration').info('Patch already applied, skipping: %s', file);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
db.get('SELECT * FROM schema_version WHERE version = ?', version, function (err, row) {
|
const sql = 'BEGIN TRANSACTION;\n' +
|
||||||
if (err) {
|
contents.toString() + '\n' +
|
||||||
return callback(err);
|
'INSERT INTO schema_version (version) VALUES (\'' + version + '\');\n' +
|
||||||
}
|
'END TRANSACTION;';
|
||||||
|
|
||||||
if (row) {
|
await db.exec(sql);
|
||||||
// patch is already applied. skip!
|
|
||||||
Logger.tag('database', 'migration').info('Patch already applied, skipping: %s', file);
|
|
||||||
return callback(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var sql = 'BEGIN TRANSACTION;\n' +
|
Logger.tag('database', 'migration').info('Patch successfully applied: %s', file);
|
||||||
contents.toString() + '\n' +
|
|
||||||
'INSERT INTO schema_version (version) VALUES (\'' + version + '\');\n' +
|
|
||||||
'END TRANSACTION;';
|
|
||||||
|
|
||||||
db.exec(sql, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.tag('database', 'migration').info('Patch successfully applied: %s', file);
|
|
||||||
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyMigrations(db, callback) {
|
async function applyMigrations(db) {
|
||||||
Logger.tag('database', 'migration').info('Migrating database...');
|
Logger.tag('database', 'migration').info('Migrating database...');
|
||||||
|
|
||||||
var sql = 'BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS schema_version (\n' +
|
const sql = 'BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS schema_version (\n' +
|
||||||
' version VARCHAR(255) PRIMARY KEY ASC,\n' +
|
' version VARCHAR(255) PRIMARY KEY ASC,\n' +
|
||||||
' applied_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL\n' +
|
' applied_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL\n' +
|
||||||
'); END TRANSACTION;';
|
'); END TRANSACTION;';
|
||||||
db.exec(sql, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
glob(__dirname + '/patches/*.sql', function (err, files) {
|
await db.exec(sql);
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
async.eachSeries(
|
const files = await glob(__dirname + '/patches/*.sql');
|
||||||
files,
|
for (const file of files) {
|
||||||
function (file, fileCallback) {
|
await applyPatch(db, file)
|
||||||
applyPatch(db, file, fileCallback);
|
}
|
||||||
},
|
}
|
||||||
callback
|
|
||||||
);
|
async function init() {
|
||||||
});
|
const SQLite3 = require('sqlite3');
|
||||||
|
|
||||||
|
const file = config.server.databaseFile;
|
||||||
|
Logger.tag('database').info('Setting up database: %s', file);
|
||||||
|
|
||||||
|
let db;
|
||||||
|
try {
|
||||||
|
db = new SQLite3.Database(file);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
Logger.tag('database').error('Error initialzing database:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.on('profile', (sql, time) => Logger.tag('database').profile('[%sms]\t%s', time, sql));
|
||||||
|
|
||||||
|
try {
|
||||||
|
await applyMigrations(db);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
Logger.tag('database').error('Error migrating database:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: We have to use funtion() syntax here, to satisfy ng-di. m(
|
||||||
|
return angular.module('ffffng').factory('Database', function () {
|
||||||
|
return db;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function (callback) {
|
init
|
||||||
var SQLite3 = require('sqlite3');
|
|
||||||
|
|
||||||
var file = config.server.databaseFile;
|
|
||||||
Logger.tag('database').info('Setting up database: %s', file);
|
|
||||||
|
|
||||||
var db;
|
|
||||||
try {
|
|
||||||
db = new SQLite3.Database(file);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
Logger.tag('database').error('Error initialzing database:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.on('profile', function (sql, time) {
|
|
||||||
Logger.tag('database').profile('[%sms]\t%s', time, sql);
|
|
||||||
});
|
|
||||||
|
|
||||||
applyMigrations(db, function (err) {
|
|
||||||
if (err) {
|
|
||||||
Logger.tag('database').error('Error migrating database:', err);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
angular.module('ffffng').factory('Database', function () {
|
|
||||||
return db;
|
|
||||||
});
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,8 @@ angular.module('ffffng', []);
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
// Use graceful-fs instead of fs also in all libraries to have more robust fs handling.
|
// Use graceful-fs instead of fs also in all libraries to have more robust fs handling.
|
||||||
var realFs = require('fs');
|
const realFs = require('fs');
|
||||||
var gracefulFs = require('graceful-fs');
|
const gracefulFs = require('graceful-fs');
|
||||||
gracefulFs.gracefulify(realFs);
|
gracefulFs.gracefulify(realFs);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ require('./validation/validator');
|
||||||
|
|
||||||
require('./jobs/scheduler');
|
require('./jobs/scheduler');
|
||||||
|
|
||||||
var db = require('./db/database');
|
const db = require('./db/database');
|
||||||
|
|
||||||
db.init(function () {
|
db.init().then(() => {
|
||||||
|
// WARNING: We have to use funtion() syntax here, to satisfy ng-di. m(
|
||||||
angular.injector(['ffffng']).invoke(function (config, app, Logger, Scheduler, Router) {
|
angular.injector(['ffffng']).invoke(function (config, app, Logger, Scheduler, Router) {
|
||||||
Logger.tag('main').info('Initializing...');
|
Logger.tag('main').info('Initializing...');
|
||||||
|
|
||||||
|
@ -58,4 +59,7 @@ db.init(function () {
|
||||||
app.listen(config.server.port, '::');
|
app.listen(config.server.port, '::');
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
});
|
});
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Could not init database: ', error);
|
||||||
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue