|
|
@ -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(); |
|
|
|
} |
|
|
|