-
Notifications
You must be signed in to change notification settings - Fork 0
/
DBOperations.js
127 lines (118 loc) · 4.08 KB
/
DBOperations.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const sql = require("mssql");
class Database {
constructor(config) {
this.pool = new sql.ConnectionPool(config);
this.poolConnect = this.pool.connect();
this.pool.on("error", async (err) => {
console.error("SQL Pool Error:", err);
if (err.code === "ECONNRESET" || err.code === "ETIMEDOUT") {
try {
await this.reconnect();
} catch (reconnectError) {
console.error(
"Failed to reconnect after pool error:",
reconnectError
);
}
}
});
}
async reconnect() {
console.log("Attempting to reconnect to database...");
try {
await this.pool.close();
this.pool = new sql.ConnectionPool(this.pool.config);
this.poolConnect = this.pool.connect();
await this.poolConnect;
console.log("Reconnected to database successfully.");
} catch (error) {
console.error("Failed to reconnect to database:", error);
throw error;
}
}
async query(sqlQuery, params = {}, retries = 3) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
await this.poolConnect;
const request = this.pool.request();
for (const [key, value] of Object.entries(params)) {
request.input(key, value);
}
const result = await request.query(sqlQuery);
return result;
} catch (err) {
console.error(`SQL Error on attempt ${attempt}:`, err);
if (attempt < retries) {
console.log("Retrying the query...");
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
await this.reconnect();
} else {
throw err;
}
}
}
}
async isExist(tableName, columnName, value, condition = false) {
let whereClause = condition ? `${condition}` : `${columnName} = @value`;
const sqlQuery = `SELECT TOP 1 * FROM ${tableName} WITH (NOLOCK) WHERE ${whereClause}`;
const params = { value };
const result = await this.query(sqlQuery, params);
return result.recordset.length > 0
? Object.values(result.recordset[0])[0]
: false;
}
async getDBValues(tableName, columnName, condition = false) {
let whereClause = condition ? `${condition}` : "1=1";
const sqlQuery = `SELECT ${columnName} FROM ${tableName} WITH (NOLOCK) WHERE ${whereClause}`;
const result = await this.query(sqlQuery);
return result.recordset.length > 0 ? result.recordset : false;
}
async insertDBValues(tableName, values) {
const columns = [];
const paramRefs = [];
const params = {};
for (const [key, value] of Object.entries(values)) {
columns.push(key);
paramRefs.push(
typeof value === "string" && value.toUpperCase() === "GETDATE()"
? value
: `@${key}`
);
if (typeof value !== "string" || value.toUpperCase() !== "GETDATE()") {
params[key] = value;
}
}
const columnsString = columns.join(", ");
const paramRefsString = paramRefs.join(", ");
const sqlQuery = `INSERT INTO ${tableName} (${columnsString}) VALUES (${paramRefsString}); SELECT SCOPE_IDENTITY() AS KeyID`;
const result = await this.query(sqlQuery, params);
return result.recordset.length > 0
? Object.values(result.recordset[0])[0]
: false;
}
async updateDBValues(tableName, values, condition) {
const setClauses = [];
const params = {};
for (const [key, value] of Object.entries(values)) {
setClauses.push(
`${key} = ${
typeof value === "string" && value.toUpperCase() === "GETDATE()"
? value
: `@${key}`
}`
);
if (typeof value !== "string" || value.toUpperCase() !== "GETDATE()") {
params[key] = value;
}
}
const setClause = setClauses.join(", ");
const sqlQuery = `UPDATE ${tableName} SET ${setClause} WHERE ${condition}`;
const result = await this.query(sqlQuery, params);
return result.rowsAffected[0] > 0;
}
async truncateTable(tableName) {
const sqlQuery = `TRUNCATE TABLE ${tableName}`;
await this.query(sqlQuery);
}
}
module.exports = Database;