UNPKG

extra-sql

Version:

SQL is designed for managing or stream processing data in an RDBMS.

234 lines (228 loc) 8.65 kB
'use strict'; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var _build = {}; var hasRequired_build; function require_build () { if (hasRequired_build) return _build; hasRequired_build = 1; Object.defineProperty(_build, "__esModule", { value: true }); _build.deleteData = _build.insertIntoData = _build.selectData = _build.updateData = _build.createTableData = _build.matchTsquery = _build.selectTsquery = _build.tableExists = _build.setupTable = _build.setupTableIndex = _build.insertIntoStream = _build.insertInto = _build.createView = _build.createIndex = _build.createTable = _build.OPERAND_COUNT = _build.OPERATORS = void 0; _build.OPERATORS = new Set([ '+', '-', '*', '/', '%', '&', '|', '^', '=', '>', '<', '>=', '<=', '<>', '+=', '-=', '*=', '/=', '%=', '&=', '^=', '|=', 'ALL', 'AND', 'ANY', 'BETWEEN', 'EXISTS', 'IN', 'LIKE', 'NOT', 'OR', 'SOME' ]); _build.OPERAND_COUNT = new Map([ ['+', 2], ['-', 2], ['*', 2], ['/', 2], ['%', 2], ['&', 2], ['|', 2], ['^', 2], ['=', 2], ['>', 2], ['<', 2], ['>=', 2], ['<=', 2], ['<>', 2], ['+=', 2], ['-=', 2], ['*=', 2], ['/=', 2], ['%=', 2], ['&=', 2], ['^=', 2], ['|=', 2], ['ALL', 2], ['AND', 2], ['ANY', 2], ['BETWEEN', 3], ['EXISTS', 1], ['IN', 2], ['LIKE', 2], ['NOT', 1], ['OR', 2], ['SOME', 2] ]); function _format(obj, fmt, sep, i = 0, val) { const a = []; const ve = Array.isArray(val); i = i || (ve ? val.length : 0); for (const k in obj) { const v = obj[k]; a.push(fmt.replace(/%k/g, k).replace(/%v/g, String(v)).replace(/%i/g, String(i++))); if (ve && val) val.push(v); } return a.join(sep); } function _array(x) { if (Array.isArray(x)) return x; if (x == null || typeof x === 'string' || typeof x[Symbol.iterator] !== 'function') return [x]; return Array.from(x); } function addRow(row, acc = '', i = 0) { if (i === 0) { for (const k in row) acc += `"${k}", `; acc = acc.endsWith(', ') ? acc.substring(0, acc.length - 2) : acc; acc += ') VALUES\n('; } for (const k in row) acc += row[k] == null ? 'NULL, ' : `$$${row[k]}$$, `; acc = acc.endsWith(', ') ? acc.substring(0, acc.length - 2) : acc; acc += '),\n('; return acc; } function createTable(name, cols, opt = {}, acc = '') { acc += `CREATE TABLE IF NOT EXISTS "${name}" (`; for (const k in cols) acc += `"${k}" ${cols[k]}, `; if (opt.pk) acc += `PRIMARY KEY("${opt.pk}"), `; return acc.replace(/, $/, '') + `);\n`; } _build.createTable = createTable; function createIndex(name, table, expr, opt = {}, acc = '') { acc += `CREATE INDEX IF NOT EXISTS "${name}" ON "${table}" `; if (opt.method) acc += `USING ${opt.method} `; return acc + `(${expr});\n`; } _build.createIndex = createIndex; function createView(name, query, opt = null, acc = '') { acc += `CREATE OR REPLACE VIEW "${name}" AS ${query};\n`; return acc; } _build.createView = createView; function insertInto(table, rows, opt = {}, acc = '') { let i = -1; acc += `INSERT INTO "${table}" (`; for (const val of rows) acc = addRow(val, acc, ++i); acc = acc.replace(/\),\n\($/, '') + ')'; if (opt.pk) acc += `\nON CONFLICT ("${opt.pk}") DO NOTHING`; return acc + ';\n'; } _build.insertInto = insertInto; function insertIntoStream(table, stream, opt = {}, acc = '') { let i = -1; acc += `INSERT INTO "${table}" (`; return new Promise((resolve, reject) => { stream.on('error', reject); stream.on('data', (row) => { acc = addRow(row, acc, ++i); }); stream.on('end', () => { acc = acc.replace(/\),\n\($/, '') + ')'; if (opt.pk) acc += `\nON CONFLICT ("${opt.pk}") DO NOTHING`; resolve(acc + ';\n'); }); }); } _build.insertIntoStream = insertIntoStream; insertInto.stream = insertIntoStream; function tsvector(cols) { let acc = ''; for (const k in cols) { if (cols[k]) acc += `setweight(to_tsvector('english', "${k}"), '${cols[k]}')||`; } return acc.replace(/\|\|$/, ''); } function setupTableIndex(table, cols, opt = {}, acc = '') { if (opt.tsvector) { const tv = tsvector(opt.tsvector); acc += createView(table + '_tsvector', `SELECT *, ${tv} AS "tsvector" FROM "${table}"`); if (opt.index) acc += createIndex(table + '_tsvector_idx', table, `(${tv})`, { method: 'GIN' }); } if (opt.index) { for (const k in cols) { if (cols[k] == null || k === opt.pk) continue; const knam = k.replace(/\W+/g, '_').toLowerCase(); acc += createIndex(`${table}_${knam}_idx`, table, `"${k}"`); } } return acc; } _build.setupTableIndex = setupTableIndex; function setupTable(name, cols, rows = null, opt = {}, acc = '') { acc = createTable(name, cols, opt, acc); if (rows) acc = insertInto(name, rows, opt, acc); return setupTableIndex(name, cols, opt, acc); } _build.setupTable = setupTable; setupTable.index = setupTableIndex; function tableExists(name) { return `SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='${name}');\n`; } _build.tableExists = tableExists; function selectTsquery(table, query, tsv = '"tsvector"', opt = {}) { const col = opt.columns || '*'; const nrm = opt.normalization || 0; let acc = `SELECT ${col} FROM "${table}" WHERE ${tsv} @@ plainto_tsquery('${query}')`; if (opt.order) acc += ` ORDER BY ts_rank(${tsv}, plainto_tsquery('${query}'), ${nrm}) DESC`; if (opt.limit) acc += ` LIMIT ${opt.limit}`; acc += `;\n`; return acc; } _build.selectTsquery = selectTsquery; function matchTsquery(table, words, tsv = '"tsvector"', opt = {}) { const col = opt.columns || '*'; const nrm = opt.normalization || 0; let acc = ''; for (let i = words.length; i > 0; i--) { const qry = words.slice(0, i).join(' ').replace(/([\'\"])/g, '$1$1'); acc += `SELECT ${col}, '${i}'::INT AS "matchTsquery" FROM "${table}"`; acc += ` WHERE ${tsv} @@ plainto_tsquery('${qry}')`; if (opt.order) acc += ` ORDER BY ts_rank(${tsv}, plainto_tsquery('${qry}'), ${nrm}) DESC`; acc += ' UNION ALL\n'; } acc = acc.substring(0, acc.length - 11); if (opt.limit) acc += ` LIMIT ${opt.limit}`; acc += ';\n'; return acc; } _build.matchTsquery = matchTsquery; function createTableData(table, cols, pkeys) { return { query: `CREATE TABLE IF NOT EXISTS "${table}" (` + `${_format(cols, '"%k" %v', ', ')}` + (pkeys ? `, PRIMARY KEY(${_format(_array(pkeys), '"%v"', ', ')})` : ``) + `);`, data: [] }; } _build.createTableData = createTableData; function updateData(table, set, where, op = '=', sep = 'AND') { const par = []; const setStr = _format(set || {}, '"%k" = $%i', ', ', 1, par); const exp = _format(where || {}, `"%k" ${op} $%i`, ` ${sep} `, par.length + 1, par); return { query: `UPDATE "${table}" SET ${setStr}${exp ? ' WHERE ' + exp : ''};`, data: par }; } _build.updateData = updateData; function selectData(tab, whr, op = '=', sep = 'AND') { const par = []; const exp = _format(whr || {}, `"%k" ${op} $%i`, ` ${sep} `, 1, par); return { query: `SELECT * FROM "${tab}"${exp ? ' WHERE ' + exp : ''};`, data: par }; } _build.selectData = selectData; function insertIntoData(table, rows) { const par = []; const into = _format(rows[0] || {}, '"%k"', ', ', 1, par); const rowsStr = _format(par, '$%i', ', ', 1); return { query: `INSERT INTO "${table}" (${into}) VALUES (${rowsStr});`, data: par }; } _build.insertIntoData = insertIntoData; function deleteData(table, where, op = '=', sep = 'AND') { const par = []; const exp = _format(where || {}, `"%k" ${op} $%i`, ` ${sep} `, 1, par); return { query: `DELETE FROM "${table}"${exp ? ' WHERE ' + exp : ''};`, data: par }; } _build.deleteData = deleteData; return _build; } var _buildExports = require_build(); var index = /*@__PURE__*/getDefaultExportFromCjs(_buildExports); module.exports = index;