VALUES () tables, RETURNING and export select_builder

master
Vitaliy Filippov 2019-05-08 16:42:58 +03:00
parent 6b4ddbd808
commit 43d8eb0d15
1 changed files with 47 additions and 5 deletions

View File

@ -1,5 +1,6 @@
// Простенький "селект билдер" по мотивам MediaWiki-овского, успешно юзаю подобный в PHP уже лет 8 // Простенький "селект билдер" по мотивам MediaWiki-овского, успешно юзаю подобный в PHP уже лет 8
// (c) Виталий Филиппов, 2019 // (c) Виталий Филиппов, 2019
// Версия 2019-05-08
// В PHP, правда, прикольнее - там в массиве можно смешивать строковые и численные ключи, // В PHP, правда, прикольнее - там в массиве можно смешивать строковые и численные ключи,
// благодаря чему можно писать $where = [ 't1.a=t2.a', 't2.b' => [ 1, 2, 3 ] ] // благодаря чему можно писать $where = [ 't1.a=t2.a', 't2.b' => [ 1, 2, 3 ] ]
@ -21,7 +22,7 @@ const MS_ROW = 2;
const MS_COL = 4; const MS_COL = 4;
const MS_VALUE = 6; const MS_VALUE = 6;
function selectBuilder(tables, fields, where, options) function select_builder(tables, fields, where, options)
{ {
let sql = 'SELECT ', bind = []; let sql = 'SELECT ', bind = [];
if (fields instanceof Array) if (fields instanceof Array)
@ -66,8 +67,25 @@ function selectBuilder(tables, fields, where, options)
} }
else 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]); 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]); bind.push.apply(bind, on[1]);
} }
} }
@ -172,7 +190,7 @@ function _inline(sql, bind)
// dbh = node-postgres.Client // dbh = node-postgres.Client
async function select(dbh, tables, fields, where, options, format) 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)); //console.log(_inline(sql, bind));
let data = await dbh.query(_positional(sql), bind); let data = await dbh.query(_positional(sql), bind);
if ((format & MS_LIST) || (format & MS_COL)) if ((format & MS_LIST) || (format & MS_COL))
@ -186,7 +204,7 @@ async function select(dbh, tables, fields, where, options, format)
return data; return data;
} }
async function insert(dbh, table, rows) async function insert(dbh, table, rows, options)
{ {
if (!(rows instanceof Array)) if (!(rows instanceof Array))
{ {
@ -205,7 +223,15 @@ async function insert(dbh, table, rows)
sql += (i > 0 ? ', (' : '(') + keys.map(() => '$'+(++i)).join(', ')+')'; sql += (i > 0 ? ', (' : '(') + keys.map(() => '$'+(++i)).join(', ')+')';
bind.push.apply(bind, keys.map(k => row[k])); 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) async function _delete(dbh, table, where)
@ -224,11 +250,27 @@ async function update(dbh, table, set, where)
return await dbh.execute(_positional(sql), bind); 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 = { module.exports = {
select_builder,
select, select,
insert, insert,
delete: _delete, delete: _delete,
update, update,
values,
MS_HASH, MS_HASH,
MS_LIST, MS_LIST,
MS_ROW, MS_ROW,