ffffng/server/db/database.js
2017-05-06 17:31:34 +02:00

112 lines
3.1 KiB
JavaScript

'use strict';
var async = require('async');
var fs = require('graceful-fs');
var glob = require('glob');
var path = require('path');
var config = require('../config');
var Logger = require('../logger');
function applyPatch(db, file, callback) {
Logger.tag('database', 'migration').info('Checking if patch need to be applied: %s', file);
fs.readFile(file, function (err, contents) {
if (err) {
return callback(err);
}
var version = path.basename(file, '.sql');
db.get('SELECT * FROM schema_version WHERE version = ?', version, function (err, row) {
if (err) {
return callback(err);
}
if (row) {
// patch is already applied. skip!
Logger.tag('database', 'migration').info('Patch already applied, skipping: %s', file);
return callback(null);
}
var sql = 'BEGIN TRANSACTION;\n' +
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) {
Logger.tag('database', 'migration').info('Migrating database...');
var sql = 'BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS schema_version (\n' +
' version VARCHAR(255) PRIMARY KEY ASC,\n' +
' applied_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL\n' +
'); END TRANSACTION;';
db.exec(sql, function (err) {
if (err) {
return callback(err);
}
glob(__dirname + '/patches/*.sql', function (err, files) {
if (err) {
return callback(err);
}
async.eachSeries(
files,
function (file, fileCallback) {
applyPatch(db, file, fileCallback);
},
callback
);
});
});
}
module.exports = {
init: function (callback) {
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();
});
}
};