UNPKG

n1-sql

Version:
95 lines (84 loc) 2.34 kB
'use strict'; var Immutable = require('immutable'); var parseColumn = require('./util').parseColumn; var toSqlColumn = require('./util').toSqlColumn; module.exports.callJoinBuilder = function (f, state) { var sql; if (typeof f === "function") { var jc = createInitialCtxt(state); var jb = f(joinBuilder(jc)); if (!jb) { throw '"join" needs to return a join function'; } sql = jb._toSql(); } else if (typeof f === 'string') { sql = f; } else { throw 'Unknown join definition "' + f + '".'; } return state.updateIn(['join'], function (l) { return l.push(sql); }); }; function createInitialCtxt(state) { return Immutable.Map({ cols: Immutable.List(), joinOps: Immutable.List(), state: state }); } function joinBuilder(ctxt) { //"orgA.t" dp1 JOIN "orgB.t" dp2 ON dp1.id = dp2.id function toSql() { var cols = ctxt.get('cols').toJS(); if (cols.length < 2) { throw 'Join needs at least two columns, but found only ' + cols.length + '.'; } var joinOps = ctxt.get('joinOps').toJS(); if (cols.length !== joinOps.length + 1) { throw 'Unexpected number of join tables and associated join operations'; } var ra = [toSqlTable(cols[0])]; var i; for (i = 1; i < cols.length; i++) { ra.push('JOIN'); ra.push(toSqlTable(cols[i])); ra.push('ON'); ra.push(toSqlJoinOp(joinOps[i - 1], cols[i - 1], cols[i])); } return ra.join(' '); } function toSqlTable(t) { var s = t.table; if (t.tableAlias) { s += ' ' + t.tableAlias; } return s; } function toSqlJoinOp(joinOp, left, right) { return [toSqlColumn(left), ' ', joinOp, ' ', toSqlColumn(right)].join(''); } function joinOp(op) { return function () { var c = ctxt.updateIn(['joinOps'], function (l) { return l.push(op); }); return joinBuilder(c); }; } return { column: function column(colId) { var c = ctxt.updateIn(['cols'], function (l) { var ch = parseColumn(colId, ctxt.get('state')); var js = ctxt.get('joinOps').size; if (js !== l.size) { throw 'Column needs to be first or follow a join operator'; } return l.push(ch); }); return joinBuilder(c); }, eq: joinOp('='), _toSql: toSql }; }