UNPKG

touchway-sqlite

Version:

Touchway SQLite to JSON wrapper

1,132 lines (935 loc) 98.1 kB
'use strict' var sqlite3 = require('sqlite3'); const COLUMNTYPE = { NM: "N:M", FK: "1:N", DEFAULT: "Default column", PK: "Primary key" }; function TouchwaySQLite() { TouchwaySQLite.prototype.init = function (databasePath) { return new Promise(function (fulfill, reject) { // var tmpDB = new sqlite3.Database(databasePath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, function (err) { return new TWSqlite(databasePath).initialize().then(function (ref) { fulfill(ref); }).catch(function (err) { reject(err); }); // }); }); } class TWDataTypeHelper { static isObject(value) { return value && typeof value === 'object' && value.constructor === Object; } } class TWSqlite { constructor(databasePath) { this._databasePath = databasePath; this._db = null; this._connections = {}; this._definitions = null; this._restrictions = {}; } open() { let ref = this; return new Promise(function (fulfill, reject) { if (!ref._db || ref._db === null) { ref._db = new sqlite3.Database(ref._databasePath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, function (err) { if (err) { reject(err); } else { // ref._connections[ref._databasePath] = this._db; // console.log("SET!"); fulfill(ref._db); } }); }else{ console.log("REUSE!"); fulfill(ref._db); } }); }; close(){ try{ this._db.close(); }catch(err){ } } initialize() { let ref = this; return new Promise(function (fulfill, reject) { if (!ref._definitions) { ref.getDefinitions().then(function (definitionsResult) { ref._definitions = definitionsResult; fulfill(ref); }).catch(function (err) { reject(err); }); } else { fulfill(ref); } }); } resolveForeignKeys(value) { if (typeof value === "undefined") value = true; this._resolveForeignKeys = value; } setLimit(value) { if (typeof value === "undefined") return; this._limit = value; } setOffset(value) { if (typeof value === "undefined") return; this._offset = value; } setRestriction(key, valueArr) { if (typeof key === "undefined" || !key) return; if (typeof valueArr === "undefined" || !valueArr || !Array.isArray(valueArr)) return; this._restrictions[key] = valueArr; } setRestrictions(restrictionTree) { if (typeof restrictionTree === "undefined" || !restrictionTree) return; this._restrictions = Object.assign(this._restrictions, restrictionTree); } prepare(tableName, action, selectors, conditions) { if (typeof tableName === "undefined") throw "No table specified"; if (typeof action === "undefined") throw "No action specified"; this._selectors = selectors; let newRef = new TWSqlite(this._databasePath); newRef._definitions = this._definitions; newRef._tableName = tableName; newRef._resolveForeignKeys = this._resolveForeignKeys; newRef._limit = this._limit; newRef._offset = this._offset; newRef._action = (typeof action !== "undefined" && action) ? String(action).trim().toUpperCase() : "SELECT"; newRef._selectors = (typeof selectors !== "undefined" && selectors) ? this.filterSelectors(selectors, tableName) : []; newRef._conditions = (typeof conditions !== "undefined" && conditions) ? this.filterConditions(conditions, tableName) : []; return newRef; } filterConditions(conditions, table) { let ref = this; let tmpObj = {}; for (let i in conditions) { if (!ref._definitions.hasOwnProperty(table) || !ref._definitions[table].hasOwnProperty(i)) continue; tmpObj[i] = conditions[i]; } return tmpObj; } filterSelectors(selectorArray, table) { let ref = this; let tmpArr = []; for (let i in selectorArray) { let tmpI = selectorArray[i]; if (!ref._definitions.hasOwnProperty(table) || !ref._definitions[table].hasOwnProperty(tmpI)) continue; tmpArr.push(tmpI); } return tmpArr; } getDefinitions() { let ref = this; return new Promise(function (fulfill, reject) { //console.time("dbsave"); let tmpDefinitions = {}; ref.getTables().then(function (tableResult) { let promises = []; for (let t in tableResult) { promises.push(ref.getColumns(t)); } Promise.all(promises).then(values => { for (let v in values) { let row = values[v]; tmpDefinitions[row.table] = row.columns } fulfill(tmpDefinitions); }).catch(function (err) { reject(err); }); }); }); } getTables() { let ref = this; return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let tables = {}; //db.serialize(function () { db.all("SELECT * FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'SQL%'", {}, (err, rows) => { if (err) { reject(err); } else { for (let r in rows) { let row = rows[r]; tables[row.name] = row.type; } fulfill(tables); } }); //}); //db.close(); }).catch(function (err) { reject(err); }); }); }; getNMTables(tableName) { let ref = this; return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let tables = {}; //db.serialize(function () { db.all("SELECT * FROM sqlite_master WHERE type = 'table' AND name LIKE '%/_%' ESCAPE '/' AND name NOT LIKE '%Admin%' AND name NOT LIKE 'SQL%' AND name LIKE '%" + tableName + "%' AND name <> '" + tableName + "'", {}, (err, rows) => { if (err) { reject(err); } else { for (let r in rows) { let row = rows[r]; tables[row.name] = row.type; } fulfill(tables); } }); //}); //db.close(); }).catch(function (err) { reject(err); }); }); }; getColumns(tableName) { let ref = this; let tableToQuery = this._tableName; if (typeof tableName !== "undefined" && tableName) { tableToQuery = tableName; } return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let columns = {}; ref.getTables().then(function (tables) { ref.getNM(tableToQuery).then(function (result) { //db.serialize(function () { db.all("PRAGMA table_info(" + tableToQuery + ")", {}, (err, rows) => { if (err) { reject(err); } else { for (let r in rows) { let row = rows[r]; columns[row.name] = { type: row.type, name: row.name, isPrimaryKey: (row.pk == 1) ? true : false, isForeignKey: tables.hasOwnProperty(row.name), isNMKey: false } } for (let r in result) { let tmpName = r.split('_'); let tableDest = null; if (tmpName[0] == tableToQuery) { tableDest = tmpName[0]; tmpName = tmpName[1]; } else { tableDest = tmpName[1]; tmpName = tmpName[0]; } columns[tmpName] = { type: "INTEGER", name: r, table: r, tableDest: tableDest, isPrimaryKey: false, isForeignKey: false, isNMKey: true } } fulfill({ table: tableName, columns: columns }); } // db.close(); }); //}); }).catch(function (err) { reject(err); }); }).catch(function (err) { reject(err); }); }).catch(function (err) { reject(err); }); }); }; getNM(tableName) { let ref = this; return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let tables = {}; //db.serialize(function () { //console.log("GET NM STATEMENT: ", "SELECT * FROM sqlite_master WHERE name LIKE '%" + tableName + "%' AND name LIKE '%/_%' ESCAPE '/' AND name LIKE '%/_%' ESCAPE '/' AND type = 'table'"); db.all("SELECT * FROM sqlite_master WHERE name LIKE '%" + tableName + "%' AND name LIKE '%/_%' ESCAPE '/' AND name LIKE '%/_%' ESCAPE '/' AND type = 'table'", {}, (err, rows) => { if (err) { reject(err); } else { //console.log("GET NM: ", tableName, rows); for (let i in rows) { let row = rows[i]; if (row.name.indexOf('_') >= 0) { tables[row.name] = row.type; } } fulfill(tables); } }); //}); //db.close(); }).catch(function (err) { reject(err); }); }); }; getForeignKeys(tableName) { let moduleRef = this; return new Promise(function (fulfill, reject) { moduleRef.getTables().then(function (res) { let tables = res; if (!tables.hasOwnProperty(tableName)) { reject(`Table '${tableName}' doesn't exist`); } else { moduleRef.getColumns(tableName).then(function (colResult) { fulfill({ table: tableName, columns: colResult.columns, foreignKeys: moduleRef.commonKeys(colResult, tables) }); }, function (err) { reject(err); }); } }, function (err) { reject(err); }); }); }; findTableOfSelector(selectorName) { let ref = this; //First lets search in origin table try { if (ref._definitions[ref._tableName].hasOwnProperty(selectorName)) return ref._tableName; } catch (err) { } for (let t in ref._definitions) { try { if (ref._definitions[t].hasOwnProperty(selectorName)) return t; } catch (err) { } } return null; } parseSelectors(selectors) { let ref = this; let tmpArr = []; if (typeof selectors !== "undefined" && selectors && selectors.length > 0) { for (let s in selectors) { let tmpSelector = selectors[s]; if (tmpSelector.split('.').length > 1) { tmpArr.push(tmpSelector); continue; } let table = ref.findTableOfSelector(tmpSelector); tmpArr.push((table) ? (table + "." + tmpSelector) : tmpSelector); } } return tmpArr; } getNMSelectors(selectors) { let ref = this; let tmpArr = []; if (selectors.length > 0) { for (let s in selectors) { let tmpSelector = selectors[s]; let tmpSelectorTable = ref._tableName; let tmpSelectorSplitted = tmpSelector.split('.'); if (tmpSelectorSplitted.length > 1) { tmpSelectorTable = tmpSelectorSplitted[0]; tmpSelector = tmpSelectorSplitted[1]; } else { let tmpFindTable = ref.findTableOfSelector(tmpSelector); tmpSelectorTable = (tmpFindTable) ? tmpFindTable : tmpSelectorTable; } //Find table in definition list if (ref._definitions.hasOwnProperty(tmpSelectorTable) && ref._definitions[tmpSelectorTable]) { if (ref._definitions[tmpSelectorTable].hasOwnProperty(tmpSelector) && ref._definitions[tmpSelectorTable][tmpSelector]) { if (ref._definitions[tmpSelectorTable][tmpSelector].isNMKey) { tmpArr.push(tmpSelector); } } } } } // console.log("NM Selectors: ", tmpArr); return tmpArr; } getFKSelectors(selectors) { let ref = this; let tmpArr = []; if (selectors.length > 0) { for (let s in selectors) { let tmpSelector = selectors[s]; let tmpSelectorTable = ref._tableName; let tmpSelectorSplitted = tmpSelector.split('.'); if (tmpSelectorSplitted.length > 1) { tmpSelectorTable = tmpSelectorSplitted[0]; tmpSelector = tmpSelectorSplitted[1]; } else { let tmpFindTable = ref.findTableOfSelector(tmpSelector); tmpSelectorTable = (tmpFindTable) ? tmpFindTable : tmpSelectorTable; } //Find table in definition list if (ref._definitions.hasOwnProperty(tmpSelectorTable) && ref._definitions[tmpSelectorTable]) { if (ref._definitions[tmpSelectorTable].hasOwnProperty(tmpSelector) && ref._definitions[tmpSelectorTable][tmpSelector]) { if (ref._definitions[tmpSelectorTable][tmpSelector].hasOwnProperty("isForeignKey") && ref._definitions[tmpSelectorTable][tmpSelector].isForeignKey) { tmpArr.push(tmpSelector); } } } } } return tmpArr; } generateNM(selectors) { let ref = this; let tmpArr = {}; let nmColumns = ref.getNMSelectors(selectors); for (let n in nmColumns) { tmpArr[nmColumns[n]] = (ref.generateNMStatement(ref._tableName, nmColumns[n])); } return tmpArr; } generateFK(selectors, table) { let ref = this; let tmpArr = {}; let nmColumns = ref.getFKSelectors(selectors); for (let n in nmColumns) { tmpArr[nmColumns[n]] = (ref.generateFKStatement(ref._tableName || table, nmColumns[n])); // console.log(` // ========================================================================================== // NM COLUMNS: ${nmColumns[n]} // GENERATED FK STATEMENT: ${tmpArr[nmColumns[n]]} // ========================================================================================== // `); } return tmpArr; } /*generateFKInsert(table, data) { let ref = this; let tmpArr = {}; let nmColumns = ref.getFKSelectors(selectors); for (let n in nmColumns) { tmpArr[nmColumns[n]] = (ref.generateFKInsertStatement(table, data)); } return tmpArr; }*/ generateFKStatement(table1, table2) { let ref = this; let columnsTable1 = ref._definitions[table1]; if (columnsTable1.hasOwnProperty(table2)) { let primaryKeyTable2 = ref.getPrimaryKey(table2); if (!primaryKeyTable2) return; let tmpNMTablename = table2; let tmpSQLobj = new TWSqlStatement(table2, [table2 + ".*"]); tmpSQLobj.isFK = true; tmpSQLobj.NMTable = tmpNMTablename; tmpSQLobj.addJoin(table2, table1, primaryKeyTable2, table2); return tmpSQLobj; } return null; } /*generateFKInsertStatement(table1, table2) { let ref = this; let columnsTable1 = ref._definitions[table1]; if (columnsTable1.hasOwnProperty(table2)) { let primaryKeyTable2 = ref.getPrimaryKey(table2); if (!primaryKeyTable2) return; let tmpNMTablename = table2; let tmpSQLobj = new TWSqlStatement(table2, [table2 + ".*"]); tmpSQLobj.isFK = true; tmpSQLobj.NMTable = tmpNMTablename; tmpSQLobj.addJoin(table2, table1, primaryKeyTable2, table2); return tmpSQLobj; } return null; }*/ generateNMStatement(table1, table2) { let ref = this; let columnsTable1 = ref._definitions[table1]; if (columnsTable1.hasOwnProperty(table2)) { let primaryKeyTable2 = ref.getPrimaryKey(table2); if (!primaryKeyTable2) return; let tmpNMTablename = (table1 > table2) ? table2 + "_" + table1 : table1 + "_" + table2; let tmpSQLobj = new TWSqlStatement(table2, [table2 + ".*"]); tmpSQLobj.NMTable = tmpNMTablename; tmpSQLobj.addJoin(table2, tmpNMTablename, primaryKeyTable2, table2); return tmpSQLobj; } return null; } isValidColumn(tableName, column) { let ref = this; if (ref._definitions.hasOwnProperty(tableName) && ref._definitions[tableName] && ref._definitions[tableName].hasOwnProperty(column)) { return true; } return false; } getPrimaryKey(tableName) { let ref = this; if (ref._definitions.hasOwnProperty(tableName) && ref._definitions[tableName]) { let columns = ref._definitions[tableName]; for (let c in columns) { if (columns.hasOwnProperty(c) && columns[c] && columns[c].hasOwnProperty("isPrimaryKey") && columns[c].isPrimaryKey) { return c; } } } return null; } getPrimaryKeyValue(node, tableName) { if (typeof node === "undefined" || typeof tableName === "undefined") return null; let ref = this; let primaryKeyColumn = ref.getPrimaryKey(tableName); if (primaryKeyColumn) { if (node.hasOwnProperty(primaryKeyColumn) && node[primaryKeyColumn]) { return node[primaryKeyColumn]; } } return null; } getKeyType(tableName, key) { let ref = this; if (ref._definitions.hasOwnProperty(tableName) && ref._definitions[tableName]) { let columns = ref._definitions[tableName]; if (columns && columns.hasOwnProperty(key) && columns[key]) { if (columns[key].isForeignKey) return COLUMNTYPE.FK; if (columns[key].isNMKey) return COLUMNTYPE.NM; return COLUMNTYPE.DEFAULT; } } return null; } generateNMTableName(table1, table2) { if (typeof table1 === "undefined" || !table1 || typeof table2 === "undefined" || !table2) return null; if (table1 < table2) return table1 + "_" + table2; else return table2 + "_" + table1; } executeRAW(sql) { let ref = this; return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let tables = {}; db.all(sql, {}, (err, rows) => { if (err) { reject(err); } else { fulfill(rows); } }); }).catch(function (err) { reject(err); }); }); }; executeJSON(data, action, table) { let ref = this; return new Promise(function (fulfill, reject) { ref.open().then(function (db) { let primaryKeyColumn = ref.getPrimaryKey(table); let primaryKeyValue = null; // console.log("============================================="); // console.log(" Table: ", table); // console.log(" PrimaryKeyColumn: ", primaryKeyColumn); if (data.hasOwnProperty(primaryKeyColumn) && data[primaryKeyColumn]) { primaryKeyValue = data[primaryKeyColumn]; } // console.log(" PrimaryKeyValue: ", primaryKeyValue); let isUpdate = (primaryKeyValue !== null); let isInsert = (primaryKeyValue === null); // console.log(" Is update: ", isUpdate); // console.log(" Is insert: ", isInsert); // console.log(" Data: ", data); let nmQueries = []; let fkPromises = []; if (isInsert) { let sqlSetValues = {}; let sqlSetParts = []; let sqlSetPartsWithDollar = []; for (let key in data) { if (!ref.isValidColumn(table, key)) { console.log(" [!] WARN: Column '" + key + "' doesn't exist"); continue; } let value = data[key]; switch (ref.getKeyType(table, key)) { case COLUMNTYPE.FK: { let fkValue = null; if (TWDataTypeHelper.isObject(value)) { fkValue = ref.getPrimaryKeyValue(value, key); if (fkValue == null && Object.values(value).length > 0) { fkPromises.push(ref.executeJSON(value, action, key)); } } else { fkValue = value; } sqlSetValues["$" + key] = fkValue; sqlSetParts.push(key); sqlSetPartsWithDollar.push("$" + key); } break; case COLUMNTYPE.DEFAULT: { if (key == primaryKeyColumn) continue; sqlSetValues["$" + key] = value; sqlSetParts.push(key); sqlSetPartsWithDollar.push("$" + key); } break; } } Promise.all(fkPromises).then(values => { for (let v in values) { let currentValue = values[v]; if (currentValue.hasOwnProperty("ID")) { sqlSetValues["$" + currentValue.table] = currentValue.ID; } } let sql = "INSERT INTO " + table + " (" + sqlSetParts.join(', ') + ") VALUES (" + sqlSetPartsWithDollar.join(', ') + ")"; // console.log("SQL: ", sql, "\nVALUES:", sqlSetValues); db.run(sql, sqlSetValues, function (err) { if (err) { console.error("SQL ERROR: ", err, " QUERY WAS: ", sql); reject(err); } else { let insertID = this.lastID || 0; let changes = this.changes || false; //Inject new insert ID into original data, in order to be returned data[primaryKeyColumn] = insertID; if (insertID && changes) { ref.executeJSON(data, action, table).then(function (insertResult) { var tmpFulFill = { result: insertResult.result, table: table, ID: insertID || null }; fulfill(tmpFulFill); }).catch(function (insertErr) { reject(insertErr); }); } else { reject("No Insert ID returned"); } } }); }).catch(function (err) { reject(err); }); } if (isUpdate) { //nmQueries.push("BEGIN TRANSACTION"); let sqlSetValues = {}; let sqlSetParts = []; //Add primary key to placeholder values sqlSetValues["$" + primaryKeyColumn] = primaryKeyValue; for (let key in data) { let value = data[key]; if (!ref.isValidColumn(table, key)) { console.log(" [!] WARN: Column '" + key + "' doesn't exist"); continue; } switch (ref.getKeyType(table, key)) { case COLUMNTYPE.FK: { let fkValue = null; if (TWDataTypeHelper.isObject(value)) { //fkValue = ref.getPrimaryKeyValue(value, key); if (Object.values(value).length > 0) { fkPromises.push(ref.executeJSON(value, action, key)); } } else { fkValue = value; } // console.log("\n\nFKK!!!!!!!!!!!!!!!!!", key, fkValue, "\n\n"); sqlSetValues["$" + key] = fkValue; sqlSetParts.push(key + " = $" + key); } break; case COLUMNTYPE.NM: { let primaryKeyColumnNM = ref.getPrimaryKey(key); let nmTableName = ref.generateNMTableName(table, key); let tmpSQLDelete = "DELETE FROM " + nmTableName + " WHERE " + table + " IN (" + ((typeof primaryKeyValue.join === "function") ? primaryKeyValue.join(', ') : primaryKeyValue) + ")"; nmQueries.push(tmpSQLDelete); if (Array.isArray(value)) { for (let i in value) { if (value.hasOwnProperty(i) && value[i] && value[i].hasOwnProperty(primaryKeyColumnNM) && value[i][primaryKeyColumnNM]) { let tmpI = value[i][primaryKeyColumnNM]; let tmpSQLPKV = null; if (Array.isArray(primaryKeyValue)) { for (let iPK in primaryKeyValue) { let tmpPKV = primaryKeyValue[iPK]; tmpSQLPKV = "INSERT OR REPLACE INTO " + nmTableName + " (" + table + ", " + key + ") VALUES (" + tmpPKV + "," + tmpI + ")"; nmQueries.push(tmpSQLPKV); //db.run(tmpSQLPKV); } } else { tmpSQLPKV = "INSERT OR REPLACE INTO " + nmTableName + " (" + table + ", " + key + ") VALUES (" + primaryKeyValue + "," + tmpI + ")"; //db.run(tmpSQLPKV); } nmQueries.push(tmpSQLPKV); } } } } break; default: { if (key == primaryKeyColumn) continue; sqlSetValues["$" + key] = value; sqlSetParts.push(key + " = $" + key); } break; } } Promise.all(fkPromises).then(values => { for (let v in values) { let currentValue = values[v]; // console.log("FK PROMISES RETURN: ", currentValue); if (currentValue.hasOwnProperty("ID")) { sqlSetValues["$" + currentValue.table] = currentValue.ID; } } let sql = "UPDATE " + table + " SET " + sqlSetParts.join(', ') + " WHERE "; if (Array.isArray(primaryKeyValue)) { sql += primaryKeyColumn + " IN (" + primaryKeyValue.join(', ') + ")"; } else { sql += primaryKeyColumn + " = $" + primaryKeyColumn; } db.serialize(function () { db.run("BEGIN TRANSACTION"); if (sqlSetParts && sqlSetParts.length > 0) { db.run(sql, sqlSetValues, function (err) { if (err) { console.error(err, "SQL: ", sql, " VALUES: ", sqlSetValues); } else { // console.log("DB RUN result: ", this); // console.log("DB RUN values: ", sqlSetValues); // console.log("DB PRIMARY KEY VALUE: ", primaryKeyValue); } }); } for (let i in nmQueries) { let singleQuery = nmQueries[i]; // console.log(" [*] run: ", singleQuery); db.run(singleQuery, {}, function (err) { if (err) { console.error(err); } }); } db.run("END", {}, function (err) { if (err) { reject(err); } else { let fulfillResult = { result: data, table: table, ID: primaryKeyValue || this.lastID || null }; // console.log("\n\fulfillResult: ", fulfillResult); fulfill(fulfillResult); } }); }); }).catch(function (err) { reject(err); }); // console.log(); } // console.log("============================================="); }); }); } generate() { let ref = this; let columns = ref._definitions[ref._tableName]; let primaryKeyColumn = null; for (let c in columns) { if (columns.hasOwnProperty(c) && columns[c] && columns[c].hasOwnProperty("isPrimaryKey") && columns[c].isPrimaryKey) { primaryKeyColumn = c; break; } } switch (ref._action) { case "REMOVE": case "DELETE": { let sql = new TWSqlDeleteStatement(ref._tableName, ref._conditions); sql.primaryKeyColumn = primaryKeyColumn; sql.setParsedSelectors(ref.parseSelectors(ref._selectors)); sql.ID = ref._selectors[primaryKeyColumn] || ref._conditions[primaryKeyColumn]; //console.log("DELETE STATEMENT: ", sql.debug().toSQL(), " VALUES: ", sql.values); return sql; } break; case "PUT": case "STORE": case "WRITE": case "UPDATE": case "INSERT": case "SAVE": { let tmpSelectors = Object.keys(ref._conditions); let tmpFilteredConditions = ref.filterConditions(ref._conditions, ref._tableName); let tmpFKSelectors = ref.getFKSelectors(tmpSelectors); let nmSelectors = (ref.getNMSelectors(Object.keys(ref._conditions))); let sql = new TWSqlInsertStatement(ref._tableName, ref._conditions, null); sql.rawData = Object.assign({}, ref._conditions); sql.primaryKeyColumn = primaryKeyColumn; sql.ID = tmpSelectors[primaryKeyColumn] || ref._conditions[primaryKeyColumn]; if (sql.ID) { if (Array.isArray(sql.ID)) { sql.addInCondition(primaryKeyColumn, "IN", sql.ID); sql.removeSelector(primaryKeyColumn); } else { sql.addCondition(primaryKeyColumn, "=", sql.ID, ref._tableName); } } for (let i in tmpFKSelectors) { let tmpI = tmpFKSelectors[i]; if (ref._conditions.hasOwnProperty(tmpI) && ref._conditions[tmpI]) { if (TWDataTypeHelper.isObject(ref._conditions[tmpI])) { let tmpSubData = (ref._conditions.hasOwnProperty(tmpI)) ? JSON.parse(JSON.stringify(ref._conditions[tmpI])) : []; if (!tmpSubData || Object.keys(tmpSubData) <= 0) continue; //if no data node let subSqlObj = ref.prepare(tmpI, ref._action, null, tmpSubData).generate(); subSqlObj.isFK = true; let fkPrimaryKey = ref.getPrimaryKey(tmpI); if (!sql.hasOwnProperty("FK")) { sql.FK = {}; } if (!sql.hasOwnProperty(tmpI)) { sql.FK[tmpI] = []; } sql.FK[tmpI].push(subSqlObj); } else { //console.log("NOT A EXTENDED OBJECT: ", ref._conditions[tmpI]); } } } for (let i in nmSelectors) { let tmpI = nmSelectors[i]; if (ref._conditions.hasOwnProperty(tmpI)) { let tmpSubData = (ref._conditions.hasOwnProperty(tmpI)) ? JSON.parse(JSON.stringify(ref._conditions[tmpI])) : []; if (!sql.hasOwnProperty("NM")) { sql.NM = {}; } if (!sql.NM.hasOwnProperty(tmpI)) { sql.NM[tmpI] = []; } for (let subI in tmpSubData) { let tmpSubDataI = tmpSubData[subI]; let backupSubData = Object.assign({}, tmpSubDataI); let tmpSubConditions = {}; if (tmpSubDataI.hasOwnProperty(primaryKeyColumn)) { tmpSubConditions[primaryKeyColumn] = tmpSubDataI[primaryKeyColumn]; } let subSqlObj = ref.prepare(tmpI, ref._action, tmpSubDataI, tmpSubConditions).generate(); subSqlObj.isNM = true; subSqlObj.rawData = backupSubData; if (tmpSubDataI.hasOwnProperty(primaryKeyColumn)) { subSqlObj.ID = tmpSubDataI[primaryKeyColumn]; delete tmpSubDataI[primaryKeyColumn]; } sql.NM[tmpI].push(subSqlObj); } } sql.removeSelector(tmpI); } return sql; } break; default: { let sql = new TWSqlStatement(ref._tableName, ref._selectors); sql.depth = 0; sql.limit = (typeof ref._limit !== "undefined") ? ref._limit : 1000; sql.offset = (typeof ref._offset !== "undefined") ? ref._offset : 0; sql.primaryKeyColumn = primaryKeyColumn; sql.setParsedSelectors(ref.parseSelectors(ref._selectors)); let tmpNMSelectors = ref.getNMSelectors(ref._selectors); sql.setNMSelectors(tmpNMSelectors); let tmpFKSelectors = ref.getFKSelectors(ref._selectors); sql.setFKSelectors(tmpFKSelectors); sql.NM = ref.generateNM(ref._selectors); sql.FK = ref.generateFK(ref._selectors); if ((sql.NM && Object.keys(sql.NM).length > 0) || (sql.FK && Object.keys(sql.FK).length > 0)) { //Mit Vorsicht zu geniessen sql.addSelector(primaryKeyColumn, ref._tableName); } //Add restrictions if (ref._restrictions) { for (let c in ref._restrictions) { let tmpI = ref._restrictions[c]; if (columns.hasOwnProperty(c) && columns[c]) { ref._conditions[c] = tmpI; } if (ref._tableName == c) { let primaryKeyColumn = ref.getPrimaryKey(c); if (typeof ref._conditions[primaryKeyColumn] !== "undefined") { if (tmpI.indexOf(ref._conditions[primaryKeyColumn]) < 0) { ref._conditions[ref.getPrimaryKey(c)] = { "@Operator": "IN", "@Values": tmpI } } } else { ref._conditions[ref.getPrimaryKey(c)] = { "@Operator": "IN", "@Values": tmpI } } } } } //Add contitions // console.log("++++++++++++++++++++++++++++++++: ", ref._conditions); for (let c in ref._conditions) { let tmpC = ref._conditions[c]; if (TWDataTypeHelper.isObject(tmpC)) { if (tmpC.hasOwnProperty("@Operator")) { sql.addConditionNode(c, tmpC, ref._tableName); } else { //Lets make joins only if it's not a special operator if (columns.hasOwnProperty(c) && columns[c]) { //Lets find primary key of columns[c].table let primaryKeyColumnTable2 = null; for (let pkIndex in ref._definitions[c]) { if (ref._definitions[c][pkIndex].isPrimaryKey) { primaryKeyColumnTable2 = pkIndex; } } if (columns[c].hasOwnProperty("table") && columns[c].table) { sql.addJoin(ref._tableName, columns[c].table, primaryKeyColumn, ref._tableName); sql.addJoin(columns[c].table, c, c, primaryKeyColumnTable2); } else { sql.addJoin(ref._tableName, c, c, primaryKeyColumnTable2); } if (Object.keys(tmpC).length > 0) { for (let k in tmpC) { let currentKeyValue = tmpC[k]; //HAT FUNKTIONIERT !!!! //sql.addConditionNode(k, currentKeyValue, c); sql.addConditionNode(c, currentKeyValue, columns[c].table); // console.log("Add condition"); //sql.addConditionNode(c, currentKeyValue, ref._tableName); } }