Permalink
Browse files

Added ability to define custom clauses, updated tests

  • Loading branch information...
1 parent ce018cb commit f496efde5c81ca109c429447158a6f4e58712b10 Robert Poole committed Jul 17, 2013
Showing with 94 additions and 14 deletions.
  1. +24 −5 lib/model.js
  2. +28 −4 lib/query.js
  3. +17 −4 test/chain.js
  4. +25 −1 test/define.js
View
@@ -106,10 +106,10 @@ function addAssociationMethod (obj, associationName, association) {
switch (association.type) {
case "hasMany":
addHasManyAssociationMethod(obj, associationName, association);
- break;
+ break;
case "hasOne":
addHasOneAssociationMethod(obj, associationName, association);
- break;
+ break;
default:
throw new Error("Invalid association type '" + association.type + "'");
}
@@ -214,17 +214,36 @@ exports.define = function (name, columnDefs, opts) {
Model.tableName = opts.tableName || inflection.pluralize(name);
Model.associations = {};
Model.columns = {};
+ Model.customClauses = {};
Model.eventEmmiter = new events.EventEmitter();
var n;
for (n in events.EventEmitter.prototype) {
Model[n] = events.EventEmitter.prototype[n];
/*
- Model[n] = function() {
- Model.eventEmmiter.apply(Model.eventEmmiter, arguments);
- }*/
+ Model[n] = function() {
+ Model.eventEmmiter.apply(Model.eventEmmiter, arguments);
+ }*/
}
+ Model.defineClause = function(name, clauses) {
+ if (Model[name] || Query[name] || this.customClauses[name]) {
+ throw new Error('You cannot define a custom clause using that name as one already exists.');
+ }
+
+ this.customClauses[name] = clauses;
+
+ // add it to the model
+ Model[name] = function() {
+ var query = this.using(null);
+ return query[name].apply(query, arguments);
+ };
+
+ Model[name] = persistUtil.bind(name, Model[name], Model);
+
+ return this;
+ };
+
Model.normalizeColumnDef = function (propertyName, columnDef) {
if (!columnDef) {
throw new Error(util.format('Invalid column definition for property "%s" of model "%s"', propertyName, this.modelName));
View
@@ -34,8 +34,32 @@ var Query = function(connection, model) {
}
}
}
+
+ this._defineCustomClauses();
};
+Query.prototype._defineCustomClauses = function() {
+ var customClauses = this.model.customClauses;
+
+ for (var name in customClauses) {
+ var clauses = customClauses[name];
+
+ this[name] = function() {
+ for (var clause in clauses) {
+ if (!this[clause]) {
+ throw new Error('Clause "' + clause + '" does not exist.');
+ }
+
+ var args = clauses[clause];
+ this[clause](args);
+ }
+
+ return this;
+ };
+
+ }
+}
+
// "name = ?", "bob"
// "name = ? AND age = ?", ["bob", 6]
// "name = 'bob'"
@@ -83,8 +107,8 @@ Query.prototype.include = function() {
if (typeof (arguments[0]) === 'string') {
var associationPropertyName = arguments[0];
var association = this.model.associations[associationPropertyName]
- || this.model.associations[inflection.singularize(associationPropertyName)]
- || this.model.associations[inflection.pluralize(associationPropertyName)];
+ || this.model.associations[inflection.singularize(associationPropertyName)]
+ || this.model.associations[inflection.pluralize(associationPropertyName)];
if (!association) {
throw new Error('Could not find association "' + associationPropertyName + '" off of "' + this.model.modelName + '"');
}
@@ -141,8 +165,8 @@ Query.prototype.leftJoin = function(otherTable, otherTableId, thisTableId) {
Query.prototype._join = function(type, otherTable, otherTableId, thisTableId) {
if (arguments.length === 2) {
var association = this.model.associations[arguments[1]]
- || this.model.associations[inflection.singularize(arguments[1])]
- || this.model.associations[inflection.pluralize(arguments[1])];
+ || this.model.associations[inflection.singularize(arguments[1])]
+ || this.model.associations[inflection.pluralize(arguments[1])];
otherTable = association.model.tableName;
if (association.type === 'hasOne') {
otherTableId = this.model.getIdColumn().dbColumnName;
View
@@ -18,6 +18,11 @@ exports['Chain'] = nodeunit.testCase({
"age": type.INTEGER
}).hasMany(this.Phone);
+ this.Person.defineClause('testClause', {
+ where: ["age = ?", 21],
+ where: "name like '%Bob%'",
+ });
+
testUtils.connect(persist, {}, function(err, connection) {
if(err) { console.log(err); return; }
self.connection = connection;
@@ -61,9 +66,13 @@ exports['Chain'] = nodeunit.testCase({
self.Phone.deleteAll,
self.Phone.all,
self.Person.first,
- persist.runSqlAll('SELECT * FROM People')
+ persist.runSqlAll('SELECT * FROM People'),
+ self.Person.testClause().all,
], function(err, results) {
- if(err) { console.error(err); return; }
+ if (err) {
+ console.error(err);
+ return;
+ }
// person3.save
test.equal(results[0].name, 'fred');
@@ -115,6 +124,10 @@ exports['Chain'] = nodeunit.testCase({
// Person.first
test.ok(results[14].length, 5);
+ // Person.testClause
+ test.ok(results[15].length, 1);
+ test.ok(results[15][0].name, "Bob O'Neill");
+
test.done();
});
},
@@ -131,6 +144,6 @@ exports['Chain'] = nodeunit.testCase({
test.equal(results.maxAge, 23);
test.done();
});
- }
+ },
-});
+});
View
@@ -84,6 +84,30 @@ exports['Define'] = nodeunit.testCase({
test.equals(person.phones.length, 0);
test.done();
- }
+ },
+ "defineClause": function(test) {
+ var Person = persist.define("Person", {
+ "name": type.STRING
+ }).defineClause('testClause', {
+ where: 'id = 1',
+ });
+
+ assert.isNotNullOrUndefined(Person.testClause, "Person.testClause is null or undefined");
+ test.done();
+ },
+
+ "defineClauseError": function(test) {
+ test.throws(function(){
+ var Person = persist.define("Person", {
+ "name": type.STRING
+ });
+
+ Person.property = 'hi';
+
+ Person.defineClause('property', {});
+ }, 'defineClause did not throw an error.');
+
+ test.done();
+ },
});

0 comments on commit f496efd

Please sign in to comment.