api-v1/core/db/jsonQueryExecutor.js

108 lines
2.2 KiB
JavaScript

/**
* Execute a JSON-based query using Knex
*
* Supported ops:
* SELECT | INSERT | UPDATE | DELETE
*/
export default function executeJsonQuery(knex, query) {
const {
op,
table,
columns,
values,
where,
orderBy,
limit,
offset
} = query;
if (!op || !table) {
throw new Error('JSON query must include "op" and "table"');
}
let qb;
switch (op) {
// ----------------------------------
// SELECT
// ----------------------------------
case 'SELECT': {
qb = knex(table);
if (Array.isArray(columns) && columns.length > 0) {
qb.select(columns);
} else {
qb.select('*');
}
if (where && typeof where === 'object') {
qb.where(where);
}
if (Array.isArray(orderBy)) {
for (const { column, direction } of orderBy) {
qb.orderBy(column, direction || 'asc');
}
}
if (Number.isInteger(limit)) {
qb.limit(limit);
}
if (Number.isInteger(offset)) {
qb.offset(offset);
}
return qb;
}
// ----------------------------------
// INSERT
// ----------------------------------
case 'INSERT': {
if (!values || typeof values !== 'object') {
throw new Error('INSERT requires "values"');
}
return knex(table)
.insert(values)
.returning(columns || '*');
}
// ----------------------------------
// UPDATE
// ----------------------------------
case 'UPDATE': {
if (!values || typeof values !== 'object') {
throw new Error('UPDATE requires "values"');
}
if (!where || typeof where !== 'object') {
throw new Error('UPDATE without WHERE is not allowed');
}
return knex(table)
.where(where)
.update(values)
.returning(columns || '*');
}
// ----------------------------------
// DELETE
// ----------------------------------
case 'DELETE': {
if (!where || typeof where !== 'object') {
throw new Error('DELETE without WHERE is not allowed');
}
return knex(table)
.where(where)
.del();
}
default:
throw new Error(`Unsupported JSON op: ${op}`);
}
}