/
AggregateFunctions.js
80 lines (65 loc) · 2.01 KB
/
AggregateFunctions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
module.exports = AggregateFunctions;
function AggregateFunctions(opts) {
if (typeof opts.driver.getQuery != "function") {
throw new Error("This driver does not support aggregate functions");
}
if (!Array.isArray(opts.driver.aggregate_functions)) {
throw new Error("This driver does not support aggregate functions");
}
var aggregates = [ [] ];
var appendFunction = function (fun) {
return function () {
var args = (arguments.length && Array.isArray(arguments[0]) ? arguments[0] : Array.prototype.slice.apply(arguments));
if (args.length > 0) {
aggregates[aggregates.length - 1].push({ f: fun, a: args });
aggregates.push([]);
} else {
aggregates[aggregates.length - 1].push({ f: fun });
}
return proto;
};
};
var proto = {
get : function (cb) {
if (typeof cb != "function") {
throw new Error("You must pass a callback to Model.aggregate().get()");
}
if (aggregates[aggregates.length - 1].length === 0) {
aggregates.length -= 1;
}
if (aggregates.length === 0) {
throw new Error("Missing aggregate functions");
}
var query = opts.driver.getQuery().select().from(opts.table);
for (var i = 0; i < aggregates.length; i++) {
for (var j = 0; j < aggregates[i].length; j++) {
query[aggregates[i][j].f](aggregates[i][j].a);
}
}
query.where(opts.conditions);
opts.driver.execQuery(query.build(), function (err, data) {
if (err) {
return cb(err);
}
var items = [];
for (var k in data[0]) {
if (!data[0].hasOwnProperty(k)) continue;
items.push(data[0][k]);
}
items.unshift(null);
return cb.apply(null, items);
});
}
};
for (var i = 0; i < opts.driver.aggregate_functions.length; i++) {
addAggregate(proto, opts.driver.aggregate_functions[i], appendFunction);
}
return proto;
}
function addAggregate(proto, fun, builder) {
if (Array.isArray(fun)) {
proto[fun[0].toLowerCase()] = builder((fun[1] || fun[0]).toLowerCase());
} else {
proto[fun.toLowerCase()] = builder(fun.toLowerCase());
}
}