trilogy
Version:
TypeScript SQLite layer with support for both native C++ & pure JavaScript drivers.
155 lines (154 loc) • 5.21 kB
JavaScript
;
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();
}