jugglingdb
Version:
Node.js ORM for every database: redis, mysql, mongodb, postgres, sqlite, ...
278 lines (243 loc) • 8.63 kB
JavaScript
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var fs = require('fs');
var path = require('path');
var Schema = require('./schema').Schema;
var existsSync = fs.existsSync || path.existsSync;
/* global railway */
if (global.railway) {
railway.orm._schemas = [];
}
module.exports = function init(root) {
var railway = void 0,
app = void 0,
models = void 0;
if ((typeof root === 'undefined' ? 'undefined' : _typeof(root)) !== 'object' || root.constructor.name !== 'Compound' && root.constructor.name !== 'CompoundServer') {
railway = global.railway;
app = global.app;
models = app.models;
} else {
railway = root;
app = railway.app;
root = railway.root;
models = railway.models;
}
railway.orm._schemas = [];
var confFile = (root || app.root) + '/config/database';
var appConf = app.get('database');
var config = railway.orm.config = appConf || {};
var env = app.set('env');
var schema = void 0;
if (!railway.parent) {
if (!appConf) {
try {
var cf = require(confFile);
if (cf instanceof Array) {
cf = cf[0];
}
if (typeof cf === 'function') {
config = cf(railway);
} else {
config = cf[env];
}
} catch (e) {
console.log('Could not load config/database.{js|json|yml}');
throw e;
}
}
if (!config) {
console.log('No environment ' + env + ' found in config/database.{js|json|yml}');
throw new Error('No environment ' + env + ' found in config/database.{js|json|yml}');
}
// when driver name started with point - look for driver in app root (relative path)
if (config.driver && config.driver.match(/^\./)) {
config.driver = path.join(app.root, config.driver);
}
schema = new Schema(config && config.driver || 'memory', config);
schema.log = log;
if (!schema.adapter) {
throw new Error('Adapter is not defined');
}
} else {
schema = railway.parent.orm._schemas[0];
}
if (schema.waitForConnect) {
schema.on('connected', function () {
return loadSchema(schema, railway, app, models);
});
} else {
loadSchema(schema, railway, app, models);
}
// check validations and display warning
function loadSchema(schema, railway, app, models) {
railway.orm._schemas.push(schema);
var context = prepareContext(models, railway, app, schema);
// run schema first
var schemaFile = (root || app.root) + '/db/schema.';
if (existsSync(schemaFile + 'js')) {
schemaFile += 'js';
} else if (existsSync(schemaFile + 'coffee')) {
schemaFile += 'coffee';
} else {
schemaFile = false;
}
if (schemaFile) {
var code = fs.readFileSync(schemaFile).toString();
if (schemaFile.match(/\.coffee$/)) {
code = require('coffee-script').compile(code);
}
/*jshint evil: true */
var fn = new Function('context', 'require', 'with(context){(function(){' + code + '})()}');
fn(context, require);
}
// autoupdate if set app.enable('autoupdate') or freeze schemas by default
railway.orm._schemas.forEach(function (schema) {
if (app.enabled('autoupdate')) {
schema.autoupdate();
} else {
schema.freeze();
}
});
}
function log(str, startTime) {
var $ = railway.utils.stylize.$;
var m = Date.now() - startTime;
railway.utils.debug(str + $(' [' + (m < 10 ? m : $(m).red) + ' ms]').bold);
app.emit('app-event', {
type: 'query',
param: str,
time: m
});
}
function prepareContext(models, railway, app, defSchema, done) {
var ctx = { app: app },
_models = {},
settings = {};
var cname = void 0,
schema = void 0,
connected = 0,
wait = 0,
nonJugglingSchema = false;
done = done || function () {};
/**
* Multiple schemas support
* example:
* schema('redis', {url:'...'}, function() {
* describe models using redis connection
* ...
* });
* schema(function() {
* describe models stored in memory
* ...
* });
*/
ctx.schema = function () {
var name = argument('string');
var opts = argument('object') || {};
var def = argument('function') || function () {};
schema = new Schema(name || opts.driver || 'memory', opts);
railway.orm._schemas.push(schema);
wait += 1;
ctx.gotSchema = true;
schema.on('log', log);
schema.on('connected', function () {
connected += 1;
if (wait === connected) {
done();
}
});
def();
schema = false;
};
/**
* Use custom schema driver
*/
ctx.customSchema = function () {
var def = argument('function') || function () {};
nonJugglingSchema = true;
def();
Object.keys(ctx.exports).forEach(function (m) {
ctx.define(m, ctx.exports[m]);
});
nonJugglingSchema = false;
};
ctx.exports = {};
ctx.module = { exports: ctx.exports };
/**
* Define a class in current schema
*/
ctx.describe = ctx.define = function (className, callback) {
var m = void 0;
cname = className;
_models[cname] = {};
settings[cname] = {};
if (nonJugglingSchema) {
m = callback;
} else {
if (typeof callback === 'function') {
callback();
}
m = (schema || defSchema).define(className, _models[cname], settings[cname]);
}
if (global.railway) {
global[cname] = m;
}
models[cname] = ctx[cname] = m;
return m;
};
/**
* Define a property in current class
*/
ctx.property = function (name, type, params) {
if (!params) {
params = {};
}
if (typeof type !== 'function' && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && !(type instanceof Array)) {
params = type;
type = String;
}
params.type = type || String;
_models[cname][name] = params;
};
/**
* Set custom table name for current class
* @param name - name of table
*/
ctx.setTableName = function (name) {
if (cname) {
settings[cname].table = name;
}
};
/**
* Set configuration param
*
* @param name - name of param.
* @param value - value.
*/
ctx.set = function (name, value) {
if (cname) {
settings[cname][name] = value;
}
};
ctx.pathTo = railway.map && railway.map.pathTo || {};
/**
* If the Schema has additional types, add them to the context
* e.g. MySQL has an additional Point type
*/
if (Schema.types && Object.keys(Schema.types).length) {
Object.keys(Schema.types).forEach(function (typeName) {
ctx[typeName] = Schema.types[typeName];
});
}
return ctx;
function argument(type) {
var r = void 0;
[].forEach.call(arguments.callee.caller.arguments, function (a) {
if (!r && (typeof a === 'undefined' ? 'undefined' : _typeof(a)) === type) {
r = a;
}
});
return r;
}
}
};
;