loopback-datasource-juggler/lib/sequelize.js

179 lines
4.6 KiB
JavaScript

var Sequelize = require('sequelize');
exports.initialize = function initializeSchema(schema) {
schema.adapter = new SequelizeAdapter(schema);
};
function SequelizeAdapter(schema) {
this.schema = schema;
this._models = {};
this._modelDefinitions = {};
this.client = new Sequelize(
schema.settings.database,
schema.settings.username,
schema.settings.password, {
host: schema.settings.host,
port: schema.settings.port,
logging: schema.settings.port,
maxConcurrentQueries: schema.settings.maxConcurrentQueries
}
);
}
SequelizeAdapter.prototype.define = function (d) {
var model = d.model;
var settings = d.settings;
var properties = d.properties;
var translate = {
'String': Sequelize.STRING,
'Text': Sequelize.TEXT,
'Number': Sequelize.INTEGER,
'Boolean': Sequelize.BOOLEAN,
'Date': Sequelize.DATE
};
var props = {};
Object.keys(properties).forEach(function (property) {
props[property] = translate[properties[property].type.name];
});
this._modelDefinitions[model.modelName] = props;
this._models[model.modelName] = this.client.define(model.modelName, props, settings);
};
SequelizeAdapter.prototype.model = function getModel(name) {
return this._models[name];
};
SequelizeAdapter.prototype.cleanup = function (model, obj) {
if (!obj) {
return null;
}
var def = this._modelDefinitions[model];
var data = {};
Object.keys(def).concat(['id']).forEach(function (key) {
data[key] = obj[key];
});
return data;
};
SequelizeAdapter.prototype.save = function (model, data, callback) {
this.model(model).find(data.id)
.on('success', function (record) {
record.updateAttributes(data)
.on('success', callback.bind(data, null))
.on('failure', callback);
})
.on('failure', callback);
};
SequelizeAdapter.prototype.updateAttributes = function (model, id, data, callback) {
data.id = id;
this.save(model, data, callback);
};
SequelizeAdapter.prototype.create = function (model, data, callback) {
this.model(model)
.build(data)
.save()
.on('success', function (obj) {
callback(null, obj.id);
})
.on('failure', callback);
};
SequelizeAdapter.prototype.automigrate = function (cb) {
this.client.sync({force: true})
.on('success', cb.bind(this, null))
.on('failure', cb);
};
SequelizeAdapter.prototype.exists = function (model, id, callback) {
this.model(model)
.find(id)
.on('success', function (data) {
if (callback) {
callback.calledOnce = true;
callback(null, data);
}
})
.on('failure', co(callback));
};
function co(cb, args) {
return function () {
if (!cb.calledOnce) {
cb.calledOnce = true;
cb.call.apply(cb, args || []);
}
}
}
SequelizeAdapter.prototype.find = function find(model, id, callback) {
this.model(model)
.find(id)
.on('success', function (data) {
callback(null, this.cleanup(model, data));
}.bind(this))
.on('failure', callback);
};
SequelizeAdapter.prototype.destroy = function destroy(model, id, callback) {
this.model(model)
.find(id)
.on('success', function (data) {
data.destroy()
.on('success', callback.bind(null, null))
.on('failure', callback);
}.bind(this))
.on('failure', callback);
};
SequelizeAdapter.prototype.all = function all(model, filter, callback) {
this.model(model).all.on('success', function (data) {
// TODO: filter
callback(null, data);
}).on('failure', callback);
};
function applyFilter(filter) {
if (typeof filter === 'function') {
return filter;
}
var keys = Object.keys(filter);
return function (obj) {
var pass = true;
keys.forEach(function (key) {
if (!test(filter[key], obj[key])) {
pass = false;
}
});
return pass;
}
function test(example, value) {
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
return value.match(example);
}
// not strict equality
return example == value;
}
}
SequelizeAdapter.prototype.destroyAll = function destroyAll(model, callback) {
callback();
};
SequelizeAdapter.prototype.count = function count(model, callback) {
this.model(model).count()
.on('success', function (c) {
if (callback) callback(null, c);
})
.on('failure', callback);
};