From 43d8eb0d15ad7dfc9859d12608b6846db8308d9a Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 8 May 2019 16:42:58 +0300 Subject: [PATCH] VALUES () tables, RETURNING and export select_builder --- select-builder-pgsql.js | 52 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/select-builder-pgsql.js b/select-builder-pgsql.js index 983001f..042c819 100644 --- a/select-builder-pgsql.js +++ b/select-builder-pgsql.js @@ -1,5 +1,6 @@ // Простенький "селект билдер" по мотивам MediaWiki-овского, успешно юзаю подобный в PHP уже лет 8 // (c) Виталий Филиппов, 2019 +// Версия 2019-05-08 // В PHP, правда, прикольнее - там в массиве можно смешивать строковые и численные ключи, // благодаря чему можно писать $where = [ 't1.a=t2.a', 't2.b' => [ 1, 2, 3 ] ] @@ -21,7 +22,7 @@ const MS_ROW = 2; const MS_COL = 4; const MS_VALUE = 6; -function selectBuilder(tables, fields, where, options) +function select_builder(tables, fields, where, options) { let sql = 'SELECT ', bind = []; if (fields instanceof Array) @@ -66,8 +67,25 @@ function selectBuilder(tables, fields, where, options) } else { + sql += ' ' + tables[k][0].toUpperCase() + ' JOIN '; + let t = tables[k][1]; + if (t instanceof Pg_Values) + { + sql += '(VALUES '; + let i = 0; + for (const row of t.rows) + { + sql += (i > 0 ? ', (' : '(') + t.keys.map(() => '$'+(++i)).join(', ')+')'; + bind.push.apply(bind, t.keys.map(k => row[k])); + } + sql += ') AS '+k+'('+t.keys.join(', ')+')'; + } + else + { + sql += t + ' ' + k; + } const on = whereBuilder(tables[k][2]); - sql += ' ' + tables[k][0].toUpperCase() + ' JOIN ' + tables[k][1] + ' ' + k + ' ON ' + (on[0] || '1=1'); + sql += ' ON ' + (on[0] || '1=1'); bind.push.apply(bind, on[1]); } } @@ -172,7 +190,7 @@ function _inline(sql, bind) // dbh = node-postgres.Client async function select(dbh, tables, fields, where, options, format) { - let [ sql, bind ] = selectBuilder(tables, fields, where, options); + let [ sql, bind ] = select_builder(tables, fields, where, options); //console.log(_inline(sql, bind)); let data = await dbh.query(_positional(sql), bind); if ((format & MS_LIST) || (format & MS_COL)) @@ -186,7 +204,7 @@ async function select(dbh, tables, fields, where, options, format) return data; } -async function insert(dbh, table, rows) +async function insert(dbh, table, rows, options) { if (!(rows instanceof Array)) { @@ -205,7 +223,15 @@ async function insert(dbh, table, rows) sql += (i > 0 ? ', (' : '(') + keys.map(() => '$'+(++i)).join(', ')+')'; bind.push.apply(bind, keys.map(k => row[k])); } - return await dbh.query(sql, bind); + if (options.returning) + { + sql += ' returning '+options.returning; + return (await dbh.query(sql, bind)).rows; + } + else + { + return await dbh.query(sql, bind); + } } async function _delete(dbh, table, where) @@ -224,11 +250,27 @@ async function update(dbh, table, set, where) return await dbh.execute(_positional(sql), bind); } +function values(rows) +{ + return new Pg_Values(Object.keys(rows[0]), rows); +} + +class Pg_Values +{ + constructor(keys, rows) + { + this.keys = keys; + this.rows = rows; + } +} + module.exports = { + select_builder, select, insert, delete: _delete, update, + values, MS_HASH, MS_LIST, MS_ROW,