miridoo-js-orm
Version:
miridoo javascript orm for database
331 lines (303 loc) • 11.3 kB
JavaScript
var QueryBuider = function(name, alias){
var self = this;
this.selectedColumn = [];
this.whereClause = [];
this.updateSetter = {};
this.havingClause = [];
this.fromOtherTable = [];
this.tpsparams = {};
this.params = {};
this.countParams = 0;
this.groupBy = [];
this.orderBy = [];
this.limitBy = {use : false, skip : 0, take : 0};
this.operation = '';
this.tableName = name;
this.tableAliasName = alias || name;
this.$functionsClass = null;
this.$functionFileLink = __dirname+'/Functions';
this.operator = {
'<=' : '<=',
'>=' : '>=',
'=' : '=',
'<' : '<',
'>' : '>',
'<>' : '<>',
'!=' : '!=',
'and' : 'AND',
'or' : 'OR',
'not' : 'NOT',
'in' : 'IN',
'isnull' : 'IS NULL',
'isnotnull' : 'IS NOT NULL',
'notin' : 'NOT IN',
'like' : 'LIKE',
'regexp' : 'REGEXP',
'notlike' : 'NOT LIKE',
'between' : 'BETWEEN',
'notbetween' : 'NOT BETWEEN',
'ilike' : 'ILIKE'
};
this.$graft = function(r){
r.tableName = this.tableName;
r.tableAliasName = this.tableAliasName;
return r;
};
this.$builder = null;
this.getRefName = function(arguments){
return (typeof arguments == 'string')? this.tableAliasName+'.'+arguments : Array.from(arguments).map(function(value, index){
if(typeof value != 'string' || value.trim() == '')
return self.tableAliasName+'.'+value;
else if(!(/[^a-zA-Z0-9_$]/.test(value)))
return value;
return '"'+(value.replace(/^\+/, ''))+'"';
});
};
this.$functions = function(){
if(!this.$functionsClass)
this.$functionsClass = require(this.$functionFileLink);
return this.$graft((new this.$functionsClass()));
};
this.only = function(){
for(var i in arguments){
if(typeof arguments[i] == 'string')
this.selectedColumn.push(this.getRefName(arguments[i]));
else if(typeof arguments[i] == 'function'){
var r = this.$functions();
arguments[i](r);
this.selectedColumn = this.selectedColumn.concat(r.toArray());
}
}
return this;
};
//WHERE CLAUSE
this.all = function(){
this.cleanQuery();
return this.get();
};
this.find = function(){
this.cleanQuery();
return this.whereIn.apply(this, Array.from(arguments).unshift(this.$builder.$primaryColumn)).get();
};
this.$addIn = function(arguments){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
var args = Array.from(arguments);
var col = args[0], values = args.slice(1);
var params = [];
values.map(function(v, index){
if(typeof v == 'object'){
for(var i in v){
var k = self.$getParamsKey(v[i]);
params.push(':'+k);
}
}else{
var k = self.$getParamsKey(v);
params.push(':'+k);
}
});
return {col : col, params : params};
};
this.$addWhere = function(arguments){
var args = Array.from(arguments);
if(args.length > 1) {
if (args.length == 2) {
args.push(args[1]);
args[1] = '=';
}
args[0] = this.tableAliasName+'.'+args[0];
args[1] = this.operator[args[1]];
var key = this.$getParamsKey(args[2]);
args[2] = ':'+key;
this.whereClause.push(args.join(' '));
}else{
var r = new QueryBuider();
r.countParams = this.countParams;
args[0](r);
this.whereClause.push('('+r.whereClause.join(' ')+')');
for(var i in r.params)
this.params[i] = r.params[i];
this.countParams = r.countParams;
}
return this;
};
this.$getParamsKey = function(value){
this.countParams++;
var key = 'P'+this.countParams;
this.params[key] = value;
return key;
};
this.where = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
return this.$addWhere(arguments);
};
this.whereIn = function(){
var r = this.$addIn(arguments);
this.whereClause.push(this.getRefName(r.col)+' '+this.operator['in']+' ('+r.params.join(',')+')');
return this;
};
this.whereNotIn = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
var r = this.$addIn(arguments);
this.whereClause.push(this.getRefName(r.col)+' '+this.operator['notin']+' ('+r.params.join(',')+')');
return this;
};
this.whereIsNull = function(col){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
this.whereClause.push(this.getRefName(col)+' '+this.operator['isnull']);
return this;
};
this.whereIsNotNull = function(col){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
this.whereClause.push(this.getRefName(col)+' '+this.operator['isnotnull']);
return this;
};
this.orWhere = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['or']);
return this.$addWhere(arguments);
};
this.orWhereIn = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['or']);
return this.whereIn.apply(this, arguments);
};
this.orWhereNotIn = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['or']);
return this.whereNotIn.apply(this, arguments);
};
this.orWhereIsNull = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['or']);
return this.whereIsNull.apply(this, arguments);
};
this.orWhereIsNotNull = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['or']);
return this.whereIsNotNull.apply(this, arguments);
};
this.whereNotIn = function(){
if(this.whereClause.length > 0) this.whereClause.push(this.operator['and']);
var r = this.$addIn(arguments);
this.whereClause.push(this.getRefName(r.col)+' '+this.operator['notin']+' ('+r.params.join(',')+')');
return this;
};
this.groupeBy = function(){
this.groupBy = Array.from(arguments);
return this;
};
this.orderBy = function(){
this.orderBy = Array.from(arguments);
return this;
};
//HAVING
this.when = function(){
return this.if.apply(this, arguments);
};
this.if = function(){
//use having
};
this.limit = function(skip, take){
this.limitBy.use = true;
if(!take){
take = skip;
skip = 0;
}
this.limitBy.skip = skip;
this.limitBy.take = take;
return this;
};
this.skip = function(skip){
this.limitBy.use = true;
this.limitBy.skip = skip;
return this;
};
this.take = function(take){
this.limitBy.use = true;
this.limitBy.take = take;
return this;
};
//USER FONCTION
this.use = function(){
this.selectedColumn.push(arguments[0]+'('+Array.from(arguments).slice(1).join(',')+')');
return this;
};
this.set = function(setters){
for(var i in setters){
this.updateSetter[i] = setters[i];
}
return this;
};
this.with = function(){
this.$builder.with.apply(this.$builder, Array.from(arguments));
return this;
};
this.notWith = function(){
this.$builder.notWith.apply(this.$builder, Array.from(arguments));
return this;
};
this.get = function(calback){
this.operation = 'SELECT';
return this.$builder.get(this.toString(), this.tpsparams || {}, true);
};
this.update = function(){
this.operation = 'UPDATE';
return this.$builder.get(this.toString(), this.tpsparams || {}, true);
};
this.delete = function(){
this.operation = 'DELETE';
return this.$builder.delete(this.toString(), this.tpsparams || {}, true);
};
this.create = function(json){
return this.$builder.save(json);
};
this.cleanQuery = function(json){
this.selectedColumn = [];
this.whereClause = [];
this.updateSetter = {};
this.havingClause = [];
this.fromOtherTable = [];
this.tpsparams = Object.assign({}, this.params);
this.params = {};
this.countParams = 0;
this.groupBy = [];
this.orderBy = [];
this.limitBy = {use : false, skip : 0, take : 0};
this.operation = '';
return this;
};
this.toString = function(){
var sql = '';
switch(this.operation){
case '' :
case 'SELECT' :
sql = 'SELECT '+(this.selectedColumn.length==0?'*':this.selectedColumn.join(', '))+
' FROM '+(this.tableName+' '+((this.tableName!=this.tableAliasName)?' '+this.tableAliasName:'')+this.fromOtherTable.join(', '));
if(this.whereClause.length > 0)
sql += ' WHERE '+this.whereClause.join(' ');
if(this.havingClause.length > 0)
sql += ' HAVING '+this.havingClause.join(' ');
if(this.groupBy.length > 0)
sql += ' GROUP BY '+this.groupBy.join(', ');
if(this.limitBy.use)
sql += ' LIMIT '+this.limitBy.skip+', '+this.limitBy.take;
if(this.orderBy.length > 0)
sql += ' ORDER BY '+this.orderBy.join(', ');
break;
case 'UPDATE' :
var paramsValues = [];
for(var i in this.updateSetter){
paramsValues.push(i+' = :'+i);
this.params[i] = this.updateSetter[i];
}
sql = 'UPDATE '+this.tableName+' SET '+paramsValues;
if(this.whereClause.length > 0)
sql += ' WHERE '+this.whereClause.join(' ');
break;
case 'DELETE' :
sql = 'DELETE FROM '+
' FROM '+(this.tableName+' '+((this.tableName!=this.tableAliasName)?' '+this.tableAliasName:'')+this.fromOtherTable.join(', '));
if(this.whereClause.length > 0)
sql += ' WHERE '+this.whereClause.join(' ');
break;
}
this.cleanQuery();
return sql;
};
};
module.exports = QueryBuider;