UNPKG

trilogy

Version:

TypeScript SQLite layer with support for both native C++ & pure JavaScript drivers.

155 lines (154 loc) 5.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findKey = exports.runQuery = exports.normalizeCriteria = exports.isValidWhere = exports.isWhereMultiple = exports.isWhereTuple = exports.buildWhere = exports.buildOrder = exports.parseResponse = void 0; const schema_helpers_1 = require("./schema-helpers"); const sqljs_handler_1 = require("./sqljs-handler"); const util = require("./util"); const hooks_1 = require("./hooks"); const HasTableSubstring = `from sqlite_master where type = 'table'`; function parseResponse(contents) { if (!contents || !contents.length) return []; const [{ columns, values }] = contents; const results = []; for (let i = 0; i < values.length; i++) { const line = {}; for (let j = 0; j < columns.length; j++) { line[columns[j]] = values[i][j]; } results.push(line); } return results; } exports.parseResponse = parseResponse; function buildOrder(partial, order) { if (util.isString(order)) { if (order === 'random') { return partial.orderByRaw('RANDOM()'); } return partial.orderBy(order); } if (Array.isArray(order)) { if (order.length === 1) { return partial.orderBy(order[0]); } else if (order.length === 2) { return partial.orderBy(order[0], order[1]); } } return partial; } exports.buildOrder = buildOrder; function buildWhere(partial, where, inner) { if (where === undefined) return partial; if (isWhereTuple(where)) { const i = where.length - 1; const cast = where; cast[i] = schema_helpers_1.castValue(where[i]); if (cast.length === 2) { return partial.where(...cast); } else if (cast.length === 3) { return partial.where(...cast); } } if (!inner && isWhereMultiple(where)) { return where.reduce((accumulator, clause) => { return buildWhere(accumulator, clause, true); }, partial); } if (util.isObject(where)) { return partial.where(util.mapObj(where, schema_helpers_1.castValue)); } util.invariant(false, `invalid where clause type: '${typeof where}'`); } exports.buildWhere = buildWhere; function isWhereTuple(where) { return (Array.isArray(where) && (where.length === 2 || where.length === 3) && typeof where[0] === 'string'); } exports.isWhereTuple = isWhereTuple; function isWhereMultiple(where) { return (Array.isArray(where) && where.every(item => isWhereTuple(item) || util.isObject(item))); } exports.isWhereMultiple = isWhereMultiple; function isValidWhere(where) { return (isWhereTuple(where) || util.isObject(where) || isWhereMultiple(where)); } exports.isValidWhere = isValidWhere; function normalizeCriteria(where) { if (isWhereTuple(where)) { return (where.length === 2 ? { [where[0]]: where[1] } : where); } if (isWhereMultiple(where)) { return where.map(rule => normalizeCriteria(rule)); } if (util.isObject(where)) { return where; } util.invariant(false, `invalid criteria: ${where}`); } exports.normalizeCriteria = normalizeCriteria; async function runQuery(instance, query, options = {}) { var _a; const asString = query.toString(); const action = getQueryAction(asString); if (options.model) { await options.model._callHook(hooks_1.Hook.OnQuery, [asString, options.internal]); } if (instance.isNative) { if (options.needResponse) return query; const res = await query; if (util.isNumber(res)) return res; return (_a = res === null || res === void 0 ? void 0 : res.length) !== null && _a !== void 0 ? _a : 0; } // tslint:disable-next-line:await-promise const db = await instance.pool.acquire(); let response; if (options.needResponse) { response = parseResponse(db.exec(asString)); if (asString.toLowerCase().includes(HasTableSubstring)) { response = Boolean(response.length); } } else { db.run(asString); if (['insert', 'update', 'delete'].includes(action)) { response = db.getRowsModified(); } } sqljs_handler_1.writeDatabase(instance, db); instance.pool.release(db); return response; } exports.runQuery = runQuery; function findKey(schema) { let key = ''; let hasIncrements = false; const keys = Object.keys(schema); for (const name of keys) { const props = schema[name]; if (props === 'increments' || props.type === 'increments') { key = name; hasIncrements = true; break; } else if (props.primary || props.unique) { key = name; } } return { key, hasIncrements }; } exports.findKey = findKey; function getQueryAction(str) { return str.split(' ', 1)[0].toLowerCase(); }