|
|
|
"use strict";
|
|
|
|
|
|
|
|
const mysql = require("mysql");
|
|
|
|
const dataHelp = require("./util/data.helper.js");
|
|
|
|
const whereHelp = require("./util/whereClause.helper.js");
|
|
|
|
const assert = require("assert");
|
|
|
|
|
|
|
|
//define class§
|
|
|
|
class Xsql {
|
|
|
|
constructor(sqlConfig, pool) {
|
|
|
|
//define this variables
|
|
|
|
this.sqlConfig = {};
|
|
|
|
this.pool = {};
|
|
|
|
this.metaDb = {};
|
|
|
|
this.metaDb.tables = {};
|
|
|
|
|
|
|
|
this.sqlConfig = sqlConfig;
|
|
|
|
this.pool = pool;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************** START : Cache functions ****************/
|
|
|
|
init(cbk) {
|
|
|
|
this.dbCacheInitAsync((err, results) => {
|
|
|
|
cbk(err, results);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
dbCacheInitAsync(cbk) {
|
|
|
|
let self = this;
|
|
|
|
|
|
|
|
self.pool.query(
|
|
|
|
dataHelp.getSchemaQuery(),
|
|
|
|
[this.sqlConfig.database],
|
|
|
|
(err, results) => {
|
|
|
|
if (err) {
|
|
|
|
console.log("Cache init failed during database reading");
|
|
|
|
console.log(err, results);
|
|
|
|
cbk(err, results);
|
|
|
|
} else {
|
|
|
|
for (var i = 0; i < results.length; ++i) {
|
|
|
|
let keys = Object.keys(results[i]);
|
|
|
|
|
|
|
|
for (var j = 0; j < keys.length; ++j) {
|
|
|
|
let value = results[i][keys[j]];
|
|
|
|
|
|
|
|
results[i][keys[j].toLowerCase()] = value;
|
|
|
|
|
|
|
|
//console.log(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.iterateToCacheTables(results);
|
|
|
|
self.iterateToCacheTablePks(results);
|
|
|
|
self.iterateToCacheTableColumns(results);
|
|
|
|
self.iterateToCacheTableFks(results);
|
|
|
|
|
|
|
|
// osx mysql server has limitations related to open_tables
|
|
|
|
self.pool.query("FLUSH TABLES", [], (err, results) => {
|
|
|
|
cbk(null, null);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
iterateToCacheTables(schemaResults) {
|
|
|
|
for (let i = 0; i < schemaResults.length; ++i) {
|
|
|
|
let schemaRow = schemaResults[i];
|
|
|
|
|
|
|
|
let tableName = schemaRow["table_name"];
|
|
|
|
|
|
|
|
if (!(tableName in this.metaDb.tables)) {
|
|
|
|
this.metaDb.tables[tableName] = {};
|
|
|
|
this.metaDb.tables[tableName]["primaryKeys"] = [];
|
|
|
|
this.metaDb.tables[tableName]["foreignKeys"] = [];
|
|
|
|
this.metaDb.tables[tableName]["columns"] = [];
|
|
|
|
this.metaDb.tables[tableName]["indicies"] = [];
|
|
|
|
this.metaDb.tables[tableName]["isView"] = schemaRow["isView"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
iterateToCacheTableColumns(schemaResults) {
|
|
|
|
for (let i = 0; i < schemaResults.length; ++i) {
|
|
|
|
let schemaRow = schemaResults[i];
|
|
|
|
let tableName = schemaRow["table_name"];
|
|
|
|
let col = {};
|
|
|
|
col["column_name"] = schemaRow["column_name"];
|
|
|
|
col["ordinal_position"] = schemaRow["ordinal_position"];
|
|
|
|
col["column_key"] = schemaRow["column_key"];
|
|
|
|
col["data_type"] = schemaRow["data_type"];
|
|
|
|
col["column_type"] = schemaRow["column_type"];
|
|
|
|
|
|
|
|
dataHelp.findOrInsertObjectArrayByKey(
|
|
|
|
col,
|
|
|
|
"column_name",
|
|
|
|
this.metaDb.tables[tableName]["columns"]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
iterateToCacheTablePks(schemaResults) {
|
|
|
|
for (let i = 0; i < schemaResults.length; ++i) {
|
|
|
|
let schemaRow = schemaResults[i];
|
|
|
|
let tableName = schemaRow["table_name"];
|
|
|
|
|
|
|
|
if (schemaRow["column_key"] === "PRI") {
|
|
|
|
let pk = {};
|
|
|
|
pk["column_name"] = schemaRow["column_name"];
|
|
|
|
pk["ordinal_position"] = schemaRow["ordinal_position"];
|
|
|
|
pk["column_key"] = schemaRow["column_key"];
|
|
|
|
pk["data_type"] = schemaRow["data_type"];
|
|
|
|
pk["column_type"] = schemaRow["column_type"];
|
|
|
|
|
|
|
|
dataHelp.findOrInsertObjectArrayByKey(
|
|
|
|
pk,
|
|
|
|
"column_name",
|
|
|
|
this.metaDb.tables[tableName]["primaryKeys"]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
iterateToCacheTableFks(schemaResults) {
|
|
|
|
for (let i = 0; i < schemaResults.length; ++i) {
|
|
|
|
let schemaRow = schemaResults[i];
|
|
|
|
let tableName = schemaRow["table_name"];
|
|
|
|
|
|
|
|
if (schemaRow["referenced_table_name"]) {
|
|
|
|
let fk = {};
|
|
|
|
|
|
|
|
fk["column_name"] = schemaRow["column_name"];
|
|
|
|
fk["table_name"] = schemaRow["table_name"];
|
|
|
|
fk["referenced_table_name"] = schemaRow["referenced_table_name"];
|
|
|
|
fk["referenced_column_name"] = schemaRow["referenced_column_name"];
|
|
|
|
fk["data_type"] = schemaRow["data_type"];
|
|
|
|
fk["column_type"] = schemaRow["column_type"];
|
|
|
|
|
|
|
|
dataHelp.findOrInsertObjectArrayByKey(
|
|
|
|
fk,
|
|
|
|
"column_name",
|
|
|
|
this.metaDb.tables[tableName]["foreignKeys"]
|
|
|
|
);
|
|
|
|
|
|
|
|
//console.log(fk['referenced_table_name'],fk['referenced_column_name'],tableName, schemaRow['column_name'], this.metaDb.tables[tableName]['foreignKeys'].length)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************** END : Cache functions ****************/
|
|
|
|
|
|
|
|
exec(query, params) {
|
|
|
|
let _this = this;
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
//console.log('mysql>', query, params);
|
|
|
|
_this.pool.query(query, params, function(error, rows, _fields) {
|
|
|
|
if (error) {
|
|
|
|
console.log("mysql> ", error);
|
|
|
|
return reject(error);
|
|
|
|
}
|
|
|
|
return resolve(rows);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
typeOfColumn(Type) {
|
|
|
|
//TODO: Im sure there are more types to handle here
|
|
|
|
const strTypes = [
|
|
|
|
"varchar",
|
|
|
|
"text",
|
|
|
|
"char",
|
|
|
|
"tinytext",
|
|
|
|
"mediumtext",
|
|
|
|
"longtext",
|
|
|
|
"blob",
|
|
|
|
"mediumblob",
|
|
|
|
"longblob"
|
|
|
|
];
|
|
|
|
const intTypes = [
|
|
|
|
"int",
|
|
|
|
"long",
|
|
|
|
"smallint",
|
|
|
|
"mediumint",
|
|
|
|
"bigint",
|
|
|
|
"tinyint"
|
|
|
|
];
|
|
|
|
const flatTypes = ["float", "double", "decimal"];
|
|
|
|
const dateTypes = ["date", "datetime", "timestamp", "time", "year"];
|
|
|
|
|
|
|
|
if (dataHelp.getType(Type, strTypes)) {
|
|
|
|
return "string";
|
|
|
|
} else if (dataHelp.getType(Type, intTypes)) {
|
|
|
|
return "int";
|
|
|
|
} else if (dataHelp.getType(Type, flatTypes)) {
|
|
|
|
return "float";
|
|
|
|
} else if (dataHelp.getType(Type, dateTypes)) {
|
|
|
|
return "date";
|
|
|
|
} else {
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isTypeOfColumnNumber(Type) {
|
|
|
|
//console.log(Type, this.typeOfColumn(Type));
|
|
|
|
return (
|
|
|
|
"int" === this.typeOfColumn(Type) || "float" === this.typeOfColumn(Type)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
getLimitClause(reqParams) {
|
|
|
|
//defaults
|
|
|
|
reqParams._index = 0;
|
|
|
|
reqParams._len = 20;
|
|
|
|
|
|
|
|
if ("_size" in reqParams) {
|
|
|
|
if (parseInt(reqParams._size) > 0 && parseInt(reqParams._size) <= 100) {
|
|
|
|
reqParams._len = parseInt(reqParams._size);
|
|
|
|
} else if (parseInt(reqParams._size) > 100) {
|
|
|
|
reqParams._len = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ("_p" in reqParams && parseInt(reqParams._p) > 0) {
|
|
|
|
reqParams._index = parseInt(reqParams._p) * reqParams._len;
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log(reqParams._index, reqParams._len);
|
|
|
|
|
|
|
|
return [reqParams._index, reqParams._len];
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareBulkInsert(tableName, objectArray, queryParamsObj) {
|
|
|
|
if (tableName in this.metaDb.tables && objectArray) {
|
|
|
|
let insObj = objectArray[0];
|
|
|
|
|
|
|
|
// goal => insert into ?? (?,?..?) values ? [tablName, col1,col2...coln,[[ObjValues_1],[ObjValues_2],...[ObjValues_N]]
|
|
|
|
queryParamsObj.query = " INSERT INTO ?? ( ";
|
|
|
|
queryParamsObj.params.push(tableName);
|
|
|
|
|
|
|
|
let cols = [];
|
|
|
|
let colPresent = false;
|
|
|
|
|
|
|
|
/**************** START : prepare column names to be inserted ****************/
|
|
|
|
// iterate over all column in table and have only ones existing in objects to be inserted
|
|
|
|
for (
|
|
|
|
var i = 0;
|
|
|
|
i < this.metaDb.tables[tableName]["columns"].length;
|
|
|
|
++i
|
|
|
|
) {
|
|
|
|
let colName = this.metaDb.tables[tableName]["columns"][i][
|
|
|
|
"column_name"
|
|
|
|
];
|
|
|
|
|
|
|
|
if (colName in insObj) {
|
|
|
|
if (colPresent) {
|
|
|
|
queryParamsObj.query += ",";
|
|
|
|
}
|
|
|
|
|
|
|
|
queryParamsObj.query += colName;
|
|
|
|
|
|
|
|
colPresent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cols.push(colName);
|
|
|
|
|
|
|
|
//console.log('> > ', queryParamsObj.query);
|
|
|
|
}
|
|
|
|
|
|
|
|
queryParamsObj.query += " ) values ?";
|
|
|
|
/**************** END : prepare column names to be inserted ****************/
|
|
|
|
|
|
|
|
/**************** START : prepare value object in prepared statement ****************/
|
|
|
|
// iterate over sent object array
|
|
|
|
let arrOfArr = [];
|
|
|
|
for (var i = 0; i < objectArray.length; ++i) {
|
|
|
|
let arrValues = [];
|
|
|
|
for (var j = 0; j < cols.length; ++j) {
|
|
|
|
if (cols[j] in objectArray[i])
|
|
|
|
arrValues.push(objectArray[i][cols[j]]);
|
|
|
|
}
|
|
|
|
arrOfArr.push(arrValues);
|
|
|
|
}
|
|
|
|
queryParamsObj.params.push(arrOfArr);
|
|
|
|
/**************** END : prepare value object in prepared statement ****************/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getGroupByClause(_groupby, tableName, queryParamsObj) {
|
|
|
|
if (_groupby) {
|
|
|
|
queryParamsObj.query += " group by " + _groupby + " ";
|
|
|
|
return _groupby;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getHavingClause(_having, tableName, queryParamsObj) {
|
|
|
|
if (_having) {
|
|
|
|
let whereClauseObj = whereHelp.getConditionClause(_having, "having");
|
|
|
|
|
|
|
|
if (whereClauseObj.err === 0) {
|
|
|
|
queryParamsObj.query =
|
|
|
|
queryParamsObj.query + " having " + whereClauseObj.query;
|
|
|
|
queryParamsObj.params = queryParamsObj.params.concat(
|
|
|
|
whereClauseObj.params
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log('> > > after where clause filling up:', queryParamsObj.query, queryParamsObj.params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getWhereClause(queryparams, tableName, queryParamsObj, appendToWhere) {
|
|
|
|
if (queryparams) {
|
|
|
|
let whereClauseObj = whereHelp.getConditionClause(queryparams);
|
|
|
|
|
|
|
|
if (whereClauseObj.err === 0) {
|
|
|
|
queryParamsObj.query =
|
|
|
|
queryParamsObj.query + appendToWhere + whereClauseObj.query;
|
|
|
|
queryParamsObj.params = queryParamsObj.params.concat(
|
|
|
|
whereClauseObj.params
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getOrderByClause(queryparams, tableName, queryParamsObj) {
|
|
|
|
if (queryparams._sort) {
|
|
|
|
queryParamsObj.query += " ORDER BY ";
|
|
|
|
|
|
|
|
let orderByCols = queryparams._sort.split(",");
|
|
|
|
|
|
|
|
for (let i = 0; i < orderByCols.length; ++i) {
|
|
|
|
if (i) {
|
|
|
|
queryParamsObj.query += ", ";
|
|
|
|
}
|
|
|
|
if (orderByCols[i][0] === "-") {
|
|
|
|
let len = orderByCols[i].length;
|
|
|
|
queryParamsObj.query += " ?? DESC";
|
|
|
|
queryParamsObj.params.push(orderByCols[i].substring(1, len));
|
|
|
|
} else {
|
|
|
|
queryParamsObj.query += " ?? ASC";
|
|
|
|
queryParamsObj.params.push(orderByCols[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getColumnsForSelectStmtWithGrpBy(reqQueryParams, tableName, queryParamsObj) {
|
|
|
|
let grpByCols = reqQueryParams._groupby.split(",");
|
|
|
|
|
|
|
|
for (var i = 0; i < grpByCols.length; ++i) {
|
|
|
|
if (i) {
|
|
|
|
queryParamsObj.query += ",";
|
|
|
|
}
|
|
|
|
queryParamsObj.query += " ??";
|
|
|
|
queryParamsObj.params.push(grpByCols[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
queryParamsObj.query += ",count(1) as _count ";
|
|
|
|
}
|
|
|
|
|
|
|
|
getColumnsForSelectStmt(tableName, reqQueryParams, queryParamsObj) {
|
|
|
|
let table = this.metaDb.tables[tableName];
|
|
|
|
let cols = [];
|
|
|
|
let _fieldsInQuery = [];
|
|
|
|
let removeFieldsObj = {};
|
|
|
|
|
|
|
|
// populate _fields array from query params
|
|
|
|
if ("_fields" in reqQueryParams) {
|
|
|
|
_fieldsInQuery = reqQueryParams["_fields"].split(",");
|
|
|
|
} else {
|
|
|
|
queryParamsObj.query += " * ";
|
|
|
|
return " * ";
|
|
|
|
}
|
|
|
|
|
|
|
|
// get column name in _fields and mark column name which start with '-'
|
|
|
|
for (let i = 0; i < _fieldsInQuery.length; ++i) {
|
|
|
|
if (_fieldsInQuery[i][0] === "-") {
|
|
|
|
removeFieldsObj[
|
|
|
|
_fieldsInQuery[i].substring(1, _fieldsInQuery[i].length)
|
|
|
|
] = 1;
|
|
|
|
} else {
|
|
|
|
cols.push(_fieldsInQuery[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cols.length) {
|
|
|
|
// for each column in table - add only which are not in removeFieldsObj
|
|
|
|
for (let i = 0; i < table["columns"].length; ++i) {
|
|
|
|
if (!(table["columns"][i]["column_name"] in removeFieldsObj)) {
|
|
|
|
cols.push(table["columns"][i]["column_name"]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cols = this.removeUnknownColumns(cols, tableName);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < cols.length; ++i) {
|
|
|
|
if (i) {
|
|
|
|
queryParamsObj.query += ",";
|
|
|
|
}
|
|
|
|
queryParamsObj.query += "??";
|
|
|
|
queryParamsObj.params.push(cols[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cols.join(",");
|
|
|
|
}
|
|
|
|
|
|
|
|
removeUnknownColumns(inputColumns, tableName) {
|
|
|
|
let cols = inputColumns;
|
|
|
|
let unknown_cols_in_input = [];
|
|
|
|
let shadowCols = [];
|
|
|
|
let tableColumns = this.metaDb.tables[tableName]["columns"];
|
|
|
|
|
|
|
|
// find unknown fields if any
|
|
|
|
for (var j = 0; j < cols.length; ++j) {
|
|
|
|
let found = 0;
|
|
|
|
|
|
|
|
for (var i = 0; i < tableColumns.length; ++i) {
|
|
|
|
if (tableColumns[i]["column_name"] === cols[j]) {
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
unknown_cols_in_input.push(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there are unknown fields - remove and ignore 'em
|
|
|
|
if (unknown_cols_in_input.length) {
|
|
|
|
for (var i = 0; i < cols.length; ++i) {
|
|
|
|
if (unknown_cols_in_input.indexOf(i) === -1) {
|
|
|
|
shadowCols.push(cols[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cols = [];
|
|
|
|
cols = shadowCols;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cols;
|
|
|
|
}
|
|
|
|
|
|
|
|
getPrimaryKeyName(tableName) {
|
|
|
|
let pk = null;
|
|
|
|
if (tableName in this.metaDb.tables) {
|
|
|
|
pk = this.metaDb.tables[tableName].primaryKeys[0]["column_name"];
|
|
|
|
}
|
|
|
|
return pk;
|
|
|
|
}
|
|
|
|
|
|
|
|
getPrimaryKeyWhereClause(tableName, pksValues) {
|
|
|
|
let whereClause = "";
|
|
|
|
let whereCol = "";
|
|
|
|
let whereValue = "";
|
|
|
|
let pks = [];
|
|
|
|
|
|
|
|
if (tableName in this.metaDb.tables) {
|
|
|
|
pks = this.metaDb.tables[tableName].primaryKeys;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// number of primary keys in table and one sent should be same
|
|
|
|
if (pksValues.length !== pks.length) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get a where clause out of the above columnNames and their values
|
|
|
|
for (let i = 0; i < pks.length; ++i) {
|
|
|
|
let type = dataHelp.getColumnType(pks[i]);
|
|
|
|
|
|
|
|
whereCol = pks[i]["column_name"];
|
|
|
|
|
|
|
|
if (type === "string") {
|
|
|
|
whereValue = mysql.escape(pksValues[i]);
|
|
|
|
} else if (type === "int") {
|
|
|
|
whereValue = parseInt(pksValues[i]);
|
|
|
|
} else if (type === "float") {
|
|
|
|
whereValue = parseFloat(pksValues[i]);
|
|
|
|
} else if (type === "date") {
|
|
|
|
whereValue = Date(pksValues[i]);
|
|
|
|
} else {
|
|
|
|
console.error(pks[i]);
|
|
|
|
assert(false, "Unhandled type of primary key");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i) {
|
|
|
|
whereClause += " and ";
|
|
|
|
}
|
|
|
|
|
|
|
|
whereClause += whereCol + " = " + whereValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return whereClause;
|
|
|
|
}
|
|
|
|
|
|
|
|
getForeignKeyWhereClause(parentTable, parentId, childTable) {
|
|
|
|
let whereValue = "";
|
|
|
|
|
|
|
|
//get all foreign keys of child table
|
|
|
|
let fks = this.metaDb.tables[childTable].foreignKeys;
|
|
|
|
let fk = dataHelp.findObjectInArrayByKey(
|
|
|
|
"referenced_table_name",
|
|
|
|
parentTable,
|
|
|
|
fks
|
|
|
|
);
|
|
|
|
let whereCol = fk["column_name"];
|
|
|
|
let colType = dataHelp.getColumnType(fk);
|
|
|
|
|
|
|
|
if (colType === "string") {
|
|
|
|
whereValue = mysql.escape(parentId);
|
|
|
|
} else if (colType === "int") {
|
|
|
|
whereValue = mysql.escape(parseInt(parentId));
|
|
|
|
} else if (colType === "float") {
|
|
|
|
whereValue = mysql.escape(parseFloat(parentId));
|
|
|
|
} else if (colType === "date") {
|
|
|
|
whereValue = mysql.escape(Date(parentId));
|
|
|
|
} else {
|
|
|
|
console.error(pks[i]);
|
|
|
|
assert(false, "Unhandled column type in foreign key handling");
|
|
|
|
}
|
|
|
|
|
|
|
|
return whereCol + " = " + whereValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareRoute(internal, httpType, apiPrefix, urlRoute, routeType) {
|
|
|
|
let route = {};
|
|
|
|
route["httpType"] = httpType;
|
|
|
|
route["routeUrl"] = apiPrefix + urlRoute;
|
|
|
|
if (internal) {
|
|
|
|
route["routeType"] = routeType;
|
|
|
|
}
|
|
|
|
return route;
|
|
|
|
}
|
|
|
|
|
|
|
|
getSchemaRoutes(internal, apiPrefix) {
|
|
|
|
let schemaRoutes = [];
|
|
|
|
|
|
|
|
for (var tableName in this.metaDb.tables) {
|
|
|
|
if (tableName in this.sqlConfig.ignoreTables) {
|
|
|
|
//console.log('ignore table', tableName);
|
|
|
|
} else {
|
|
|
|
let routes = [];
|
|
|
|
let tableObj = {};
|
|
|
|
let table = this.metaDb.tables[tableName];
|
|
|
|
let isView = this.metaDb.tables[tableName]["isView"];
|
|
|
|
|
|
|
|
tableObj["resource"] = tableName;
|
|
|
|
|
|
|
|
// order of routes is important for express routing - DO NOT CHANGE ORDER
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/describe",
|
|
|
|
"describe"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/count",
|
|
|
|
"count"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/groupby",
|
|
|
|
"groupby"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/distinct",
|
|
|
|
"distinct"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/ugroupby",
|
|
|
|
"ugroupby"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/chart",
|
|
|
|
"chart"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/aggregate",
|
|
|
|
"aggregate"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/findOne",
|
|
|
|
"findOne"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/autoChart",
|
|
|
|
"autoChart"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!isView && !this.sqlConfig.readOnly) {
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(internal, "post", apiPrefix, tableName, "create")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(internal, "get", apiPrefix, tableName, "list")
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!isView && !this.sqlConfig.readOnly) {
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"post",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/bulk",
|
|
|
|
"bulkInsert"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"delete",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/bulk",
|
|
|
|
"bulkDelete"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/bulk",
|
|
|
|
"bulkRead"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!isView && !this.sqlConfig.readOnly) {
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(internal, "put", apiPrefix, tableName, "update")
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"patch",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/:id",
|
|
|
|
"patch"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"delete",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/:id",
|
|
|
|
"delete"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/:id",
|
|
|
|
"read"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
tableName + "/:id/exists",
|
|
|
|
"exists"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
for (var j = 0; j < table["foreignKeys"].length; ++j) {
|
|
|
|
let fk = table["foreignKeys"][j];
|
|
|
|
|
|
|
|
if (fk["referenced_table_name"] in this.sqlConfig.ignoreTables) {
|
|
|
|
//console.log('ignore table',fk['referenced_table_name']);
|
|
|
|
} else {
|
|
|
|
routes.push(
|
|
|
|
this.prepareRoute(
|
|
|
|
internal,
|
|
|
|
"get",
|
|
|
|
apiPrefix,
|
|
|
|
fk["referenced_table_name"] + "/:id/" + fk["table_name"],
|
|
|
|
"relational"
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tableObj["routes"] = routes;
|
|
|
|
|
|
|
|
schemaRoutes.push(tableObj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return schemaRoutes;
|
|
|
|
}
|
|
|
|
|
|
|
|
getJoinType(joinInQueryParams) {
|
|
|
|
//console.log('joinInQueryParams',joinInQueryParams);
|
|
|
|
|
|
|
|
switch (joinInQueryParams) {
|
|
|
|
case "_lj":
|
|
|
|
return " left join ";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "_rj":
|
|
|
|
return " right join ";
|
|
|
|
break;
|
|
|
|
|
|
|
|
// case '_fj':
|
|
|
|
// return ' full join '
|
|
|
|
// break;
|
|
|
|
|
|
|
|
case "_ij":
|
|
|
|
return " inner join ";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "_j":
|
|
|
|
return " join ";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return " join ";
|
|
|
|
}
|
|
|
|
|
|
|
|
globalRoutesPrint(apiPrefix) {
|
|
|
|
let r = [];
|
|
|
|
|
|
|
|
r.push(apiPrefix + "tables");
|
|
|
|
r.push(apiPrefix + "xjoin");
|
|
|
|
|
|
|
|
if (this.sqlConfig.dynamic) {
|
|
|
|
r.push(apiPrefix + "dynamic");
|
|
|
|
r.push("/upload");
|
|
|
|
r.push("/uploads");
|
|
|
|
r.push("/download");
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
getChartQueryAndParamsFromStepPair(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
stepArray,
|
|
|
|
isRange = false
|
|
|
|
) {
|
|
|
|
let obj = {};
|
|
|
|
|
|
|
|
obj.query = "";
|
|
|
|
obj.params = [];
|
|
|
|
|
|
|
|
//console.log('getChartQueryAndParamsFromStepArray',isRange);
|
|
|
|
|
|
|
|
//select ? as ??, count(*) as _count from ?? where ?? between ? and ?
|
|
|
|
|
|
|
|
if (
|
|
|
|
stepArray.length &&
|
|
|
|
stepArray.length >= 2 &&
|
|
|
|
stepArray.length % 2 === 0
|
|
|
|
) {
|
|
|
|
for (
|
|
|
|
let i = 0;
|
|
|
|
i < stepArray.length && stepArray.length >= 2;
|
|
|
|
i = i + 2
|
|
|
|
) {
|
|
|
|
obj.query = obj.query + dataHelp.getChartQuery();
|
|
|
|
|
|
|
|
if (i + 2 < stepArray.length) {
|
|
|
|
obj.query = obj.query + " union ";
|
|
|
|
}
|
|
|
|
|
|
|
|
obj.params.push(stepArray[i] + " to " + stepArray[i + 1]);
|
|
|
|
obj.params.push(columnName);
|
|
|
|
obj.params.push(tableName);
|
|
|
|
obj.params.push(columnName);
|
|
|
|
obj.params.push(stepArray[i]);
|
|
|
|
obj.params.push(stepArray[i + 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log('step spread query', obj);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
getChartQueryAndParamsFromStepArray(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
stepArray,
|
|
|
|
isRange = false
|
|
|
|
) {
|
|
|
|
let obj = {};
|
|
|
|
|
|
|
|
obj.query = "";
|
|
|
|
obj.params = [];
|
|
|
|
|
|
|
|
//console.log('getChartQueryAndParamsFromStepArray',isRange);
|
|
|
|
|
|
|
|
if (stepArray.length && stepArray.length >= 2) {
|
|
|
|
for (let i = 0; i < stepArray.length - 1; i = i + 1) {
|
|
|
|
obj.query = obj.query + dataHelp.getChartQuery();
|
|
|
|
if (i + 2 < stepArray.length) {
|
|
|
|
obj.query = obj.query + " union ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i && isRange === false) {
|
|
|
|
stepArray[i] = stepArray[i] + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isRange === false) {
|
|
|
|
obj.params.push(stepArray[i] + " to " + stepArray[i + 1]);
|
|
|
|
} else {
|
|
|
|
obj.params.push(stepArray[0] + " to " + stepArray[i + 1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
obj.params.push(columnName);
|
|
|
|
obj.params.push(tableName);
|
|
|
|
obj.params.push(columnName);
|
|
|
|
|
|
|
|
if (isRange === false) {
|
|
|
|
obj.params.push(stepArray[i]);
|
|
|
|
obj.params.push(stepArray[i + 1]);
|
|
|
|
} else {
|
|
|
|
obj.params.push(stepArray[0]);
|
|
|
|
obj.params.push(stepArray[i + 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log('step spread query', obj);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
getChartQueryAndParamsFromMinMaxStddev(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
min,
|
|
|
|
max,
|
|
|
|
stddev,
|
|
|
|
isRange = false
|
|
|
|
) {
|
|
|
|
let stepArray = dataHelp.getStepArray(min, max, stddev);
|
|
|
|
|
|
|
|
//console.log('steparray', stepArray);
|
|
|
|
|
|
|
|
let obj = this.getChartQueryAndParamsFromStepArray(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
stepArray,
|
|
|
|
isRange
|
|
|
|
);
|
|
|
|
|
|
|
|
//console.log('steparray', obj);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
getChartQueryAndParamsFromMinMaxStep(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
min,
|
|
|
|
max,
|
|
|
|
step,
|
|
|
|
isRange = false
|
|
|
|
) {
|
|
|
|
let stepArray = dataHelp.getStepArraySimple(min, max, step);
|
|
|
|
|
|
|
|
//console.log('steparray', stepArray);
|
|
|
|
|
|
|
|
let obj = this.getChartQueryAndParamsFromStepArray(
|
|
|
|
tableName,
|
|
|
|
columnName,
|
|
|
|
stepArray,
|
|
|
|
isRange
|
|
|
|
);
|
|
|
|
|
|
|
|
//console.log('steparray', obj);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
_getGrpByHavingOrderBy(req, tableName, queryParamsObj, listType) {
|
|
|
|
/**************** add group by ****************/
|
|
|
|
this.getGroupByClause(
|
|
|
|
req.query._groupby,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj
|
|
|
|
);
|
|
|
|
|
|
|
|
/**************** add having ****************/
|
|
|
|
this.getHavingClause(
|
|
|
|
req.query._having,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj
|
|
|
|
);
|
|
|
|
|
|
|
|
/**************** add order clause ****************/
|
|
|
|
this.getOrderByClause(req.query, req.app.locals._tableName, queryParamsObj);
|
|
|
|
|
|
|
|
/**************** add limit clause ****************/
|
|
|
|
if (listType === 2) {
|
|
|
|
//nested
|
|
|
|
queryParamsObj.query += " limit 1 ";
|
|
|
|
} else {
|
|
|
|
queryParamsObj.query += " limit ?,? ";
|
|
|
|
queryParamsObj.params = queryParamsObj.params.concat(
|
|
|
|
this.getLimitClause(req.query)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param req
|
|
|
|
* @param res
|
|
|
|
* @param queryParamsObj : {query, params}
|
|
|
|
* @param listType : 0:list, 1:nested, 2:findOne, 3:bulkRead, 4:distinct, 5:xjoin
|
|
|
|
*
|
|
|
|
* Updates query, params for query of type listType
|
|
|
|
*/
|
|
|
|
prepareListQuery(req, res, queryParamsObj, listType = 0) {
|
|
|
|
queryParamsObj.query = "select ";
|
|
|
|
queryParamsObj.params = [];
|
|
|
|
|
|
|
|
if (listType === 4) {
|
|
|
|
//list type distinct
|
|
|
|
queryParamsObj.query += " distinct ";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************** select columns ****************/
|
|
|
|
if (req.query._groupby) {
|
|
|
|
this.getColumnsForSelectStmtWithGrpBy(
|
|
|
|
req.query,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
this.getColumnsForSelectStmt(
|
|
|
|
req.app.locals._tableName,
|
|
|
|
req.query,
|
|
|
|
queryParamsObj
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************** add tableName ****************/
|
|
|
|
queryParamsObj.query += " from ?? ";
|
|
|
|
|
|
|
|
if (listType === 1) {
|
|
|
|
//nested list
|
|
|
|
|
|
|
|
req.app.locals._tableName = req.app.locals._childTable;
|
|
|
|
|
|
|
|
queryParamsObj.params.push(req.app.locals._childTable);
|
|
|
|
|
|
|
|
queryParamsObj.query += " where ";
|
|
|
|
|
|
|
|
/**************** add where foreign key ****************/
|
|
|
|
let whereClause = this.getForeignKeyWhereClause(
|
|
|
|
req.app.locals._parentTable,
|
|
|
|
req.params.id,
|
|
|
|
req.app.locals._childTable
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!whereClause) {
|
|
|
|
return res.status(400).send({
|
|
|
|
error:
|
|
|
|
"Table is made of composite primary keys - all keys were not in input"
|
|
|
|
});
|
|
|
|
}
|
|
|
|
queryParamsObj.query += whereClause;
|
|
|
|
|
|
|
|
this.getWhereClause(
|
|
|
|
req.query._where,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj,
|
|
|
|
" and "
|
|
|
|
);
|
|
|
|
} else if (listType === 3) {
|
|
|
|
//bulkRead
|
|
|
|
|
|
|
|
// select * from table where pk in (ids) and whereConditions
|
|
|
|
queryParamsObj.params.push(req.app.locals._tableName);
|
|
|
|
queryParamsObj.query += " where ?? in ";
|
|
|
|
queryParamsObj.params.push(
|
|
|
|
this.getPrimaryKeyName(req.app.locals._tableName)
|
|
|
|
);
|
|
|
|
|
|
|
|
queryParamsObj.query += "(";
|
|
|
|
|
|
|
|
if (req.query && req.query._ids) {
|
|
|
|
let ids = req.query._ids.split(",");
|
|
|
|
for (var i = 0; i < ids.length; ++i) {
|
|
|
|
if (i) {
|
|
|
|
queryParamsObj.query += ",";
|
|
|
|
}
|
|
|
|
queryParamsObj.query += "?";
|
|
|
|
queryParamsObj.params.push(ids[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
queryParamsObj.query += ") ";
|
|
|
|
this.getWhereClause(
|
|
|
|
req.query._where,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj,
|
|
|
|
" and "
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.params.push(req.app.locals._tableName);
|
|
|
|
|
|
|
|
/**************** add where clause ****************/
|
|
|
|
this.getWhereClause(
|
|
|
|
req.query._where,
|
|
|
|
req.app.locals._tableName,
|
|
|
|
queryParamsObj,
|
|
|
|
" where "
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._getGrpByHavingOrderBy(req, req.app.locals._tableName, queryParamsObj);
|
|
|
|
|
|
|
|
//console.log(queryParamsObj.query, queryParamsObj.params);
|
|
|
|
}
|
|
|
|
|
|
|
|
_joinTableNames(isSecondJoin, joinTables, index, queryParamsObj) {
|
|
|
|
if (isSecondJoin) {
|
|
|
|
/**
|
|
|
|
* in second join - there will be ONE table and an ON condition
|
|
|
|
* if clause deals with this
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// add : join / left join / right join / full join / inner join
|
|
|
|
queryParamsObj.query += this.getJoinType(joinTables[index]);
|
|
|
|
queryParamsObj.query += " ?? as ?? ";
|
|
|
|
|
|
|
|
// eg: tbl.tableName
|
|
|
|
let tableNameAndAs = joinTables[index + 1].split(".");
|
|
|
|
|
|
|
|
if (
|
|
|
|
tableNameAndAs.length === 2 &&
|
|
|
|
!(tableNameAndAs[1] in this.sqlConfig.ignoreTables)
|
|
|
|
) {
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[1]);
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[0]);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
console.log("there was no dot for tableName ", joinTables[index + 1]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/**
|
|
|
|
* in first join - there will be TWO tables and an ON condition
|
|
|
|
* else clause deals with this
|
|
|
|
*/
|
|
|
|
|
|
|
|
// first table
|
|
|
|
queryParamsObj.query += " ?? as ?? ";
|
|
|
|
// add : join / left join / right join / full join / inner join
|
|
|
|
queryParamsObj.query += this.getJoinType(joinTables[index + 1]);
|
|
|
|
// second table
|
|
|
|
queryParamsObj.query += " ?? as ?? ";
|
|
|
|
|
|
|
|
let tableNameAndAs = joinTables[index].split(".");
|
|
|
|
if (
|
|
|
|
tableNameAndAs.length === 2 &&
|
|
|
|
!(tableNameAndAs[1] in this.sqlConfig.ignoreTables)
|
|
|
|
) {
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[1]);
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[0]);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
console.log("there was no dot for tableName ", joinTables[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
tableNameAndAs = [];
|
|
|
|
tableNameAndAs = joinTables[index + 2].split(".");
|
|
|
|
if (
|
|
|
|
tableNameAndAs.length === 2 &&
|
|
|
|
!(tableNameAndAs[1] in this.sqlConfig.ignoreTables)
|
|
|
|
) {
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[1]);
|
|
|
|
queryParamsObj.params.push(tableNameAndAs[0]);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
console.log("there was no dot for tableName ", joinTables[index]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareJoinQuery(req, res, queryParamsObj) {
|
|
|
|
queryParamsObj.query = "SELECT ";
|
|
|
|
queryParamsObj.grammarErr = 0;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
/**************** START : get fields ****************/
|
|
|
|
if (req.query._fields) {
|
|
|
|
let fields = req.query._fields.split(",");
|
|
|
|
|
|
|
|
// from _fields to - ??, ??, ?? [col1,col2,col3]
|
|
|
|
for (var i = 0; i < fields.length && !queryParamsObj.grammarErr; ++i) {
|
|
|
|
if (i) {
|
|
|
|
queryParamsObj.query += ",";
|
|
|
|
}
|
|
|
|
queryParamsObj.query += " ?? ";
|
|
|
|
queryParamsObj.params.push(fields[i]);
|
|
|
|
let aliases = fields[i].split(".");
|
|
|
|
if (aliases.length === 2) {
|
|
|
|
queryParamsObj.query += "as " + aliases[0] + "_" + aliases[1];
|
|
|
|
//console.log(queryParamsObj.query);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
queryParamsObj.query += " from ";
|
|
|
|
|
|
|
|
if (queryParamsObj.grammarErr) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************** END : get fields ****************/
|
|
|
|
|
|
|
|
/**************** START : get join + on ****************/
|
|
|
|
let joinTables = req.query._join.split(",");
|
|
|
|
if (joinTables.length < 3) {
|
|
|
|
//console.log('grammar error ', joinTables.length);
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log('jointables.length', joinTables);
|
|
|
|
|
|
|
|
let onCondnCount = 0;
|
|
|
|
|
|
|
|
for (
|
|
|
|
let i = 0;
|
|
|
|
i < joinTables.length - 1 && queryParamsObj.grammarErr === 0;
|
|
|
|
i = i + 2
|
|
|
|
) {
|
|
|
|
onCondnCount++;
|
|
|
|
|
|
|
|
this._joinTableNames(i, joinTables, i, queryParamsObj);
|
|
|
|
|
|
|
|
if (queryParamsObj.grammarErr) {
|
|
|
|
console.log("failed at _joinTableNames", queryParamsObj);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//console.log('after join tables', queryParamsObj);
|
|
|
|
|
|
|
|
let onCondn = "_on" + onCondnCount;
|
|
|
|
let onCondnObj = {};
|
|
|
|
if (onCondn in req.query) {
|
|
|
|
//console.log(onCondn, req.query[onCondn]);
|
|
|
|
onCondnObj = whereHelp.getConditionClause(req.query[onCondn], " on ");
|
|
|
|
//console.log('onCondnObj', onCondnObj);
|
|
|
|
queryParamsObj.query += " on " + onCondnObj.query;
|
|
|
|
queryParamsObj.params = queryParamsObj.params.concat(
|
|
|
|
onCondnObj.params
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
queryParamsObj.grammarErr = 1;
|
|
|
|
//console.log('No on condition: ', onCondn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i === 0) {
|
|
|
|
i = i + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**************** END : get join + on ****************/
|
|
|
|
|
|
|
|
if (queryParamsObj.grammarErr) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
this.getWhereClause(
|
|
|
|
req.query._where,
|
|
|
|
" ignore ",
|
|
|
|
queryParamsObj,
|
|
|
|
" where "
|
|
|
|
);
|
|
|
|
this._getGrpByHavingOrderBy(req, "ignore", queryParamsObj, 5);
|
|
|
|
//console.log('after where',queryParamsObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (queryParamsObj.grammarErr) {
|
|
|
|
queryParamsObj.query = "";
|
|
|
|
queryParamsObj.params = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
return queryParamsObj;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//expose class
|
|
|
|
module.exports = Xsql;
|