|
|
|
@ -16,74 +16,6 @@ class QueryBuilderBase {
|
|
|
|
|
this.state = new State();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Complete the sql building based on the type provided
|
|
|
|
|
*
|
|
|
|
|
* @private
|
|
|
|
|
* @param {String} type - Type of SQL query
|
|
|
|
|
* @param {String} table - The table to run the query on
|
|
|
|
|
* @return {String} - The compiled sql
|
|
|
|
|
*/
|
|
|
|
|
_compile (type, table) {
|
|
|
|
|
// Put together the basic query
|
|
|
|
|
let sql = this._compileType(type, table);
|
|
|
|
|
|
|
|
|
|
// Set each subClause
|
|
|
|
|
['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(clause => {
|
|
|
|
|
let param = this.state[clause];
|
|
|
|
|
|
|
|
|
|
if (!Helpers.isScalar(param)) {
|
|
|
|
|
Object.keys(param).forEach(part => {
|
|
|
|
|
sql += param[part].conjunction + param[part].string;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
sql += param;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Append the limit, if it exists
|
|
|
|
|
if (Helpers.isNumber(this.state.limit)) {
|
|
|
|
|
sql = this.driver.limit(sql, this.state.limit, this.state.offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_compileType (type, table) {
|
|
|
|
|
let sql = '';
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'insert':
|
|
|
|
|
let params = Array(this.state.setArrayKeys.length).fill('?');
|
|
|
|
|
|
|
|
|
|
sql = `INSERT INTO ${table} (`;
|
|
|
|
|
sql += this.state.setArrayKeys.join(',');
|
|
|
|
|
sql += `) VALUES (${params.join(',')})`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'update':
|
|
|
|
|
sql = `UPDATE ${table} SET ${this.state.setString}`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'delete':
|
|
|
|
|
sql = `DELETE FROM ${table}`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
sql = `SELECT * FROM ${this.state.fromString}`;
|
|
|
|
|
|
|
|
|
|
// Set the select string
|
|
|
|
|
if (this.state.selectString.length > 0) {
|
|
|
|
|
// Replace the star with the selected fields
|
|
|
|
|
sql = sql.replace('*', this.state.selectString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_like (field, val, pos, like, conj) {
|
|
|
|
|
field = this.driver.quoteIdentifiers(field);
|
|
|
|
|
|
|
|
|
@ -147,7 +79,7 @@ class QueryBuilderBase {
|
|
|
|
|
Object.keys(obj).forEach(k => {
|
|
|
|
|
// If a single value for the return
|
|
|
|
|
if (['key', 'value'].indexOf(valType) !== -1) {
|
|
|
|
|
let pushVal = (valType === 'key') ? k : obj[k];
|
|
|
|
|
const pushVal = (valType === 'key') ? k : obj[k];
|
|
|
|
|
this.state[letName].push(pushVal);
|
|
|
|
|
} else {
|
|
|
|
|
this.state[letName][k] = obj[k];
|
|
|
|
@ -166,8 +98,8 @@ class QueryBuilderBase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_fixConjunction (conj) {
|
|
|
|
|
let lastItem = this.state.queryMap[this.state.queryMap.length - 1];
|
|
|
|
|
let conjunctionList = Helpers.arrayPluck(this.state.queryMap, 'conjunction');
|
|
|
|
|
const lastItem = this.state.queryMap[this.state.queryMap.length - 1];
|
|
|
|
|
const conjunctionList = Helpers.arrayPluck(this.state.queryMap, 'conjunction');
|
|
|
|
|
|
|
|
|
|
if (this.state.queryMap.length === 0 || (!Helpers.regexInArray(conjunctionList, /^ ?WHERE/i))) {
|
|
|
|
|
conj = ' WHERE ';
|
|
|
|
@ -189,7 +121,7 @@ class QueryBuilderBase {
|
|
|
|
|
this.state = this.parser.parseWhere(this.driver, this.state);
|
|
|
|
|
|
|
|
|
|
this.state.whereMap.forEach(clause => {
|
|
|
|
|
let conj = this._fixConjunction(defaultConj);
|
|
|
|
|
const conj = this._fixConjunction(defaultConj);
|
|
|
|
|
this._appendMap(conj, clause, 'where');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -198,7 +130,7 @@ class QueryBuilderBase {
|
|
|
|
|
|
|
|
|
|
_whereNull (field, stmt, conj) {
|
|
|
|
|
field = this.driver.quoteIdentifiers(field);
|
|
|
|
|
let item = `${field} ${stmt}`;
|
|
|
|
|
const item = `${field} ${stmt}`;
|
|
|
|
|
|
|
|
|
|
this._appendMap(this._fixConjunction(conj), item, 'whereNull');
|
|
|
|
|
}
|
|
|
|
@ -225,7 +157,7 @@ class QueryBuilderBase {
|
|
|
|
|
|
|
|
|
|
_whereIn (key, val, inClause, conj) {
|
|
|
|
|
key = this.driver.quoteIdentifiers(key);
|
|
|
|
|
let params = Array(val.length);
|
|
|
|
|
const params = Array(val.length);
|
|
|
|
|
params.fill('?');
|
|
|
|
|
|
|
|
|
|
val.forEach(value => {
|
|
|
|
@ -233,7 +165,7 @@ class QueryBuilderBase {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
conj = (this.state.queryMap.length > 0) ? ` ${conj} ` : ' WHERE ';
|
|
|
|
|
let str = `${key} ${inClause} (${params.join(',')}) `;
|
|
|
|
|
const str = `${key} ${inClause} (${params.join(',')}) `;
|
|
|
|
|
|
|
|
|
|
this._appendMap(conj, str, 'whereIn');
|
|
|
|
|
}
|
|
|
|
@ -257,7 +189,7 @@ class QueryBuilderBase {
|
|
|
|
|
_getCompile (type, table, reset) {
|
|
|
|
|
reset = reset || false;
|
|
|
|
|
|
|
|
|
|
let sql = this._compile(type, table);
|
|
|
|
|
const sql = this._compile(type, table);
|
|
|
|
|
|
|
|
|
|
if (reset) {
|
|
|
|
|
this._resetState();
|
|
|
|
@ -266,6 +198,74 @@ class QueryBuilderBase {
|
|
|
|
|
return sql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Complete the sql building based on the type provided
|
|
|
|
|
*
|
|
|
|
|
* @private
|
|
|
|
|
* @param {String} type - Type of SQL query
|
|
|
|
|
* @param {String} table - The table to run the query on
|
|
|
|
|
* @return {String} - The compiled sql
|
|
|
|
|
*/
|
|
|
|
|
_compile (type, table) {
|
|
|
|
|
// Put together the basic query
|
|
|
|
|
let sql = this._compileType(type, table);
|
|
|
|
|
|
|
|
|
|
// Set each subClause
|
|
|
|
|
['queryMap', 'groupString', 'orderString', 'havingMap'].forEach(clause => {
|
|
|
|
|
const param = this.state[clause];
|
|
|
|
|
|
|
|
|
|
if (!Helpers.isScalar(param)) {
|
|
|
|
|
Object.keys(param).forEach(part => {
|
|
|
|
|
sql += param[part].conjunction + param[part].string;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
sql += param;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Append the limit, if it exists
|
|
|
|
|
if (Helpers.isNumber(this.state.limit)) {
|
|
|
|
|
sql = this.driver.limit(sql, this.state.limit, this.state.offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_compileType (type, table) {
|
|
|
|
|
let sql = '';
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'insert':
|
|
|
|
|
const params = Array(this.state.setArrayKeys.length).fill('?');
|
|
|
|
|
|
|
|
|
|
sql = `INSERT INTO ${table} (`;
|
|
|
|
|
sql += this.state.setArrayKeys.join(',');
|
|
|
|
|
sql += `) VALUES (${params.join(',')})`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'update':
|
|
|
|
|
sql = `UPDATE ${table} SET ${this.state.setString}`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'delete':
|
|
|
|
|
sql = `DELETE FROM ${table}`;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
sql = `SELECT * FROM ${this.state.fromString}`;
|
|
|
|
|
|
|
|
|
|
// Set the select string
|
|
|
|
|
if (this.state.selectString.length > 0) {
|
|
|
|
|
// Replace the star with the selected fields
|
|
|
|
|
sql = sql.replace('*', this.state.selectString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_resetState () {
|
|
|
|
|
this.state = new State();
|
|
|
|
|
}
|
|
|
|
|