@cocalc/database
Version:
CoCalc: code for working with our PostgreSQL database
81 lines • 3.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.userGetQueryFilter = exports.queryIsCmp = void 0;
const schema_1 = require("@cocalc/util/schema");
const util_1 = require("../postgres/schema/util");
const misc_1 = require("@cocalc/util/misc");
function queryIsCmp(val) {
if (!(0, misc_1.is_object)(val)) {
return false;
}
const keys = Object.keys(val);
if (keys.length != 1) {
return false;
}
if (schema_1.OPERATORS.includes(keys[0])) {
return keys[0];
}
return false;
}
exports.queryIsCmp = queryIsCmp;
// Additional where object condition imposed by user's get query
function userGetQueryFilter(user_query, client_query) {
if (client_query.get == null) {
// no get queries allowed (this is mainly to make typescript happy below.)
return {};
}
// If the schema lists the value in a get query as 'null', then we remove it;
// nulls means it was only there to be used by the initial where filter
// part of the query.
for (const field in client_query.get.fields) {
const val = client_query.get.fields[field];
if (val === "null") {
delete user_query[field];
}
}
const where = {};
for (const field in user_query) {
const val = user_query[field];
if (val == null)
continue;
if (client_query.get.remove_from_query != null &&
client_query.get.remove_from_query.includes(field)) {
// do not include any field that explicitly excluded from the query
continue;
}
if (!queryIsCmp(val)) {
where[`${(0, util_1.quoteField)(field)} = $`] = val;
continue;
}
// It's a comparison query, e.g., {field : {'<=' : 5}}
for (let op in val) {
const v = val[op];
if (op === "==") {
// not in SQL, but natural for our clients to use it
op = "=";
}
if (op.toLowerCase().startsWith("is")) {
// hack to use same where format for now, since $ replacement
// doesn't work for "foo IS ...".
where[`${(0, util_1.quoteField)(field)} ${op} ${(0, schema_1.isToOperand)(v)}`] = true;
}
else if ((0, misc_1.is_object)(v) &&
v["relative_time"] != null &&
schema_1.SUPPORTED_TIME_UNITS.includes(v["unit"])) {
const time = parseInt(v["relative_time"]);
// ${v["unit"]} is safe because we checked that it is in SUPPORTED_TIME_UNITS above.
// Also see https://stackoverflow.com/questions/7796657/using-a-variable-period-in-an-interval-in-postgres
// for how we do this "interval" arithmetic.
const int = `NOW() + $ * INTERVAL '1 ${v["unit"]}'`;
const expr = `${(0, util_1.quoteField)(field)} ${op} (${int})`;
where[expr] = time;
}
else {
where[`${(0, util_1.quoteField)(field)} ${op} $`] = v;
}
}
}
return where;
}
exports.userGetQueryFilter = userGetQueryFilter;
//# sourceMappingURL=user-get-query.js.map