diff --git a/src/backup/slave.js b/src/backup/slave.js index 28ec1d3..1dee013 100644 --- a/src/backup/slave.js +++ b/src/backup/slave.js @@ -315,7 +315,7 @@ function deleteTableData(data) { data.forEach(r => r.t_name in delete_needed ? delete_needed[r.t_name].push(r.id) : delete_needed[r.t_name] = [r.id]); let queries = []; for (let table in delete_needed) - queries.push(`DELETE FROM ${table} WHERE id IN (${delete_needed[table]})`); + queries.push("DELETE FROM ?? WHERE id IN (?)", [table, delete_needed[table]]); DB.transaction(queries).then(_ => resolve(true)).catch(error => reject(error)); }) } @@ -326,9 +326,10 @@ function updateTableData(table, data) { return resolve(null); let cols = Object.keys(data[0]); let values = data.map(r => cols.map(c => validateValue(r[c]))); - let statement = `INSERT INTO ${table} (${cols}) VALUES ?` + - " ON DUPLICATE KEY UPDATE " + cols.map(c => `${c}=VALUES(${c})`).join(); - DB.query(statement, [values]).then(_ => resolve(true)).catch(error => reject(error)); + let statement = "INSERT INTO ?? (??) VALUES ? ON DUPLICATE KEY UPDATE " + Array(cols.length).fill("??=VALUES(??)").join(); + let query_values = [table, cols, values]; + cols.forEach(c => query_values.push(c, c)); + DB.query(statement, query_values).then(_ => resolve(true)).catch(error => reject(error)); }) } @@ -336,7 +337,7 @@ const validateValue = val => (typeof val === "string" && /\.\d{3}Z$/.test(val)) function verifyChecksum(checksum_ref) { return new Promise((resolve, reject) => { - DB.query("CHECKSUM TABLE " + Object.keys(checksum_ref).join()).then(result => { + DB.query("CHECKSUM TABLE ??", [Object.keys(checksum_ref)]).then(result => { let checksum = Object.fromEntries(result.map(r => [r.Table.split(".").pop(), r.Checksum])); let mismatch = []; for (let table in checksum) @@ -375,7 +376,7 @@ function requestHash(tables) { function verifyHash(hashes) { const getHash = table => new Promise((res, rej) => { - DB.query("SHOW COLUMNS FROM " + table).then(result => { + DB.query("SHOW COLUMNS FROM ??", [table]).then(result => { let columns = result.map(r => r["Field"]).sort(); DB.query(`SELECT CEIL(id/${HASH_N_ROW}) as group_id, MD5(GROUP_CONCAT(${columns.map(c => `IFNULL(${c}, "NULL")`).join()})) as hash FROM ${table} GROUP BY group_id ORDER BY group_id`) .then(result => res(Object.fromEntries(result.map(r => [r.group_id, r.hash])))) @@ -403,8 +404,8 @@ function verifyHash(hashes) { //Data to be deleted (incorrect data will be added by resync) let id_end = result[t].value[1].map(i => i * HASH_N_ROW); //eg if i=2 AND H_R_C = 5 then id_end = 2 * 5 = 10 (ie, range 6-10) Promise.allSettled(id_end.map(i => - DB.query(`DELETE FROM ${tables[t]} WHERE id BETWEEN ${i - HASH_N_ROW + 1} AND ${i}`))) //eg, i - HASH_N_ROW + 1 = 10 - 5 + 1 = 6 - .then(_ => null); + DB.query("DELETE FROM ?? WHERE id BETWEEN ? AND ?", [tables[t], i - HASH_N_ROW + 1, i]) //eg, i - HASH_N_ROW + 1 = 10 - 5 + 1 = 6 + )).then(_ => null); } else console.error(result[t].reason); //console.debug("Hash-mismatch", mismatch); diff --git a/src/backup/sync.js b/src/backup/sync.js index 0f3f7d4..86e0eee 100644 --- a/src/backup/sync.js +++ b/src/backup/sync.js @@ -54,7 +54,7 @@ function backupSync_delete(last_time, ws) { function backupSync_data(last_time, ws) { const sendTable = (table, id_list) => new Promise((res, rej) => { - DB.query(`SELECT * FROM ${table} WHERE id IN (${id_list})`) + DB.query("SELECT * FROM ?? WHERE id IN (?)", [table, id_list]) .then(data => { ws.send(JSON.stringify({ table, @@ -99,7 +99,7 @@ function backupSync_checksum(ws) { let tableList = result.map(r => r['t_name']); if (!tableList.length) return resolve("checksum"); - DB.query("CHECKSUM TABLE " + tableList.join()).then(result => { + DB.query("CHECKSUM TABLE ??", [tableList]).then(result => { let checksum = Object.fromEntries(result.map(r => [r.Table.split(".").pop(), r.Checksum])); ws.send(JSON.stringify({ command: "SYNC_CHECKSUM", @@ -120,7 +120,7 @@ function backupSync_checksum(ws) { function sendTableHash(tables, ws) { const getHash = table => new Promise((res, rej) => { - DB.query("SHOW COLUMNS FROM " + table).then(result => { + DB.query("SHOW COLUMNS FROM ??", [table]).then(result => { let columns = result.map(r => r["Field"]).sort(); DB.query(`SELECT CEIL(id/${HASH_N_ROW}) as group_id, MD5(GROUP_CONCAT(${columns.map(c => `IFNULL(${c}, "NULL")`).join()})) as hash FROM ${table} GROUP BY group_id ORDER BY group_id`) .then(result => res(Object.fromEntries(result.map(r => [r.group_id, r.hash])))) @@ -196,7 +196,7 @@ function tableSync_data(tables, ws) { const sendTable = (table, group_id) => new Promise((res, rej) => { let id_end = group_id * HASH_N_ROW, id_start = id_end - HASH_N_ROW + 1; - DB.query(`SELECT * FROM ${table} WHERE id BETWEEN ? AND ?`, [id_start, id_end]).then(data => { + DB.query("SELECT * FROM ?? WHERE id BETWEEN ? AND ?", [table, id_start, id_end]).then(data => { ws.send(JSON.stringify({ table, command: "SYNC_UPDATE", @@ -245,7 +245,7 @@ function tableSync_data(tables, ws) { function tableSync_checksum(tables, ws) { return new Promise((resolve, reject) => { - DB.query("CHECKSUM TABLE " + tables.join()).then(result => { + DB.query("CHECKSUM TABLE ??", [tables]).then(result => { let checksum = Object.fromEntries(result.map(r => [r.Table.split(".").pop(), r.Checksum])); ws.send(JSON.stringify({ command: "SYNC_CHECKSUM", diff --git a/src/market.js b/src/market.js index ce948bf..575cd2c 100644 --- a/src/market.js +++ b/src/market.js @@ -202,14 +202,14 @@ function cancelOrder(type, id, floID) { tableName = "SellOrder"; else return reject(INVALID(eCode.INVALID_TYPE, "Invalid Order type! Order type must be buy (or) sell")); - DB.query(`SELECT floID, asset FROM ${tableName} WHERE id=?`, [id]).then(result => { + DB.query("SELECT floID, asset FROM ?? WHERE id=?", [tableName, id]).then(result => { if (result.length < 1) return reject(INVALID(eCode.NOT_FOUND, "Order not found!")); else if (result[0].floID !== floID) return reject(INVALID(eCode.NOT_OWNER, "Order doesnt belong to the current user")); let asset = result[0].asset; //Delete the order - DB.query(`DELETE FROM ${tableName} WHERE id=?`, [id]).then(result => { + DB.query("DELETE FROM ?? WHERE id=?", [tableName, id]).then(result => { resolve(tableName + "#" + id + " cancelled successfully"); coupling.initiate(asset); }).catch(error => reject(error)); @@ -272,7 +272,7 @@ function getTransactionDetails(txid) { type = 'trade'; } else return reject(INVALID(eCode.INVALID_TX_ID, "Invalid TransactionID")); - DB.query(`SELECT * FROM ${tableName} WHERE txid=?`, [txid]).then(result => { + DB.query("SELECT * FROM ?? WHERE txid=?", [tableName, txid]).then(result => { if (result.length) { let details = result[0]; details.type = type; diff --git a/src/price.js b/src/price.js index c32fd3c..2139aa9 100644 --- a/src/price.js +++ b/src/price.js @@ -50,40 +50,44 @@ function getPastRate(asset, hrs = 24) { function getHistory(asset, duration = '') { return new Promise((resolve, reject) => { - duration = getHistory.validateDuration(duration); - let statement = "SELECT " + - (!duration || duration.endsWith("month") || duration.endsWith("year") ? "DATE(rec_time) AS time, AVG(rate) as rate" : "rec_time AS time, rate") + - " FROM PriceHistory WHERE asset=?" + (duration ? " AND rec_time >= NOW() - INTERVAL " + duration : "") + - (!duration || duration.endsWith("month") || duration.endsWith("year") ? " GROUP BY time" : "") + - " ORDER BY time"; - DB.query(statement, [asset]) + let { statement, values } = getHistory.getRateStatement(asset, duration); + DB.query(statement, values) .then(result => resolve(result)) .catch(error => reject(error)) }); } -getHistory.validateDuration = duration => { +getHistory.statement = { + 'all-time': "SELECT DATE(rec_time) AS time, AVG(rate) as rate FROM PriceHistory WHERE asset=? GROUP BY time ORDER BY time", + 'year': "SELECT DATE(rec_time) AS time, AVG(rate) as rate FROM PriceHistory WHERE asset=? AND rec_time >= NOW() - INTERVAL ? year GROUP BY time ORDER BY time", + 'month': "SELECT DATE(rec_time) AS time, AVG(rate) as rate FROM PriceHistory WHERE asset=? AND rec_time >= NOW() - INTERVAL ? month GROUP BY time ORDER BY time", + 'week': "SELECT rec_time AS time, rate FROM PriceHistory WHERE asset=? AND rec_time >= NOW() - INTERVAL ? week ORDER BY time", + 'day': "SELECT rec_time AS time, rate FROM PriceHistory WHERE asset=? AND rec_time >= NOW() - INTERVAL ? day ORDER BY time" +} + +getHistory.getRateStatement = (asset, duration) => { let n = duration.match(/\d+/g), d = duration.match(/\D+/g); n = n ? n[0] || 1 : 1; d = d ? d[0].replace(/[-\s]/g, '') : ""; + switch (d.toLowerCase()) { case "day": case "days": - return n + " day"; + return { statement: getHistory.statement['day'], values: [asset, n] }; case "week": case "weeks": - return n + " week"; + return { statement: getHistory.statement['week'], values: [asset, n] }; case "month": case "months": - return n + " month"; + return { statement: getHistory.statement['month'], values: [asset, n] }; case "year": case "years": - return n + " year"; + return { statement: getHistory.statement['year'], values: [asset, n] }; case "alltime": - return null; + return { statement: getHistory.statement['all-time'], values: [asset] }; default: - return '1 day'; + return { statement: getHistory.statement['day'], values: [asset, 1] }; } }