db-crud-api 0.3.19 → 0.3.25

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.
@@ -0,0 +1,486 @@
1
+ 'use strict';
2
+
3
+ // import modules
4
+ import schema from './schema.js'
5
+ import * as mssql from './mssql.js';
6
+ import * as mysql from './mysql.js';
7
+
8
+ // Common
9
+ const defautlFields = ['*'];
10
+ export const serverType = Object.freeze({ mssql: 'ms-sql', mysql: 'my-sql', mongodb: 'mongo-db' });
11
+ export const objectType = Object.freeze({ table: 'T', procedure: 'P' });
12
+
13
+ // Exported functions
14
+ export function idField(tSchema) {
15
+ return tSchema.table?.idField ?? 'id';
16
+ }
17
+
18
+ export function autoId(tSchema) {
19
+ return tSchema.table?.autoId;
20
+ }
21
+
22
+ export function getProperty(obj, keyToFind) {
23
+ if (typeof obj !== 'object' || obj === null || !keyToFind) {
24
+ return undefined;
25
+ }
26
+
27
+ const lowerKeyToFind = keyToFind.toLowerCase();
28
+
29
+ for (const key in obj) {
30
+ // Usa hasOwnProperty per escludere le proprietà ereditate
31
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
32
+
33
+ if (key.toLowerCase() === lowerKeyToFind) {
34
+ return obj[key];
35
+ }
36
+ }
37
+ }
38
+
39
+ return undefined;
40
+ }
41
+
42
+ export function upsertProperty(obj, keyToUpdate, newValue) {
43
+ if (typeof obj !== 'object' || obj === null) {
44
+ // Non è un oggetto valido
45
+ return false;
46
+ }
47
+
48
+ const lowerKeyToUpdate = keyToUpdate.toLowerCase();
49
+ let propertyFound = false;
50
+
51
+ for (const key in obj) {
52
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
53
+ if (key.toLowerCase() === lowerKeyToUpdate) {
54
+ obj[key] = newValue;
55
+ propertyFound = true;
56
+ break;
57
+ }
58
+ }
59
+ }
60
+
61
+ if (!propertyFound) {
62
+ obj[keyToUpdate] = newValue;
63
+ }
64
+
65
+ return true;
66
+ }
67
+
68
+ export async function runQuery(dbOpes) {
69
+
70
+ // all connections must have same id
71
+ const _connection = Array.isArray(dbOpes) ? dbOpes[0].connection : dbOpes.connection;
72
+ if (Array.isArray(dbOpes)) {
73
+ for (let i = 1; i < dbOpes.length; i++) {
74
+ if (dbOpes[i].connection?.id !== _connection.id) throw new TypeError('runQuery: for multiple operations, connection must be the same');
75
+ }
76
+ }
77
+
78
+ // MSSQL
79
+ if (_connection.serverType === serverType.mssql) {
80
+ return await mssql.query(_connection, dbOpes);
81
+ }
82
+
83
+ // MySQL
84
+ else if (_connection.serverType === serverType.mysql) {
85
+ return await mysql.query(_connection, dbOpes);
86
+ }
87
+
88
+ // server type not supported
89
+ else throw new TypeError('server type not supported');
90
+
91
+ }
92
+
93
+ export function prepareConnection(schema) {
94
+ // MySQL
95
+ if (schema.server.type === serverType.mysql) {
96
+ const _return = mysql.prepareConnection(schema);
97
+ _return.serverType = serverType.mysql; // append 'serverType' to connection
98
+ return _return;
99
+ }
100
+ // MSSQL is also the default
101
+ if (!schema.server.type || schema.server.type === serverType.mssql) {
102
+ const _return = mssql.prepareConnection(schema);
103
+ _return.serverType = serverType.mssql; // append 'serverType' to connection
104
+ return _return;
105
+ }
106
+ throw new TypeError('server type not supported');
107
+ }
108
+
109
+ export function closeConnection(connection) {
110
+ // MSSQL
111
+ if (connection.serverType === serverType.mssql) { return mssql.closeConnection(connection); }
112
+ // MySQL
113
+ if (connection.serverType === serverType.mysql) { return mysql.closeConnection(connection); }
114
+ }
115
+
116
+ export function closeAllConnections() {
117
+ // MSSQL
118
+ mssql.closeAllConnections();
119
+ // MySQL
120
+ mysql.closeAllConnections();
121
+
122
+ return;
123
+ }
124
+
125
+ export function testConnection() {
126
+ const _connection = prepareConnection(prepareSchema("test", objectType.procedure));
127
+ // MSSQL
128
+ if (_connection.serverType === serverType.mssql) { return mssql.testConnection(_connection); }
129
+ // MySQL
130
+ if (_connection.serverType === serverType.mysql) { return mysql.testConnection(_connection); }
131
+ // server type not supported
132
+ throw new TypeError('server type not supported');
133
+ }
134
+
135
+ export function toStringValue(value) {
136
+ if (!value) return 'null';
137
+ if (value.trimStart().charAt(0) === '\'') return value;
138
+ return `\'${value}\'`;
139
+ }
140
+
141
+ export function prepareSchema(obj, objType) {
142
+ // objType = 'objectType.' (Table or StoreProcedure)
143
+ // obj = 'systemName.dbName.objName' or 'dbName.objName' or 'objName' or 'systemNme..objName'
144
+
145
+ if (obj == undefined || typeof obj !== 'string') throw new TypeError('prepareSchema: wrong obj');
146
+ if (objType !== undefined && objType !== objectType.table && objType !== objectType.procedure) throw new TypeError(`prepareSchema: wrong objType, must be ${objectType.join(', ')}`);
147
+ const objPath = obj.trimStart().split(' ')[0];
148
+
149
+ // split objPath to serverName,dbName,objName
150
+ let serverName = undefined;
151
+ let dbName = undefined;
152
+ let objName = undefined;
153
+ const objPathArray = objPath.split('.');
154
+ if (objPathArray.length > 2) {
155
+ serverName = objPathArray[0]
156
+ dbName = objPathArray[1]
157
+ objName = objPathArray[2]
158
+ }
159
+ else if (objPathArray.length > 1) {
160
+ dbName = objPathArray[0]
161
+ objName = objPathArray[1]
162
+ }
163
+ else if (objPathArray.length > 0) {
164
+ objName = objPathArray[0]
165
+ }
166
+
167
+ // server
168
+ if (!serverName || serverName.length == 0) {
169
+ if (!schema.servers || !Object.keys(schema.servers)[0]) throw new TypeError('missing default server in dbSchema');
170
+ serverName = Object.keys(schema.servers)[0];
171
+ }
172
+ else { // add server to schema
173
+ if (!schema.servers) { schema.servers = {} };
174
+ if (!schema.servers[serverName]) { schema.servers[serverName] = {} };
175
+ }
176
+ if (!schema.servers[serverName].realName) { schema.servers[serverName].realName = serverName } // add realName
177
+
178
+ // database
179
+ if (!dbName || dbName.length == 0) {
180
+ if (!schema.servers[serverName].databases || !Object.keys(schema.servers[serverName].databases)[0]) throw new TypeError('missing default database in dbSchema');
181
+ dbName = Object.keys(schema.servers[serverName].databases)[0];
182
+ }
183
+ else { // add db to schema
184
+ if (!schema.servers[serverName].databases) { schema.servers[serverName].databases = {} };
185
+ if (!schema.servers[serverName].databases[dbName]) { schema.servers[serverName].databases[dbName] = {} };
186
+ }
187
+ if (!schema.servers[serverName].databases[dbName].realName) { schema.servers[serverName].databases[dbName].realName = dbName } // add realName
188
+
189
+ // table
190
+ if (objType === objectType.table || objType == undefined) {
191
+ if (!objName || objName.length == 0) {
192
+ if (!schema.servers[serverName].databases[dbName] || !Object.keys(schema.servers[serverName].databases[dbName].tables)[0]) throw new TypeError('missing default table in dbSchema');
193
+ objName = Object.keys(schema.servers[serverName].databases[dbName].tables)[0];
194
+ }
195
+ else { // add table to schema
196
+ if (!schema.servers[serverName].databases[dbName].tables) { schema.servers[serverName].databases[dbName].tables = {} };
197
+ if (!schema.servers[serverName].databases[dbName].tables[objName]) { schema.servers[serverName].databases[dbName].tables[objName] = {} }
198
+ }
199
+ if (!schema.servers[serverName].databases[dbName].tables[objName].realName) { schema.servers[serverName].databases[dbName].tables[objName].realName = objName } // add realName
200
+ }
201
+
202
+ // store procedure
203
+ if (objType === objectType.procedure) {
204
+ if (!objName || objName.length == 0) {
205
+ if (!schema.servers[serverName].databases[dbName] || !Object.keys(schema.servers[serverName].databases[dbName].procedures)[0]) throw new TypeError('missing default procedure in dbSchema');
206
+ objName = Object.keys(schema.servers[serverName].databases[dbName].procedures)[0];
207
+ }
208
+ else { // add storeprocedure to schema
209
+ if (!schema.servers[serverName].databases[dbName].procedures) { schema.servers[serverName].databases[dbName].procedures = {} };
210
+ if (!schema.servers[serverName].databases[dbName].procedures[objName]) { schema.servers[serverName].databases[dbName].procedures[objName] = {command: obj} }
211
+ }
212
+ if (!schema.servers[serverName].databases[dbName].procedures[objName].realName) { schema.servers[serverName].databases[dbName].procedures[objName].realName = objName } // add realName
213
+ }
214
+
215
+ // return Schema
216
+ return {
217
+ table: (objType == undefined || objType === objectType.table) ? schema.servers[serverName].databases[dbName].tables[objName] : undefined,
218
+ procedure: (objType === objectType.procedure) ? schema.servers[serverName].databases[dbName].procedures[objName] : undefined,
219
+ database: schema.servers[serverName].databases[dbName],
220
+ server: schema.servers[serverName]
221
+ }
222
+
223
+ }
224
+
225
+ export function prepareRun(tSchema, connection, reqOpe) {
226
+ const _reqOpe = [];
227
+ const _result = [];
228
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
229
+ else _reqOpe.push(reqOpe);
230
+ _reqOpe.forEach(function (_ope) {
231
+ if (_ope?.get) _result.push(prepareGet(tSchema, connection, _ope));
232
+ else if (_ope?.patch) _result.push(preparePatch(tSchema, connection, _ope));
233
+ else if (_ope?.put) _result.push(preparePut(tSchema, connection, _ope));
234
+ else if (_ope?.delete) _result.push(prepareDelete(tSchema, connection, _ope));
235
+ else if (_ope?.execute) _result.push(prepareExecute(connection, _ope));
236
+ else if (_ope?.begin) _result.push(prepareBegin(connection, _ope));
237
+ else if (_ope?.commit) _result.push(prepareCommit(connection, _ope));
238
+ else if (_ope?.rollback) _result.push(prepareRollback(connection, _ope));
239
+ else if (_ope?.passthrough) _result.push(preparePassthrough(connection, _ope));
240
+ else throw new Error('Request sintax error, missing property get/patch/put/delete/...');
241
+ });
242
+ if (_result.length > 1) return _result;
243
+ if (_result.length = 1) return _result[0];
244
+ return undefined;
245
+ }
246
+
247
+ export function prepareRunById(tSchema, connection, reqOpe, idValue) {
248
+ if (reqOpe?.get) return prepareGetById(tSchema, connection, reqOpe, idValue);
249
+ if (reqOpe?.patch) return preparePatchById(tSchema, connection, reqOpe, idValue);
250
+ if (reqOpe?.put) return preparePutById(tSchema, connection, reqOpe, idValue);
251
+ if (reqOpe?.delete) return prepareDeleteById(tSchema, connection, reqOpe, idValue);
252
+ else throw new Error('Request sintax error, missing property get/patch/put/delete...');
253
+ }
254
+
255
+ export function prepareGet(tSchema, connection, reqOpe) {
256
+ const _reqOpe = [];
257
+ const _result = [];
258
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
259
+ else _reqOpe.push(reqOpe);
260
+ _reqOpe.forEach(function (_ope) {
261
+ _result.push({
262
+ get: {
263
+ schema: tSchema,
264
+ options: _ope?.get?.options,
265
+ fields: _ope?.get?.fields ?? defautlFields,
266
+ filters: _ope?.get?.filters,
267
+ groups: _ope?.get?.groups,
268
+ groupsFilters: _ope?.get?.groupsFilters,
269
+ orderBy: _ope?.get?.orderBy,
270
+ params: _ope?.get?.params
271
+ },
272
+ connection: connection,
273
+ appLog: _ope?.hasOwnProperty('appLog') ? _ope.appLog : undefined
274
+ });
275
+ });
276
+ if (_result.length > 1) return _result;
277
+ if (_result.length = 1) return _result[0];
278
+ return undefined;
279
+ };
280
+
281
+ export function prepareGetById(tSchema, connection, reqOpe, idValue) {
282
+ const _filters = [idField(tSchema) + ' = ' + toStringValue(idValue)];
283
+ if (reqOpe?.get?.filters && reqOpe?.get?.filters.length > 0) {
284
+ _filters.push('and');
285
+ Array.isArray(reqOpe.get.filters) ? _filters.push(...reqOpe.get.filters) : _filters.push(reqOpe.get.filters);
286
+ }
287
+ return {
288
+ get: {
289
+ schema: tSchema,
290
+ options: reqOpe?.get?.options,
291
+ fields: reqOpe?.get?.fields ?? defautlFields,
292
+ filters: _filters
293
+ },
294
+ connection: connection,
295
+ appLog: reqOpe?.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
296
+ }
297
+ };
298
+
299
+ export function preparePatch(tSchema, connection, reqOpe) {
300
+ const _reqOpe = [];
301
+ const _result = [];
302
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
303
+ else _reqOpe.push(reqOpe);
304
+ _reqOpe.forEach(function (_ope) {
305
+ if (_ope?.patch) {
306
+ if (!_ope.patch.sets) throw new Error('Request sintax error, missing "patch.sets" property.')
307
+ _result.push({
308
+ patch: {
309
+ schema: tSchema,
310
+ sets: _ope.patch.sets,
311
+ filters: _ope.patch.filters,
312
+ params: _ope.patch.params
313
+ },
314
+ connection: connection,
315
+ appLog: _ope.hasOwnProperty('appLog') ? _ope.appLog : undefined
316
+ });
317
+ }
318
+ else throw new Error('Request sintax error, missing "patch" property.');
319
+ });
320
+ if (_result.length > 1) return _result;
321
+ if (_result.length = 1) return _result[0];
322
+ return undefined;
323
+ };
324
+
325
+ export function preparePatchById(tSchema, connection, reqOpe, idValue) {
326
+ if (!reqOpe?.patch) throw new Error('Request sintax error, missing "patch" property.')
327
+ if (!reqOpe.patch.sets) throw new Error('Missing "patch.sets" in operation.')
328
+ const _filters = [idField(tSchema) + ' = ' + toStringValue(idValue)];
329
+ if (reqOpe?.patch?.filters && reqOpe?.patch?.filters.length > 0) {
330
+ _filters.push('and');
331
+ Array.isArray(reqOpe.patch.filters) ? _filters.push(...reqOpe.patch.filters) : _filters.push(reqOpe.patch.filters);
332
+ }
333
+ return {
334
+ patch: {
335
+ schema: tSchema,
336
+ sets: reqOpe.patch.sets,
337
+ filters: _filters
338
+ },
339
+ connection: connection,
340
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
341
+ }
342
+ };
343
+
344
+ export function preparePut(tSchema, connection, reqOpe) {
345
+ const _reqOpe = [];
346
+ const _result = [];
347
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
348
+ else _reqOpe.push(reqOpe);
349
+ _reqOpe.forEach(function (_ope) {
350
+ if (_ope?.put) {
351
+ if (!_ope.put.sets) throw new Error('Request sintax error, missing "put.sets" property.')
352
+ _result.push({
353
+ put: {
354
+ schema: tSchema,
355
+ sets: _ope.put.sets,
356
+ params: _ope.put.params
357
+ },
358
+ connection: connection,
359
+ appLog: _ope.hasOwnProperty('appLog') ? _ope.appLog : undefined
360
+ });
361
+ }
362
+ else throw new Error('Request sintax error, missing "put" property.');
363
+ });
364
+ if (_result.length > 1) return _result;
365
+ if (_result.length = 1) return _result[0];
366
+ return undefined;
367
+ };
368
+
369
+ export function preparePutById(tSchema, connection, reqOpe, idValue) {
370
+ if (!reqOpe?.put) throw new Error('Request sintax error, missing "put" property.')
371
+ if (!reqOpe.put.sets) throw new Error('Missing "put.sets" in operation.')
372
+ upsertProperty(reqOpe.put.sets, idField(tSchema), idValue);
373
+ return {
374
+ put: {
375
+ schema: tSchema,
376
+ sets: reqOpe.put.sets,
377
+ params: reqOpe.put.params
378
+ },
379
+ connection: connection,
380
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
381
+ }
382
+ };
383
+
384
+ export function prepareDelete(tSchema, connection, reqOpe) {
385
+ const _reqOpe = [];
386
+ const _result = [];
387
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
388
+ else _reqOpe.push(reqOpe);
389
+ _reqOpe.forEach(function (_ope) {
390
+ if (_ope?.delete) {
391
+ _result.push({
392
+ delete: {
393
+ schema: tSchema,
394
+ filters: _ope.delete.filters,
395
+ params: _ope.delete.params
396
+ },
397
+ connection: connection,
398
+ appLog: _ope.hasOwnProperty('appLog') ? _ope.appLog : undefined
399
+ });
400
+ }
401
+ else throw new Error('Request sintax error, missing "delete" property.');
402
+ });
403
+ if (_result.length > 1) return _result;
404
+ if (_result.length = 1) return _result[0];
405
+ return undefined;
406
+ };
407
+
408
+ export function prepareDeleteById(tSchema, connection, reqOpe, idValue) {
409
+ return {
410
+ delete: {
411
+ schema: tSchema,
412
+ filters: [idField(tSchema) + ' = ' + toStringValue(idValue)]
413
+ },
414
+ connection: connection,
415
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
416
+ }
417
+ };
418
+
419
+ export function prepareExecute(pSchema, connection, reqOpe) {
420
+ const _reqOpe = [];
421
+ const _result = [];
422
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
423
+ else _reqOpe.push(reqOpe);
424
+ _reqOpe.forEach(function (_ope) {
425
+ _result.push({
426
+ execute: {
427
+ schema: pSchema,
428
+ arguments: _ope.execute?.arguments,
429
+ params: _ope.execute?.params
430
+ },
431
+ connection: connection,
432
+ appLog: _ope.hasOwnProperty('appLog') ? _ope.appLog : undefined
433
+ });
434
+ });
435
+ if (_result.length > 1) return _result;
436
+ if (_result.length = 1) return _result[0];
437
+ return undefined;
438
+ };
439
+
440
+ export function preparePassthrough(connection, reqOpe) {
441
+ const _reqOpe = [];
442
+ const _result = [];
443
+ if (Array.isArray(reqOpe)) _reqOpe.push(...reqOpe);
444
+ else _reqOpe.push(reqOpe);
445
+ _reqOpe.forEach(function (_ope) {
446
+ if (_ope?.passthrough) {
447
+ if (!_ope.passthrough.command) throw new Error('Request sintax error, missing "passthrough.command" property.')
448
+ _result.push({
449
+ passthrough: {
450
+ command: _ope.passthrough.command,
451
+ params: _ope.passthrough.params
452
+ },
453
+ connection: connection,
454
+ appLog: _ope.hasOwnProperty('appLog') ? _ope.appLog : undefined
455
+ });
456
+ }
457
+ else throw new Error('Request sintax error, missing "passthrough" property.');
458
+ });
459
+ if (_result.length > 1) return _result;
460
+ if (_result.length = 1) return _result[0];
461
+ return undefined;
462
+ };
463
+
464
+ export function prepareBegin(connection, reqOpe) {
465
+ return {
466
+ begin: {},
467
+ connection: connection,
468
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
469
+ }
470
+ };
471
+
472
+ export function prepareCommit(connection, reqOpe) {
473
+ return {
474
+ commit: {},
475
+ connection: connection,
476
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
477
+ }
478
+ };
479
+
480
+ export function prepareRollback(connection, reqOpe) {
481
+ return {
482
+ rollback: {},
483
+ connection: connection,
484
+ appLog: reqOpe.hasOwnProperty('appLog') ? reqOpe.appLog : undefined
485
+ }
486
+ };
package/lib/mssql.js CHANGED
@@ -11,24 +11,49 @@ const pools = {};
11
11
 
12
12
  // Common
13
13
  function stringifyValue(fieldName, value, tSchema) {
14
- if (value == undefined) { return 'null' }
15
- if (typeof value !== 'string' || value.trimStart().charAt(0) !== '[') {
16
- if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
17
- if (tSchema.table.fields[fieldName].type == 'datetime') {
18
- if (typeof value == 'datetime' || typeof value == 'object') return `\'${value.toISOString()}\'`;
19
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
20
- return value;
21
- }
22
- if (tSchema.table.fields[fieldName].type == 'boolean' && typeof value == 'boolean') return `\'${value}\'`;
23
- if (tSchema.table.fields[fieldName].type == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
24
- if (tSchema.table.fields[fieldName].type == 'uuid' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
14
+
15
+ // null or undefined
16
+ if (value == undefined)
17
+ return 'null';
18
+
19
+ // detect field type from schema
20
+ let _fieldType = undefined;
21
+ if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
22
+ _fieldType = tSchema.table.fields[fieldName].type;
23
+ }
24
+
25
+ // if datetime
26
+ if (_fieldType == 'datetime') {
27
+ // my-sql not accepts 'Z' at end of ISO string
28
+ if (value instanceof Date) return `\'${value.toISOString()}\'`;
29
+ if (typeof value == 'string') {
30
+ const valueDate = new Date(Date.parse(value));
31
+ return `\'${valueDate.toISOString()}\'`;
25
32
  }
26
- else {
27
- // if (typeof value == 'datetime') return `\'${value.toISOString()}\'`;
28
- if (typeof value == 'boolean') return `\'${value}\'`;
29
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
33
+ return value;
34
+ }
35
+
36
+ // if boolean
37
+ if (_fieldType == 'boolean' && typeof value == 'boolean')
38
+ return `\'${value}\'`;
39
+
40
+ // if string or uuid
41
+ if (_fieldType == 'string' || _fieldType == 'uuid') {
42
+ if (value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') {
43
+ return `\'${value}\'`;
30
44
  }
31
45
  }
46
+
47
+ // field not in schema
48
+ if (_fieldType == undefined) {
49
+ if (value instanceof Date)
50
+ return `\'${value.toISOString()}\'`;
51
+ if (typeof value == 'boolean')
52
+ return `\'${value}\'`;
53
+ if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"')
54
+ return `\'${value}\'`;
55
+ }
56
+
32
57
  return value;
33
58
  }
34
59
 
@@ -106,21 +131,34 @@ export async function query(connection, dbOpes) {
106
131
  // Prepare sql statement
107
132
  let sqlString = '';
108
133
  let sqlRequest = pool.request();
134
+ let appLog = true;
109
135
  // if exists, input params will be added to request
110
- if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, sqlRequest); });
111
- else sqlString += ToSql(dbOpes, sqlRequest);
136
+ if (Array.isArray(dbOpes)) {
137
+ dbOpes.forEach((dbOpe, index) => {
138
+ sqlString += ToSql(dbOpe, sqlRequest);
139
+ if (dbOpe.hasOwnProperty('appLog') && dbOpe.appLog === false) appLog = false;
140
+ });
141
+ }
142
+ else {
143
+ sqlString += ToSql(dbOpes, sqlRequest);
144
+ if (dbOpes.hasOwnProperty('appLog') && dbOpes.appLog === false) appLog = false;
145
+ }
112
146
 
113
147
  sqlString = normalizeSpecialName(sqlString);
114
148
 
115
149
  // Log
116
- log(sqlString, 50);
117
- log(JSON.stringify(dbOpes), 60);
118
-
150
+ if (appLog) {
151
+ log(sqlString, 50);
152
+ log(JSON.stringify(dbOpes), 60);
153
+ }
154
+
119
155
  // Run query
120
156
  const sqlresult = await sqlRequest.query(sqlString);
121
157
 
122
158
  // Log
123
- log(`Query result: ${sqlresult.recordset ? sqlresult.recordset.length : 0} rows.`, 50);
159
+ if (appLog) {
160
+ log(`Query result: ${sqlresult.recordset ? sqlresult.recordset.length : 0} rows.`, 50);
161
+ }
124
162
 
125
163
  // normalize return object
126
164
  if (sqlresult.recordset == undefined) return;
@@ -129,14 +167,36 @@ export async function query(connection, dbOpes) {
129
167
  return sqlresult.recordset;
130
168
  }
131
169
 
132
- // Normalize SpecialName
133
- function normalizeSpecialName(name) {
134
- let _odd = false; // interpreted as 0
135
- return name.replaceAll('\`', (_m) => {
136
- _odd = !_odd;
137
- if (_odd) return '[';
138
- else return ']';
139
- });
170
+ // Normalize SQL to replace backticks with square brackets, considering quoted strings
171
+ function normalizeSpecialName(sqlString) {
172
+ let result = "";
173
+ let inSingleQuote = false;
174
+ let inDoubleQuote = false;
175
+ let msSqlOpening = true; // Serve per alternare [ e ] in modalità mssql
176
+
177
+ for (let i = 0; i < sqlString.length; i++) {
178
+ const char = sqlString[i];
179
+
180
+ // Gestione delle stringhe (costanti)
181
+ if (char === "'" && !inDoubleQuote) {
182
+ inSingleQuote = !inSingleQuote;
183
+ } else if (char === '"' && !inSingleQuote) {
184
+ inDoubleQuote = !inDoubleQuote;
185
+ }
186
+
187
+ // Se siamo fuori dalle citazioni, applichiamo la logica di conversione
188
+ if (!inSingleQuote && !inDoubleQuote) {
189
+ if (char === '`') {
190
+ result += msSqlOpening ? '[' : ']';
191
+ msSqlOpening = !msSqlOpening; // Alterna per il prossimo backtick
192
+ continue;
193
+ }
194
+ }
195
+
196
+ result += char;
197
+ }
198
+
199
+ return result;
140
200
  }
141
201
 
142
202
  // Compose fully qualified table name