You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
2.8 KiB
JavaScript
162 lines
2.8 KiB
JavaScript
"use strict";
|
|
|
|
const assureArray = require("assure-array");
|
|
const assert = require("assert");
|
|
|
|
// moreThan, lessThan, equals, not, where, select, insert, update (set), delete, collapse, collapseBy, count, parameter
|
|
|
|
|
|
module.exports = {
|
|
insertInto: function (collection, clauses) {
|
|
return {
|
|
type: "insert",
|
|
collection: collection,
|
|
clauses: assureArray(clauses)
|
|
};
|
|
},
|
|
update: function (collection, clauses) {
|
|
return {
|
|
type: "insert",
|
|
collection: collection,
|
|
clauses: assureArray(clauses)
|
|
};
|
|
},
|
|
selectFrom: function (collection, clauses) {
|
|
return {
|
|
type: "select",
|
|
collection: collection,
|
|
clauses: assureArray(clauses)
|
|
};
|
|
},
|
|
deleteFrom: function (collection, clauses) {
|
|
return {
|
|
type: "delete",
|
|
collection: collection,
|
|
clauses: assureArray(clauses)
|
|
};
|
|
},
|
|
moreThan: function (value) {
|
|
return {
|
|
type: "moreThan",
|
|
value: value
|
|
};
|
|
},
|
|
lessThan: function (value) {
|
|
return {
|
|
type: "lessThan",
|
|
value: value
|
|
};
|
|
},
|
|
equals: function (value) {
|
|
return {
|
|
type: "equals",
|
|
value: value
|
|
};
|
|
},
|
|
not: function (value) {
|
|
return {
|
|
type: "not",
|
|
value: value
|
|
};
|
|
},
|
|
where: function (conditions) {
|
|
return {
|
|
type: "where",
|
|
conditions: conditions
|
|
};
|
|
},
|
|
collapse: function (reducers) {
|
|
return {
|
|
type: "collapse",
|
|
fields: null,
|
|
reducers: reducers
|
|
};
|
|
},
|
|
collapseBy: function (fields, reducers) {
|
|
return {
|
|
type: "collapse",
|
|
fields: assureArray(fields),
|
|
reducers: reducers
|
|
};
|
|
},
|
|
item: function (item) {
|
|
return {
|
|
type: "items",
|
|
items: [ item ]
|
|
};
|
|
},
|
|
items: function (items) {
|
|
return {
|
|
type: "items",
|
|
items: items
|
|
};
|
|
},
|
|
set: function (properties) {
|
|
return {
|
|
type: "set",
|
|
properties: properties
|
|
};
|
|
},
|
|
anyOf: function (options) {
|
|
return {
|
|
type: "anyOf",
|
|
options: options
|
|
};
|
|
},
|
|
allOf: function (options) {
|
|
return {
|
|
type: "allOf",
|
|
options: options
|
|
};
|
|
},
|
|
parameter: function (name) {
|
|
return {
|
|
type: "parameter",
|
|
name: name
|
|
};
|
|
},
|
|
average: average,
|
|
count: count,
|
|
sum: sum
|
|
};
|
|
|
|
function generateGetter(propertyPath) {
|
|
assert(propertyPath != null);
|
|
|
|
let segments = (Array.isArray(propertyPath))
|
|
? propertyPath
|
|
: propertyPath.split(".");
|
|
|
|
let propertyGetters = segments
|
|
.map((segment) => {
|
|
// FIXME: Escape!
|
|
// TODO: Can this be further optimized by using regular dot properties where safely possible?
|
|
return `["${segment}"]`;
|
|
})
|
|
.join("");
|
|
|
|
return new Function("item", `
|
|
return item${propertyGetters};
|
|
`);
|
|
}
|
|
|
|
function average(propertyPath) {
|
|
let getter = generateGetter(propertyPath);
|
|
|
|
return {
|
|
onValue: (total, item, _i) => total + getter(item),
|
|
onEnd: (total, count) => total / count
|
|
};
|
|
}
|
|
|
|
function count() {
|
|
return (total) => total + 1;
|
|
}
|
|
|
|
function sum(propertyPath) {
|
|
let getter = generateGetter(propertyPath);
|
|
|
|
return (total, item, _i) => total + getter(item);
|
|
}
|
|
|