Improve SQL queries

This commit is contained in:
sairajzero 2023-03-11 23:23:17 +05:30
parent 586c2375fd
commit 6538d9e2d6
4 changed files with 35 additions and 30 deletions

View File

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

View File

@ -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",

View File

@ -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;

View File

@ -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] };
}
}