export function query(sql, ...args) { validateQuery(sql, ...args); return buildQuery(sql, ...args); } // Allow for slightly more complex parameter substitution. // Instances of "???" will be replaced by the same number of comma-separated // question marks as items in the corresponding nested parateter array // eg. buildQuery("SELECT (???) FROM ?", [["col1", "col2"], "table1"]) // would output: ["SELECT (?, ?) FROM ?", ["col1", "col2", "table1"]] export function buildQuery(sql, ...args) { const parts = sql.split("???"); const subParamLengths = args .filter(Array.isArray) .map((a) => a.length); if (parts.length !== subParamLengths.length + 1) { throw new PawSQLiteError("Unable to build query: sub-" + "paramters do not match sub-paramters in query"); } const newQuery = parts.reduce((p1, p2, i) => { const length = subParamLengths[i - 1]; return p1 + new Array(length).fill("?").join(", ") + p2; }); const flatParams = args.reduce((acc, v) => { if (Array.isArray(v)) { Array.prototype.push.apply(acc, v); } else { acc.push(v); } return acc; }, []); return [newQuery, ...flatParams]; } export function validateQuery(sql, ...args) { const reg = /^\s*(BEGIN|END|COMMIT|ROLLBACK)(?:[^A-Z]|$)/i; const match = reg.exec(sql); if (match) { const statement = match[1].toUpperCase(); throw new PawSQLiteError("Manually managing transactions is " + "forbidden. Found: \"" + statement + "\" statement."); } }