cormo
Advanced tools
Comparing version 0.6.2 to 0.6.3
@@ -716,19 +716,17 @@ // Generated by CoffeeScript 1.6.2 | ||
options.orders.forEach(function(order) { | ||
var column, dir; | ||
if (order[0] === '-') { | ||
return orders[order.slice(1)] = -1; | ||
column = order.slice(1); | ||
dir = -1; | ||
} else { | ||
return orders[order] = 1; | ||
column = order; | ||
dir = 1; | ||
} | ||
if (options.group_by && column === options.group_by.join(',')) { | ||
column = '_id'; | ||
} | ||
return orders[column] = dir; | ||
}); | ||
} | ||
client_options = { | ||
limit: options.limit, | ||
skip: options.skip | ||
}; | ||
if (fields) { | ||
client_options.fields = fields; | ||
} | ||
if (orders) { | ||
client_options.sort = orders; | ||
} | ||
if (options.group_by || options.group_fields) { | ||
@@ -744,2 +742,12 @@ pipeline = []; | ||
}); | ||
if (orders) { | ||
pipeline.push({ | ||
$sort: orders | ||
}); | ||
} | ||
if (options.conditions_of_group.length > 0) { | ||
pipeline.push({ | ||
$match: _buildWhere(options.group_fields, options.conditions_of_group) | ||
}); | ||
} | ||
return this._collection(model).aggregate(pipeline, function(error, result) { | ||
@@ -759,2 +767,12 @@ if (error) { | ||
} else { | ||
client_options = { | ||
limit: options.limit, | ||
skip: options.skip | ||
}; | ||
if (fields) { | ||
client_options.fields = fields; | ||
} | ||
if (orders) { | ||
client_options.sort = orders; | ||
} | ||
return this._collection(model).find(conditions, client_options, function(error, cursor) { | ||
@@ -761,0 +779,0 @@ if (error || !cursor) { |
@@ -386,2 +386,10 @@ // Generated by CoffeeScript 1.6.2 | ||
} | ||
if (options.conditions_of_group.length > 0) { | ||
try { | ||
sql += ' HAVING ' + this._buildWhere(options.group_fields, options.conditions_of_group, params); | ||
} catch (_error) { | ||
e = _error; | ||
return callback(e); | ||
} | ||
} | ||
if ((options != null ? options.orders.length : void 0) > 0 || order_by) { | ||
@@ -388,0 +396,0 @@ orders = options.orders.map(function(order) { |
@@ -381,2 +381,10 @@ // Generated by CoffeeScript 1.6.2 | ||
} | ||
if (options.conditions_of_group.length > 0) { | ||
try { | ||
sql += ' HAVING ' + this._buildWhere(options.group_fields, options.conditions_of_group, params); | ||
} catch (_error) { | ||
e = _error; | ||
return callback(e); | ||
} | ||
} | ||
if ((options != null ? options.orders.length : void 0) > 0) { | ||
@@ -383,0 +391,0 @@ orders = options.orders.map(function(order) { |
@@ -33,2 +33,5 @@ // Generated by CoffeeScript 1.6.2 | ||
property_type = property != null ? property.type : void 0; | ||
if (property && !property_type) { | ||
key = this._buildGroupExpr(property); | ||
} | ||
op = '='; | ||
@@ -134,4 +137,22 @@ if (Array.isArray(value)) { | ||
SQLAdapterBase.prototype._buildGroupExpr = function(group_expr) { | ||
var op, sub_expr; | ||
op = Object.keys(group_expr)[0]; | ||
if (op === '$sum') { | ||
sub_expr = group_expr[op]; | ||
if (sub_expr === 1) { | ||
return "COUNT(*)"; | ||
} else if (sub_expr.substr(0, 1) === '$') { | ||
return "SUM(" + (sub_expr.substr(1)) + ")"; | ||
} else { | ||
throw new Error("unknown expression '" + (JSON.stringify(op)) + "'"); | ||
} | ||
} else { | ||
throw new Error("unknown expression '" + (JSON.stringify(op)) + "'"); | ||
} | ||
}; | ||
SQLAdapterBase.prototype._buildGroupFields = function(group_by, group_fields) { | ||
var expr, field, op, selects, sub_expr; | ||
var expr, field, selects; | ||
@@ -144,15 +165,3 @@ selects = []; | ||
expr = group_fields[field]; | ||
op = Object.keys(expr)[0]; | ||
if (op === '$sum') { | ||
sub_expr = expr[op]; | ||
if (sub_expr === 1) { | ||
selects.push("COUNT(*) as " + field); | ||
} else if (sub_expr.substr(0, 1) === '$') { | ||
selects.push("SUM(" + (sub_expr.substr(1)) + ") as " + field); | ||
} else { | ||
throw new Error("unknown expression '" + (JSON.stringify(op)) + "'"); | ||
} | ||
} else { | ||
throw new Error("unknown expression '" + (JSON.stringify(op)) + "'"); | ||
} | ||
selects.push("" + (this._buildGroupExpr(expr)) + " as " + field); | ||
} | ||
@@ -159,0 +168,0 @@ return selects.join(','); |
@@ -323,2 +323,10 @@ // Generated by CoffeeScript 1.6.2 | ||
} | ||
if (options.conditions_of_group.length > 0) { | ||
try { | ||
sql += ' HAVING ' + this._buildWhere(options.group_fields, options.conditions_of_group, params); | ||
} catch (_error) { | ||
e = _error; | ||
return callback(e); | ||
} | ||
} | ||
if ((options != null ? options.orders.length : void 0) > 0) { | ||
@@ -325,0 +333,0 @@ orders = options.orders.map(function(order) { |
@@ -45,3 +45,5 @@ // Generated by CoffeeScript 1.6.2 | ||
this_model._associations[column] = { | ||
type: 'hasMany' | ||
type: 'hasMany', | ||
target_model: target_model, | ||
foreign_key: foreign_key | ||
}; | ||
@@ -130,3 +132,4 @@ return Object.defineProperty(this_model.prototype, column, { | ||
this_model._associations[column] = { | ||
type: 'hasOne' | ||
type: 'hasOne', | ||
target_model: target_model | ||
}; | ||
@@ -198,2 +201,6 @@ return Object.defineProperty(this_model.prototype, column, { | ||
columnGetter = '__getter_' + column; | ||
this_model._associations[column] = { | ||
type: 'belongsTo', | ||
target_model: target_model | ||
}; | ||
return Object.defineProperty(this_model.prototype, column, { | ||
@@ -349,2 +356,146 @@ get: function() { | ||
ConnectionAssociation.prototype._fetchAssociatedBelongsTo = function(records, target_model, column, select, callback) { | ||
var id, id_column, id_to_record_map, ids, query; | ||
id_column = column + '_id'; | ||
if (Array.isArray(records)) { | ||
id_to_record_map = {}; | ||
records.forEach(function(record) { | ||
var id; | ||
id = record[id_column]; | ||
if (id) { | ||
(id_to_record_map[id] || (id_to_record_map[id] = [])).push(record); | ||
} else if (!record.hasOwnProperty(column)) { | ||
Object.defineProperty(record, column, { | ||
enumerable: true, | ||
value: null | ||
}); | ||
} | ||
}); | ||
ids = Object.keys(id_to_record_map); | ||
query = target_model.find(ids); | ||
if (select) { | ||
query.select(select); | ||
} | ||
return query.exec(function(error, sub_records) { | ||
if (error) { | ||
return callback(null); | ||
} | ||
sub_records.forEach(function(sub_record) { | ||
return id_to_record_map[sub_record.id].forEach(function(record) { | ||
return Object.defineProperty(record, column, { | ||
enumerable: true, | ||
value: sub_record | ||
}); | ||
}); | ||
}); | ||
return callback(null); | ||
}); | ||
} else { | ||
id = records[id_column]; | ||
if (id) { | ||
query = target_model.find(id); | ||
if (select) { | ||
query.select(select); | ||
} | ||
return query.exec(function(error, sub_record) { | ||
if (error) { | ||
return callback(error); | ||
} | ||
Object.defineProperty(records, column, { | ||
enumerable: true, | ||
value: sub_record | ||
}); | ||
return callback(null); | ||
}); | ||
} else if (!records.hasOwnProperty(column)) { | ||
Object.defineProperty(records, column, { | ||
enumerable: true, | ||
value: null | ||
}); | ||
return callback(null); | ||
} | ||
} | ||
}; | ||
ConnectionAssociation.prototype._fetchAssociatedHasMany = function(records, target_model, foreign_key, column, select, callback) { | ||
var cond, ids, query; | ||
if (Array.isArray(records)) { | ||
ids = records.map(function(record) { | ||
Object.defineProperty(record, column, { | ||
enumerable: true, | ||
value: [] | ||
}); | ||
return record.id; | ||
}); | ||
cond = {}; | ||
cond[foreign_key] = { | ||
$in: ids | ||
}; | ||
query = target_model.where(cond); | ||
if (select) { | ||
query.select(select + ' ' + foreign_key); | ||
} | ||
return query.exec(function(error, sub_records) { | ||
if (error) { | ||
return callback(null); | ||
} | ||
sub_records.forEach(function(sub_record) { | ||
return records.forEach(function(record) { | ||
if (record.id === sub_record[foreign_key]) { | ||
return record[column].push(sub_record); | ||
} | ||
}); | ||
}); | ||
return callback(null); | ||
}); | ||
} else { | ||
Object.defineProperty(records, column, { | ||
enumerable: true, | ||
value: [] | ||
}); | ||
cond = {}; | ||
cond[foreign_key] = records.id; | ||
query = target_model.where(cond); | ||
if (select) { | ||
query.select(select + ' ' + foreign_key); | ||
} | ||
return query.exec(function(error, sub_records) { | ||
if (error) { | ||
return callback(null); | ||
} | ||
sub_records.forEach(function(sub_record) { | ||
return records[column].push(sub_record); | ||
}); | ||
return callback(null); | ||
}); | ||
} | ||
}; | ||
ConnectionAssociation.prototype.fetchAssociated = function(records, column, select, callback) { | ||
var association, record; | ||
if (typeof select === 'function') { | ||
callback = select; | ||
select = null; | ||
} | ||
record = Array.isArray(records) ? records[0] : records; | ||
if (!record) { | ||
return callback(null); | ||
} | ||
association = record.constructor._associations[column]; | ||
if (!association) { | ||
return callback(new Error("unknown column '" + column + "'")); | ||
} | ||
if (association.type === 'belongsTo') { | ||
return this._fetchAssociatedBelongsTo(records, association.target_model, column, select, callback); | ||
} else if (association.type === 'hasMany') { | ||
return this._fetchAssociatedHasMany(records, association.target_model, association.foreign_key, column, select, callback); | ||
} else { | ||
return callback(new Error("unknown column '" + column + "'")); | ||
} | ||
}; | ||
return ConnectionAssociation; | ||
@@ -351,0 +502,0 @@ |
@@ -26,4 +26,6 @@ // Generated by CoffeeScript 1.6.2 | ||
this._conditions = []; | ||
this._includes = []; | ||
this._options = { | ||
orders: [] | ||
orders: [], | ||
conditions_of_group: [] | ||
}; | ||
@@ -55,7 +57,24 @@ } | ||
Query.prototype._addCondition = function(condition) { | ||
var keys; | ||
if (this._options.group_fields) { | ||
keys = Object.keys(condition); | ||
if (keys.length === 1 && this._options.group_fields.hasOwnProperty(keys[0])) { | ||
this._options.conditions_of_group.push(condition); | ||
return; | ||
} | ||
} | ||
return this._conditions.push(condition); | ||
}; | ||
Query.prototype.where = function(condition) { | ||
var _this = this; | ||
if (Array.isArray(condition)) { | ||
this._conditions.push.apply(this._conditions, condition); | ||
condition.forEach(function(cond) { | ||
return _this._addCondition(cond); | ||
}); | ||
} else if (condition != null) { | ||
this._conditions.push(condition); | ||
this._addCondition(condition); | ||
} | ||
@@ -69,5 +88,5 @@ return this; | ||
this._options.select = null; | ||
schema_columns = Object.keys(this._model._schema); | ||
intermediate_paths = this._model._intermediate_paths; | ||
if (typeof columns === 'string') { | ||
schema_columns = Object.keys(this._model._schema); | ||
intermediate_paths = this._model._intermediate_paths; | ||
select = []; | ||
@@ -92,7 +111,11 @@ columns.split(/\s+/).forEach(function(column) { | ||
Query.prototype.order = function(orders) { | ||
var schema_columns, | ||
var avaliable_columns, | ||
_this = this; | ||
schema_columns = Object.keys(this._model._schema); | ||
if (typeof orders === 'string') { | ||
avaliable_columns = []; | ||
[].push.apply(avaliable_columns, Object.keys(this._model._schema)); | ||
if (this._options.group_fields) { | ||
[].push.apply(avaliable_columns, Object.keys(this._options.group_fields)); | ||
} | ||
orders.split(/\s+/).forEach(function(order) { | ||
@@ -106,3 +129,3 @@ var asc; | ||
} | ||
if (schema_columns.indexOf(order) >= 0) { | ||
if (avaliable_columns.indexOf(order) >= 0) { | ||
return _this._options.orders.push(asc ? order : '-' + order); | ||
@@ -150,2 +173,10 @@ } | ||
Query.prototype.include = function(column, select) { | ||
this._includes.push({ | ||
column: column, | ||
select: select | ||
}); | ||
return this; | ||
}; | ||
Query.prototype._exec = function(options, callback) { | ||
@@ -221,2 +252,17 @@ var expected_count, | ||
Query.prototype._execAndInclude = function(options, callback) { | ||
var _this = this; | ||
return this._exec(options, function(error, records) { | ||
if (error) { | ||
return callback(error); | ||
} | ||
return async.forEach(_this._includes, function(include, callback) { | ||
return _this._connection.fetchAssociated(records, include.column, include.select, callback); | ||
}, function(error) { | ||
return callback(error, records); | ||
}); | ||
}); | ||
}; | ||
Query.prototype.exec = function(options, callback) { | ||
@@ -238,3 +284,3 @@ var cache_key, cache_options, | ||
} | ||
return _this._exec(options, function(error, records) { | ||
return _this._execAndInclude(options, function(error, records) { | ||
if (error) { | ||
@@ -249,3 +295,3 @@ return callback(error); | ||
} else { | ||
return this._exec(options, callback); | ||
return this._execAndInclude(options, callback); | ||
} | ||
@@ -252,0 +298,0 @@ }; |
{ | ||
"name": "cormo", | ||
"description": "ORM framework for Node.js", | ||
"version": "0.6.2", | ||
"version": "0.6.3", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "orm", |
220110
5503