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

"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);
}