Sequelize adapter

This commit is contained in:
Anatoliy Chakkaev 2011-10-01 23:40:22 +04:00
parent d5341d3126
commit d865b77aea
3 changed files with 199 additions and 8 deletions

View File

@ -37,6 +37,14 @@ function Text() {
}
Schema.Text = Text;
Schema.prototype.automigrate = function (cb) {
if (this.adapter.automigrate) {
this.adapter.automigrate(cb);
} else {
cb && cb();
}
};
/**
* Define class
* @param className
@ -103,12 +111,14 @@ function AbstractClass(name, properties, settings, data) {
var self = this;
data = data || {};
if (data.id) {
Object.defineProperty(this, 'id', {
writable: false,
enumerable: true,
configurable: true,
value: data.id
});
}
Object.keys(properties).forEach(function (attr) {
var _attr = '_' + attr,
@ -158,6 +168,7 @@ AbstractClass.create = function (data) {
if (arguments.length == 0 || data === callback) {
data = {};
}
if (typeof callback !== 'function') {
callback = function () {};
}

178
lib/sequelize.js Normal file
View File

@ -0,0 +1,178 @@
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);
};

View File

@ -11,8 +11,10 @@
"test": "nodeunit test/*_test.js"
},
"engines": {
"node": "~v0.4.9"
"node": ">= v0.4.0"
},
"dependencies": {
"redis": "=0.6.7"
},
"dependencies": {},
"devDependencies": {}
}