/** * 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}`); } }