multi-db-orm 3.0.12 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/engines/hanadb.js CHANGED
@@ -1,244 +1,259 @@
1
- const { MultiDbORM } = require("./multidb");
2
-
3
- class HanaDB extends MultiDbORM {
4
- db;
5
- pool;
6
- dataMap = {
7
- id: "VARCHAR(50) NOT NULL PRIMARY KEY",
8
- string: "NVARCHAR(4000)",
9
- stringlarge: "NCLOB",
10
- stringsmall: "NVARCHAR(255)",
11
- number: "DOUBLE",
12
- boolean: "BOOLEAN",
13
- array: "NCLOB",
14
- object: "NCLOB",
15
- };
16
-
17
- constructor(credentials) {
18
- super();
19
- const hana = require("@sap/hana-client");
20
- this.db = hana;
21
- this.conn_params = {
22
- ...credentials,
23
- host: credentials.host,
24
- port: credentials.port,
25
- serverNode: `${credentials.host}:${credentials.port}`,
26
- uid: credentials.username,
27
- pwd: credentials.password,
28
- databaseName: credentials.database,
29
- communicationTimeout: credentials.connectionLimit || 60000,
30
- connectTimeout: credentials.connectionLimit || 60000,
31
- reconnect: credentials.reconnect ?? true,
32
- poolOptions: {
33
- maxPoolSize: credentials.connectionLimit || 10,
34
- idleTimeout: credentials.timeout || 60000,
35
- },
36
- };
37
- this.pool = hana.createPool(this.conn_params);
38
- this.db = this.pool;
39
- this.dbType = "hana";
40
- this.reqMade = 0;
41
- }
42
-
43
- async run(query) {
44
- const that = this;
45
- this.reqMade++;
46
- return new Promise((resolve, reject) => {
47
- var conn = this.pool.getConnection();
48
- conn.exec(query, (err, result) => {
49
- conn.disconnect();
50
- if (err) {
51
- err.message = err.message + " query=" + query;
52
- reject(err);
53
- } else {
54
- resolve(result);
55
- }
56
- if (that.loglevel > 3) {
57
- console.log("Query", query, "->", result);
58
- }
59
- });
60
- });
61
- }
62
-
63
- async get(modelname, filter, options) {
64
- this.metrics.get(modelname, filter, options);
65
- let where = "";
66
- for (const key in filter) {
67
- where += `"${key}" = '${filter[key]}' AND `;
68
- }
69
- where += "1 = 1";
70
- let sort = "";
71
- if (options) {
72
- if (options.apply) {
73
- if (options.apply.ineq) {
74
- where += ` AND "${options.apply.field}" ${options.apply.ineq.op} '${options.apply.ineq.value}'`;
75
- }
76
- if (options.apply.sort) {
77
- sort = `ORDER BY "${options.apply.field}" ${options.apply.sort}`;
78
- }
79
- } else if (options.sort) {
80
- sort = "ORDER BY";
81
- for (let i = 0; i < options.sort.length; i++) {
82
- sort += ` "${options.sort[i].field}" ${options.sort[i].order}`;
83
- if (i < options.sort.length - 1) {
84
- sort += ", ";
85
- }
86
- }
87
- }
88
- }
89
- const limit = options?.limit ? `LIMIT ${options.limit}` : "";
90
- const offset = options?.offset ? `OFFSET ${options.offset}` : "";
91
- const query = `SELECT * FROM ${modelname} WHERE ${where} ${sort} ${limit} ${offset};`;
92
- return (await this.run(query)) || [];
93
- }
94
- escapeSQLValue(value) {
95
- if (typeof value === "string") {
96
- return `'${value.replace(/'/g, "''")}'`;
97
- } else if (value === null || value === undefined) {
98
- return "NULL";
99
- }
100
- return value;
101
- }
102
- async getOne(modelname, filter) {
103
- this.metrics.getOne(modelname, filter);
104
- let where = "";
105
- for (const key in filter) {
106
- where += `"${key}" = '${filter[key]}' AND `;
107
- }
108
- where += "1 = 1";
109
- const query = `SELECT * FROM ${modelname} WHERE ${where} LIMIT 1;`;
110
- const row = await this.run(query);
111
- return row[0];
112
- }
113
-
114
- async create(modelname, sampleObject) {
115
- this.sync.create(modelname, sampleObject);
116
- this.metrics.create(modelname, sampleObject);
117
-
118
- let cols = "";
119
- for (const key in sampleObject) {
120
- let type;
121
- if (this.dataMap[sampleObject[key]]) {
122
- type = this.dataMap[sampleObject[key]];
123
- } else {
124
- type = this.dataMap[typeof sampleObject[key]] || "NCLOB";
125
- if (typeof sampleObject[key] === "string") {
126
- if (sampleObject[key].length > 4000) {
127
- type = this.dataMap["stringlarge"];
128
- }
129
- if (sampleObject[key].length <= 255) {
130
- type = this.dataMap["stringsmall"];
131
- }
132
- }
133
- }
134
-
135
- if (key.toLowerCase().trim() === "id") {
136
- cols += `"${key}" ${type} PRIMARY KEY NOT NULL ,`;
137
- } else {
138
- cols += `"${key}" ${type},`;
139
- }
140
- }
141
- cols = cols.substring(0, cols.length - 1);
142
- const query = `CREATE COLUMN TABLE ${modelname} (${cols});`;
143
- try {
144
- return await this.run(query);
145
- } catch (err) {
146
- if (this.loglevel > 0) console.log(err);
147
- throw err;
148
- }
149
- }
150
-
151
- async insert(modelname, object) {
152
- this.sync.insert(modelname, object);
153
- this.metrics.insert(modelname, object);
154
- let cols = "";
155
- let vals = "";
156
- for (const key in object) {
157
- cols = cols + `"${key}",`;
158
- let val = object[key];
159
- if (typeof val == "object") val = JSON.stringify(object[key]);
160
- val = this.escapeSQLValue(val);
161
- if (typeof val == "undefined") vals = vals + `Null,`;
162
- else if (typeof val == "boolean") vals = vals + `${val},`;
163
- else if (typeof val == "number") vals = vals + `${val},`;
164
- else vals = vals + `${val},`;
165
- }
166
- cols = cols.slice(0, -1);
167
- vals = vals.slice(0, -1);
168
-
169
- const query = `INSERT INTO ${modelname} (${cols}) VALUES (${vals});`;
170
-
171
- try {
172
- return await this.run(query);
173
- } catch (err) {
174
- if (err.code && err.code === "259") {
175
- // Table does not exist
176
- await this.create(modelname, object);
177
- return await this.run(query);
178
- } else {
179
- throw err;
180
- }
181
- }
182
- }
183
-
184
- async update(modelname, filter, object) {
185
- this.sync.update(modelname, filter, object);
186
- this.metrics.update(modelname, filter, object);
187
-
188
- let where = "";
189
- let vals = "";
190
- for (const key in filter) {
191
- where += `"${key}" = '${filter[key]}' AND `;
192
- }
193
- for (const key in object) {
194
- let val = object[key];
195
- if (typeof val === "object" && val != null)
196
- val = JSON.stringify(object[key]);
197
- val = this.escapeSQLValue(val);
198
-
199
- vals += `"${key}" = ${val},`;
200
- }
201
- where += "1 = 1";
202
- vals = vals.slice(0, -1);
203
-
204
- const query = `UPDATE ${modelname} SET ${vals} WHERE ${where};`;
205
- try {
206
- return await this.run(query);
207
- } catch (e) {
208
- if (this.loglevel > 4) console.log("Error in update", e);
209
- throw e;
210
- }
211
- }
212
-
213
- async delete(modelname, filter) {
214
- this.sync.delete(modelname, filter);
215
- this.metrics.delete(modelname, filter);
216
-
217
- let where = "";
218
- for (const key in filter) {
219
- where += `"${key}" = '${filter[key]}' AND `;
220
- }
221
- where += "1 = 1";
222
- const query = `DELETE FROM ${modelname} WHERE ${where};`;
223
- return await this.run(query);
224
- }
225
-
226
- closePool() {
227
- return new Promise((resolve, reject) => {
228
- this.pool.disconnect((err) => {
229
- if (err) {
230
- reject(err);
231
- if (this.loglevel > 1)
232
- console.error("Error closing connection pool:", err);
233
- } else {
234
- resolve();
235
- if (this.loglevel > 1) console.log("HanaDB: Connection pool closed");
236
- }
237
- });
238
- });
239
- }
240
- }
241
-
242
- module.exports = {
243
- HanaDB,
244
- };
1
+ const { MultiDbORM } = require("./multidb");
2
+
3
+ class HanaDB extends MultiDbORM {
4
+ db;
5
+ pool;
6
+ dataMap = {
7
+ id: "VARCHAR(50) NOT NULL PRIMARY KEY",
8
+ string: "NVARCHAR(4000)",
9
+ stringlarge: "NCLOB",
10
+ stringsmall: "NVARCHAR(255)",
11
+ number: "DOUBLE",
12
+ boolean: "BOOLEAN",
13
+ array: "NCLOB",
14
+ object: "NCLOB",
15
+ };
16
+
17
+ constructor(credentials) {
18
+ super();
19
+ const hana = require("@sap/hana-client");
20
+ this.db = hana;
21
+ this.conn_params = {
22
+ ...credentials,
23
+ host: credentials.host,
24
+ port: credentials.port,
25
+ serverNode: `${credentials.host}:${credentials.port}`,
26
+ uid: credentials.username,
27
+ pwd: credentials.password,
28
+ databaseName: credentials.database,
29
+ communicationTimeout: credentials.connectionLimit || 60000,
30
+ connectTimeout: credentials.connectionLimit || 60000,
31
+ reconnect: credentials.reconnect ?? true,
32
+ poolOptions: {
33
+ maxPoolSize: credentials.connectionLimit || 10,
34
+ idleTimeout: credentials.timeout || 60000,
35
+ },
36
+ };
37
+ this.pool = hana.createPool(this.conn_params);
38
+ this.db = this.pool;
39
+ this.dbType = "hana";
40
+ this.reqMade = 0;
41
+ }
42
+
43
+ async run(query) {
44
+ const that = this;
45
+ this.reqMade++;
46
+ return new Promise((resolve, reject) => {
47
+ var conn = this.pool.getConnection();
48
+ conn.exec(query, (err, result) => {
49
+ conn.disconnect();
50
+ if (err) {
51
+ err.message = err.message + " query=" + query;
52
+ reject(err);
53
+ } else {
54
+ resolve(result);
55
+ }
56
+ if (that.loglevel > 3) {
57
+ console.log("Query", query, "->", result);
58
+ }
59
+ });
60
+ });
61
+ }
62
+
63
+ async get(modelname, filter, options) {
64
+ const span = this.metrics.getSpan();
65
+ let where = "";
66
+ for (const key in filter) {
67
+ where += `"${key}" = '${filter[key]}' AND `;
68
+ }
69
+ where += "1 = 1";
70
+ let sort = "";
71
+ if (options) {
72
+ if (options.apply) {
73
+ if (options.apply.ineq) {
74
+ where += ` AND "${options.apply.field}" ${options.apply.ineq.op} '${options.apply.ineq.value}'`;
75
+ }
76
+ if (options.apply.sort) {
77
+ sort = `ORDER BY "${options.apply.field}" ${options.apply.sort}`;
78
+ }
79
+ } else if (options.sort) {
80
+ sort = "ORDER BY";
81
+ for (let i = 0; i < options.sort.length; i++) {
82
+ sort += ` "${options.sort[i].field}" ${options.sort[i].order}`;
83
+ if (i < options.sort.length - 1) {
84
+ sort += ", ";
85
+ }
86
+ }
87
+ }
88
+ }
89
+ const limit = options?.limit ? `LIMIT ${options.limit}` : "";
90
+ const offset = options?.offset ? `OFFSET ${options.offset}` : "";
91
+ const query = `SELECT * FROM ${modelname} WHERE ${where} ${sort} ${limit} ${offset};`;
92
+ const res = (await this.run(query)) || [];
93
+ this.metrics.get(modelname, filter, options, span);
94
+ return res;
95
+ }
96
+ escapeSQLValue(value) {
97
+ if (typeof value === "string") {
98
+ return `'${value.replace(/'/g, "''")}'`;
99
+ } else if (value === null || value === undefined) {
100
+ return "NULL";
101
+ }
102
+ return value;
103
+ }
104
+ async getOne(modelname, filter) {
105
+ const span = this.metrics.getOneSpan();
106
+ let where = "";
107
+ for (const key in filter) {
108
+ where += `"${key}" = '${filter[key]}' AND `;
109
+ }
110
+ where += "1 = 1";
111
+ const query = `SELECT * FROM ${modelname} WHERE ${where} LIMIT 1;`;
112
+ const row = await this.run(query);
113
+ this.metrics.getOne(modelname, filter, span);
114
+ return row[0];
115
+ }
116
+
117
+ async create(modelname, sampleObject) {
118
+ this.sync.create(modelname, sampleObject);
119
+ const span = this.metrics.createSpan();
120
+
121
+ let cols = "";
122
+ for (const key in sampleObject) {
123
+ let type;
124
+ if (this.dataMap[sampleObject[key]]) {
125
+ type = this.dataMap[sampleObject[key]];
126
+ } else {
127
+ type = this.dataMap[typeof sampleObject[key]] || "NCLOB";
128
+ if (typeof sampleObject[key] === "string") {
129
+ if (sampleObject[key].length > 4000) {
130
+ type = this.dataMap["stringlarge"];
131
+ }
132
+ if (sampleObject[key].length <= 255) {
133
+ type = this.dataMap["stringsmall"];
134
+ }
135
+ }
136
+ }
137
+
138
+ if (key.toLowerCase().trim() === "id") {
139
+ cols += `"${key}" ${type} PRIMARY KEY NOT NULL ,`;
140
+ } else {
141
+ cols += `"${key}" ${type},`;
142
+ }
143
+ }
144
+ cols = cols.substring(0, cols.length - 1);
145
+ const query = `CREATE COLUMN TABLE ${modelname} (${cols});`;
146
+ try {
147
+ const res = await this.run(query);
148
+ this.metrics.create(modelname, sampleObject, span);
149
+ return res;
150
+ } catch (err) {
151
+ if (this.loglevel > 0) console.log(err);
152
+ throw err;
153
+ }
154
+ }
155
+
156
+ async insert(modelname, object) {
157
+ this.sync.insert(modelname, object);
158
+ const span = this.metrics.insertSpan();
159
+ let cols = "";
160
+ let vals = "";
161
+ for (const key in object) {
162
+ cols = cols + `"${key}",`;
163
+ let val = object[key];
164
+ if (typeof val == "object") val = JSON.stringify(object[key]);
165
+ val = this.escapeSQLValue(val);
166
+ if (typeof val == "undefined") vals = vals + `Null,`;
167
+ else if (typeof val == "boolean") vals = vals + `${val},`;
168
+ else if (typeof val == "number") vals = vals + `${val},`;
169
+ else vals = vals + `${val},`;
170
+ }
171
+ cols = cols.slice(0, -1);
172
+ vals = vals.slice(0, -1);
173
+
174
+ const query = `INSERT INTO ${modelname} (${cols}) VALUES (${vals});`;
175
+
176
+ try {
177
+ const res = await this.run(query);
178
+ this.metrics.insert(modelname, object, span);
179
+ return res;
180
+ } catch (err) {
181
+ if (err.code && err.code === "259") {
182
+ // Table does not exist
183
+ await this.create(modelname, object);
184
+ const res = await this.run(query);
185
+ this.metrics.insert(modelname, object, span);
186
+ return res;
187
+ } else {
188
+ throw err;
189
+ }
190
+ }
191
+ }
192
+
193
+ async update(modelname, filter, object) {
194
+ this.sync.update(modelname, filter, object);
195
+ const span = this.metrics.updateSpan();
196
+
197
+ let where = "";
198
+ let vals = "";
199
+ for (const key in filter) {
200
+ where += `"${key}" = '${filter[key]}' AND `;
201
+ }
202
+ for (const key in object) {
203
+ let val = object[key];
204
+ if (typeof val === "object" && val != null)
205
+ val = JSON.stringify(object[key]);
206
+ val = this.escapeSQLValue(val);
207
+
208
+ vals += `"${key}" = ${val},`;
209
+ }
210
+ where += "1 = 1";
211
+ vals = vals.slice(0, -1);
212
+
213
+ const query = `UPDATE ${modelname} SET ${vals} WHERE ${where};`;
214
+ try {
215
+ const res = await this.run(query);
216
+ this.metrics.update(modelname, filter, object, span);
217
+ return res;
218
+ } catch (e) {
219
+ if (this.loglevel > 4) console.log("Error in update", e);
220
+ throw e;
221
+ }
222
+ }
223
+
224
+ async delete(modelname, filter) {
225
+ this.sync.delete(modelname, filter);
226
+ const span = this.metrics.deleteSpan();
227
+
228
+ this.metrics.delete(modelname, filter);
229
+
230
+ let where = "";
231
+ for (const key in filter) {
232
+ where += `"${key}" = '${filter[key]}' AND `;
233
+ }
234
+ where += "1 = 1";
235
+ const query = `DELETE FROM ${modelname} WHERE ${where};`;
236
+ const res = await this.run(query);
237
+ this.metrics.delete(modelname, filter, span);
238
+ return res;
239
+ }
240
+
241
+ closePool() {
242
+ return new Promise((resolve, reject) => {
243
+ this.pool.disconnect((err) => {
244
+ if (err) {
245
+ reject(err);
246
+ if (this.loglevel > 1)
247
+ console.error("Error closing connection pool:", err);
248
+ } else {
249
+ resolve();
250
+ if (this.loglevel > 1) console.log("HanaDB: Connection pool closed");
251
+ }
252
+ });
253
+ });
254
+ }
255
+ }
256
+
257
+ module.exports = {
258
+ HanaDB,
259
+ };
@@ -1,8 +1,8 @@
1
- export * from './multidb';
2
- export * from './sqlitedb';
3
- export * from './mongodb';
4
- export * from './firestoredb';
5
- export * from './oracledb';
6
- export * from './mysqldb';
7
- export * from './hanadb';
8
- export * from './bigquerydb';
1
+ export * from './multidb';
2
+ export * from './sqlitedb';
3
+ export * from './mongodb';
4
+ export * from './firestoredb';
5
+ export * from './oracledb';
6
+ export * from './mysqldb';
7
+ export * from './hanadb';
8
+ export * from './bigquerydb';
@@ -1,9 +1,9 @@
1
- export class Metrics {
2
- constructor(loglevel: number);
3
- get(modelname: string, filter: any, options: any): void;
4
- getOne(modelname: string, filter: any): void;
5
- create(modelname: string, sampleObject: any): void;
6
- insert(modelname: string, object: any): void;
7
- update(modelname: string, filter: any, object: any): void;
8
- delete(modelname: string, filter: any): void;
1
+ export class Metrics {
2
+ constructor(loglevel: number);
3
+ get(modelname: string, filter: any, options: any): void;
4
+ getOne(modelname: string, filter: any): void;
5
+ create(modelname: string, sampleObject: any): void;
6
+ insert(modelname: string, object: any): void;
7
+ update(modelname: string, filter: any, object: any): void;
8
+ delete(modelname: string, filter: any): void;
9
9
  }