@house-agency/brewstore
Version:
The Brewery Storage
107 lines (97 loc) • 2.75 kB
JavaScript
/**
* Handles Relational Data Storage ~= MySQL
* It's using Sequelize
*/
const _ = require('lodash');
const conf = require('@house-agency/brewtils/config');
const log = require('@house-agency/brewtils/log');
const q = require('q');
const Sequelize = require('sequelize');
/**
* Sets up the Sequelize by getting the database
* connection properties from config.
* In this way, we'll have a global database connection pool.
*
* @returns {object} Promise with sequelize instance
*/
function connect() {
return conf('storage.relational')
.then(props => {
log('debug', 'Connecting to relational storage', props);
return new Sequelize(
props.database,
props.username,
props.password,
{
host: props.host,
dialect: props.engine,
dialectOptions: {
multipleStatements: true
},
pool: {
max: props.pool.max
},
logging: props.logging
}
);
});
}
const connection = connect();
/**
* Creates a database model
*
* @param {string} name Table name
* @param {object} fields Table fields
* @param {object} dependent_promise An optional promise that must
* be resolved before creating table. Usable for relations.
*
* @return {object} Promise with the model
*/
function create_table(name, fields, dependent_promise) {
return q.all([
connection,
dependent_promise != null ? dependent_promise : q()
])
.spread(database => {
const table = database.define(name, fields);
return table.sync()
.then(() => database.getQueryInterface().describeTable(name))
.then(columns => auto_add_columns(
database.getQueryInterface(),
name,
columns,
fields
))
.then(() => table)
.catch(error => {
log('fatal', 'Error when defining model', name, fields, error);
throw error;
});
});
}
/**
* Automaticly add non-existing columns to table
*
* @param {object} query Query interface
* @param {string} table Table name
* @param {object} current Existing columns
* @param {object} columns The wanted set of fields
*
* @returns {void} Empty promise
*/
function auto_add_columns(query, table, current, columns) {
return _.reduce(columns, (promise, props, name) => {
return promise
.then(() => {
if (!_.has(current, name)) {
return query.addColumn(table, name, props);
}
});
}, q());
}
module.exports = Object.assign(
connection,
{
create_table: create_table
}
);