n1-sql
Version:
106 lines (92 loc) • 2.51 kB
JavaScript
;
var Immutable = require('immutable');
var setSingularState = require('./util').setSingularState;
var parseColumn = require('./util').parseColumn;
var toSqlColumn = require('./util').toSqlColumn;
var COMP_OP = 'compOp';
module.exports.callWhereBuilder = function (f, state) {
var sql;
if (typeof f === "function") {
var jc = createInitialCtxt(state);
var jb = f(whereBuilder(jc));
if (jb === undefined) {
throw '"where" needs to return a where function';
}
sql = jb._toSql();
} else if (typeof f === "string") {
sql = f;
} else {
throw 'Unknown where definition "' + f + '".';
}
return state.updateIn(['where'], function (l) {
return l.push(sql);
});
};
function createInitialCtxt(state) {
return Immutable.Map({
cols: Immutable.List(),
state: state
});
}
function whereBuilder(ctxt) {
function toSql() {
var cols = ctxt.get('cols').toJS();
if (cols.length === 0 || cols.length > 2) {
throw 'Where clause needs at least one and max. two columns, but found ' + cols.length + '.';
}
var left = cols[0];
var right = cols[1];
var compOp = ctxt.get(COMP_OP);
if (!compOp) {
throw 'Missing compare operation ';
}
var a = [toSqlColumn(left), compOp];
var value = ctxt.get('value');
if (value) {
a.push(value);
} else if (right) {
a.push(toSqlColumn(right));
} else {
throw 'Missing right hand side of where clause';
}
if (ctxt.get('partialSql')) {
a.unshift(ctxt.get('partialSql'));
}
return a.join(' ');
}
function compOp(sql) {
return function (v) {
var c = setSingularState(ctxt, COMP_OP, sql);
if (v) {
c = setSingularState(c, 'value', v);
}
return whereBuilder(c);
};
}
function logicOp(op) {
return function () {
var sql = toSql() + ' ' + op + ' ';
var p = ctxt.get('partialSql');
var c = createInitialCtxt(ctxt.get('state')).setIn(['partialSql'], p ? p + ' ' + sql : sql);
return whereBuilder(c);
};
}
return {
column: function column(colId) {
var c = ctxt.updateIn(['cols'], function (l) {
var ch = parseColumn(colId, ctxt.get('state'));
return l.push(ch);
});
return whereBuilder(c);
},
gt: compOp('>'),
ge: compOp('>='),
eq: compOp('='),
neq: compOp('!='),
lt: compOp('<'),
le: compOp('<='),
or: logicOp('OR'),
and: logicOp('AND'),
_toSql: toSql
};
}