db-crud-api 0.3.0 → 0.3.6

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/CHANGELOG.md CHANGED
@@ -40,4 +40,8 @@
40
40
  Changes:
41
41
  - execute api definition
42
42
  Added:
43
- - support for mySQL
43
+ - support for mySQL
44
+ ## v0.3.1 (2025-01-01)
45
+
46
+ Bug fix:
47
+ - autoId flag not onored
package/deploy ADDED
@@ -0,0 +1,5 @@
1
+ ##### publish npm package/module
2
+ ##### !!! pay attention to not publish files with secrets
3
+ npm login
4
+ npm publish
5
+ npm unpublish db-crud-api@0.1.0
package/lib/api-full.js CHANGED
@@ -46,7 +46,7 @@ export default class apiFull {
46
46
  async put(reqOpe) {
47
47
  const _dbOpe = dbOpe.preparePut(this.#schema, this.#connection, reqOpe);
48
48
  if (_dbOpe.put.sets) {
49
- if (this.#schema.autoId === true) // automatic Id
49
+ if (dbOpe.autoId(this.#schema)) // automatic Id
50
50
  if (!Object.keys(_dbOpe.put.sets).find(key => key.toUpperCase() === (dbOpe.idField(this.#schema)).toUpperCase())) {
51
51
  _dbOpe.put.sets[dbOpe.idField(this.#schema)] = uuidv4(); // automatic Id via uuidv4
52
52
  }
@@ -15,6 +15,10 @@ export function idField(tSchema) {
15
15
  return tSchema.table?.idField ?? 'id';
16
16
  }
17
17
 
18
+ export function autoId(tSchema) {
19
+ return tSchema.table?.autoId;
20
+ }
21
+
18
22
  export async function runQuery(dbOpes) {
19
23
 
20
24
  // all connections must have same id
package/lib/mssql.js CHANGED
@@ -1,274 +1,281 @@
1
- 'use strict';
2
-
3
- import sql from 'mssql';
4
-
5
- const pools = {};
6
-
7
- // Common
8
- function stringifyValue(fieldName, value, tSchema) {
9
- if (value == undefined) { return 'null' }
10
- if (typeof value !== 'string' || value.trimStart().charAt(0) !== '[') {
11
- if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
12
- if (tSchema.table.fields[fieldName].type == 'datetime') {
13
- if (typeof value == 'datetime' || typeof value == 'object') return `\'${value.toISOString()}\'`;
14
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
15
- return value;
16
- }
17
- if (tSchema.table.fields[fieldName].type == 'boolean' && typeof value == 'boolean') return `\'${value}\'`;
18
- if (tSchema.table.fields[fieldName].type == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
19
- if (tSchema.table.fields[fieldName].type == 'uuid' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
20
- }
21
- else {
22
- // if (typeof value == 'datetime') return `\'${value.toISOString()}\'`;
23
- if (typeof value == 'boolean') return `\'${value}\'`;
24
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
25
- }
26
- }
27
- return value;
28
- }
29
-
30
- // Create config object for pool
31
- export function prepareConnection(tSchema) {
32
- return {
33
- id: `${tSchema.server.realName}-${tSchema.database.realName}-${tSchema.server.user}`,
34
- server: ((tSchema.server.instance && tSchema.server.instance != 'DEFAULT') ? (tSchema.server.realName + '\\' + tSchema.server.instance) : tSchema.server.realName) ?? 'localhost',
35
- port: tSchema.server.port,
36
- user: tSchema.server.user,
37
- password: tSchema.server.password,
38
- options: {
39
- appName: tSchema.server.options?.appName,
40
- encrypt: tSchema.server.options?.encrypt ?? false, // true for azure
41
- trustServerCertificate: tSchema.server.options?.trustServerCertificate ?? true // true for local dev / self-signed certs
42
- },
43
- pool: tSchema.server.pool,
44
- database: tSchema.database.realName
45
- };
46
- };
47
-
48
- // Close connection
49
- export async function closeConnection(connection) {
50
- let pool = pools[connection.id];
51
- if (pool) {
52
- await pool.close(); // wait pool is closed
53
- pools[connection.id] = undefined; // remove pool from pools
54
- }
55
- }
56
-
57
- // Close all connections
58
- export async function closeAllConnections() {
59
- for (let poolId in pools) {
60
- if (!pools.hasOwnProperty(poolId)) continue;
61
- let pool = pools[poolId];
62
- if (pool) {
63
- await pool.close(); // wait pool is closed
64
- pool = undefined; // remove pool from pools
65
- }
66
- }
67
- }
68
-
69
- // Query
70
- export async function query(connection, dbOpes) {
71
-
72
- // Prepare pool
73
- let pool = pools[connection.id]; // Try to get an existing pool
74
- if (!pool) {
75
- pool = new sql.ConnectionPool(connection); // Create new pool
76
- try { await pool.connect(); // wait that connection are made
77
- } catch(err) { throw(err); } // using original error
78
- pools[connection.id] = pool; // add new pool to pools
79
- }
80
-
81
- // Prepare sql statement
82
- let sqlString = '';
83
- let sqlRequest = pool.request();
84
- // if exists, input params will be added to request
85
- if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, sqlRequest); });
86
- else sqlString += ToSql(dbOpes, sqlRequest);
87
-
88
- // Run query
89
- const sqlresult = await sqlRequest.query(sqlString);
90
-
91
- // Return a single object if there is only 1 row
92
- if (sqlresult.recordsets.length === 0) return;
93
- if (sqlresult.recordsets.length === 1) return sqlresult.recordsets[0];
94
- else return sqlresult.recordsets;
95
- }
96
-
97
- // Normalize field name
98
- //function toFieldName(s) {
99
- // if ( s.trimStart().charAt(0) === '[' ) return s;
100
- // else return `\[${s}\]`;
101
- //}
102
-
103
- // Compose fully qualified table name
104
- function fullyQualifiedTableName(tSchema) {
105
- return (tSchema.database.realName + '.' + (tSchema.table.schema ?? '') + '.' + tSchema.table.realName);
106
- }
107
-
108
- // Parse oprations object to sql string
109
- function ToSql(dbOpe, sqlRequest) {
110
- if (dbOpe.get) return getToSql(dbOpe, sqlRequest);
111
- if (dbOpe.patch) return patchToSql(dbOpe, sqlRequest);
112
- if (dbOpe.put) return putToSql(dbOpe, sqlRequest);
113
- if (dbOpe.delete) return deleteToSql(dbOpe, sqlRequest);
114
- if (dbOpe.execute) return executeToSql(dbOpe, sqlRequest);
115
- if (dbOpe.begin) return beginToSql(dbOpe, sqlRequest);
116
- if (dbOpe.commit) return commitToSql(dbOpe, sqlRequest);
117
- if (dbOpe.passthrough) return passthroughToSql(dbOpe, sqlRequest);
118
- }
119
-
120
- // Parse operation object to sql string without any trasformation.
121
- function passthroughToSql(dbOpe, sqlRequest) {
122
-
123
- let result = "";
124
-
125
- if (dbOpe.passthrough.command) {
126
- result += dbOpe.passthrough.command;
127
- }
128
- else { throw new Error('command is missing.'); }
129
-
130
- if (dbOpe.passthrough.params) addParams(dbOpe.passthrough.params, sqlRequest);
131
-
132
- return result;
133
- }
134
-
135
- // Parse get operation object to sql string
136
- function getToSql(dbOpe, sqlRequest) {
137
- let _first = true;
138
-
139
- let result = 'select '
140
-
141
- if ((dbOpe.get.options) && (Object.keys(dbOpe.get.options).length > 0)) {
142
- if (Array.isArray(dbOpe.get.options)) result += dbOpe.get.options.join(' ') + ' ';
143
- else result += dbOpe.get.options + ' ';
144
- }
145
-
146
- if ((dbOpe.get.fields) && (Object.keys(dbOpe.get.fields).length > 0)) {
147
- if (Array.isArray(dbOpe.get.fields)) result += dbOpe.get.fields.join(', ');
148
- else result += dbOpe.get.fields;
149
- }
150
- else { throw new Error('fields is missing.'); }
151
-
152
- result += ' from ' + fullyQualifiedTableName(dbOpe.get.schema);
153
-
154
- if ((dbOpe.get.filters) && (Object.keys(dbOpe.get.filters).length > 0)) {
155
- if (Array.isArray(dbOpe.get.filters)) result += ' where ' + dbOpe.get.filters.join(' ');
156
- else result += ' where ' + dbOpe.get.filters;
157
- }
158
-
159
- if ((dbOpe.get.groups) && (Object.keys(dbOpe.get.groups).length > 0)) {
160
- if (Array.isArray(dbOpe.get.groups)) result += ' group by ' + dbOpe.get.groups.join(', ');
161
- else result += ' group by ' + dbOpe.get.groups;
162
- }
163
-
164
- if ((dbOpe.get.groupsFilters) && (Object.keys(dbOpe.get.groupsFilters).length > 0)) {
165
- if (Array.isArray(dbOpe.get.groupsFilters)) result += ' having ' + dbOpe.get.groupsFilters.join(' ');
166
- else result += ' having ' + dbOpe.get.groupsFilters;
167
- }
168
-
169
- if ((dbOpe.get.orderBy) && (Object.keys(dbOpe.get.orderBy).length > 0)) {
170
- if (Array.isArray(dbOpe.get.orderBy)) result += ' order by ' + dbOpe.get.orderBy.join(', ');
171
- else result += ' order by ' + dbOpe.get.orderBy;
172
- }
173
-
174
- if (dbOpe.get.params) addParams(dbOpe.get.params, sqlRequest);
175
-
176
- result += ';'
177
-
178
- return result;
179
- }
180
-
181
- // Parse patch operation object to sql string
182
- function patchToSql(dbOpe, sqlRequest) {
183
- let result = 'update ' + fullyQualifiedTableName(dbOpe.patch.schema);
184
-
185
- if (dbOpe.patch.sets) { result += ' set ' + Object.entries(dbOpe.patch.sets).map(e => { return e[0] + '=' + stringifyValue(e[0], e[1], dbOpe.patch.schema) }).join(', '); }
186
- else { throw new Error('sets is missing.'); }
187
-
188
- if ((dbOpe.patch.filters) && (Object.keys(dbOpe.patch.filters).length > 0)) {
189
- if (Array.isArray(dbOpe.patch.filters)) result += ' where ' + dbOpe.patch.filters.join(' ');
190
- else result += ' where ' + dbOpe.patch.filters;
191
- }
192
-
193
- if (dbOpe.patch.params) addParams(dbOpe.patch.params, sqlRequest);
194
-
195
- result += ';'
196
-
197
- return result;
198
- }
199
-
200
- // Parse put (add) operation object to sql string
201
- function putToSql(dbOpe, sqlRequest) {
202
- let result = 'insert into ' + fullyQualifiedTableName(dbOpe.put.schema);
203
-
204
- if ((dbOpe.put.sets) && (Object.keys(dbOpe.put.sets).length > 0)) {
205
- let result_f = ' ('; let result_v = ' values (';
206
- let _first = true;
207
- for (const [key, value] of Object.entries(dbOpe.put.sets)) {
208
- if (!_first) { result_f += ', '; result_v += ', '; } else { _first = false }
209
- if (key || value) { result_f += key; result_v += stringifyValue(key, value, dbOpe.put.schema); }
210
- }
211
- result_f += ')'; result_v += ')';
212
- result += result_f + result_v;
213
- }
214
- else { throw new Error('sets is missing.'); }
215
-
216
- if (dbOpe.put.params) addParams(dbOpe.put.params, sqlRequest);
217
-
218
- result += ';'
219
-
220
- return result;
221
- }
222
-
223
- // Parse delete operation object to sql string
224
- function deleteToSql(dbOpe, sqlRequest) {
225
- let result = 'delete from ' + fullyQualifiedTableName(dbOpe.delete.schema);
226
-
227
- if ((dbOpe.delete.filters) && (Object.keys(dbOpe.delete.filters).length > 0)) {
228
- if (Array.isArray(dbOpe.delete.filters)) result += ' where ' + dbOpe.delete.filters.join(' ');
229
- else result += ' where ' + dbOpe.delete.filters;
230
- }
231
-
232
- if (dbOpe.delete.params) addParams(dbOpe.delete.params, sqlRequest);
233
-
234
- result += ';'
235
-
236
- return result;
237
- }
238
-
239
- // Parse execute operation object to sql string
240
- function executeToSql(dbOpe, sqlRequest) {
241
- let result = "execute ";
242
-
243
- if (dbOpe.execute.schema.procedure) {
244
- result += dbOpe.execute.schema.procedure.command;
245
- if (dbOpe.execute.arguments) result += (' ' + dbOpe.execute.arguments);
246
- }
247
- else { throw new Error('missing procedure/function name.'); }
248
-
249
- if (dbOpe.execute.params) addParams(dbOpe.execute.params, sqlRequest);
250
-
251
- result += ';'
252
-
253
- return result;
254
- }
255
-
256
- // Parse begin operation object to sql string
257
- function beginToSql(dbOpe, sqlRequest) {
258
- return "BEGIN TRANSACTION;";
259
- }
260
-
261
- // Parse commit operation object to sql string
262
- function commitToSql(dbOpe, sqlRequest) {
263
- return "IF @@TRANCOUNT > 0 COMMIT TRANSACTION;";
264
- }
265
-
266
- // Add input parameters to pool.request
267
- function addParams(params, sqlRequest) {
268
- if (params) {
269
- for (const [key, value] of Object.entries(params)) {
270
- sqlRequest.input(key, value)
271
- }
272
- }
273
- return;
1
+ 'use strict';
2
+
3
+ import sql from 'mssql';
4
+
5
+ // Regex
6
+ const _match_LIMIT = /(?:^|\W)(LIMIT )/ig
7
+
8
+ const pools = {};
9
+
10
+ // Common
11
+ function stringifyValue(fieldName, value, tSchema) {
12
+ if (value == undefined) { return 'null' }
13
+ if (typeof value !== 'string' || value.trimStart().charAt(0) !== '[') {
14
+ if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
15
+ if (tSchema.table.fields[fieldName].type == 'datetime') {
16
+ if (typeof value == 'datetime' || typeof value == 'object') return `\'${value.toISOString()}\'`;
17
+ if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
18
+ return value;
19
+ }
20
+ if (tSchema.table.fields[fieldName].type == 'boolean' && typeof value == 'boolean') return `\'${value}\'`;
21
+ if (tSchema.table.fields[fieldName].type == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
22
+ if (tSchema.table.fields[fieldName].type == 'uuid' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
23
+ }
24
+ else {
25
+ // if (typeof value == 'datetime') return `\'${value.toISOString()}\'`;
26
+ if (typeof value == 'boolean') return `\'${value}\'`;
27
+ if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
28
+ }
29
+ }
30
+ return value;
31
+ }
32
+
33
+ // Create config object for pool
34
+ export function prepareConnection(tSchema) {
35
+ return {
36
+ id: `${tSchema.server.realName}-${tSchema.database.realName}-${tSchema.server.user}`,
37
+ server: ((tSchema.server.instance && tSchema.server.instance != 'DEFAULT') ? (tSchema.server.realName + '\\' + tSchema.server.instance) : tSchema.server.realName) ?? 'localhost',
38
+ port: tSchema.server.port,
39
+ user: tSchema.server.user,
40
+ password: tSchema.server.password,
41
+ options: {
42
+ appName: tSchema.server.options?.appName,
43
+ encrypt: tSchema.server.options?.encrypt ?? false, // true for azure
44
+ trustServerCertificate: tSchema.server.options?.trustServerCertificate ?? true // true for local dev / self-signed certs
45
+ },
46
+ pool: tSchema.server.pool,
47
+ database: tSchema.database.realName
48
+ };
49
+ };
50
+
51
+ // Close connection
52
+ export async function closeConnection(connection) {
53
+ let pool = pools[connection.id];
54
+ if (pool) {
55
+ await pool.close(); // wait pool is closed
56
+ pools[connection.id] = undefined; // remove pool from pools
57
+ }
58
+ }
59
+
60
+ // Close all connections
61
+ export async function closeAllConnections() {
62
+ for (let poolId in pools) {
63
+ if (!pools.hasOwnProperty(poolId)) continue;
64
+ let pool = pools[poolId];
65
+ if (pool) {
66
+ await pool.close(); // wait pool is closed
67
+ pool = undefined; // remove pool from pools
68
+ }
69
+ }
70
+ }
71
+
72
+ // Query
73
+ export async function query(connection, dbOpes) {
74
+
75
+ // Prepare pool
76
+ let pool = pools[connection.id]; // Try to get an existing pool
77
+ if (!pool) {
78
+ pool = new sql.ConnectionPool(connection); // Create new pool
79
+ try { await pool.connect(); // wait that connection are made
80
+ } catch(err) { throw(err); } // using original error
81
+ pools[connection.id] = pool; // add new pool to pools
82
+ }
83
+
84
+ // Prepare sql statement
85
+ let sqlString = '';
86
+ let sqlRequest = pool.request();
87
+ // if exists, input params will be added to request
88
+ if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, sqlRequest); });
89
+ else sqlString += ToSql(dbOpes, sqlRequest);
90
+
91
+ // Run query
92
+ const sqlresult = await sqlRequest.query(sqlString);
93
+
94
+ // Return a single object if there is only 1 row
95
+ if (sqlresult.recordsets.length === 0) return;
96
+ if (sqlresult.recordsets.length === 1) return sqlresult.recordsets[0];
97
+ else return sqlresult.recordsets;
98
+ }
99
+
100
+ // Normalize field name
101
+ //function toFieldName(s) {
102
+ // if ( s.trimStart().charAt(0) === '[' ) return s;
103
+ // else return `\[${s}\]`;
104
+ //}
105
+
106
+ // Compose fully qualified table name
107
+ function fullyQualifiedTableName(tSchema) {
108
+ return (tSchema.database.realName + '.' + (tSchema.table.schema ?? '') + '.' + tSchema.table.realName);
109
+ }
110
+
111
+ function replaceLIMITToTOP(s) {
112
+ return s.replace(_match_LIMIT,' TOP ')
113
+ }
114
+
115
+ // Parse oprations object to sql string
116
+ function ToSql(dbOpe, sqlRequest) {
117
+ if (dbOpe.get) return getToSql(dbOpe, sqlRequest);
118
+ if (dbOpe.patch) return patchToSql(dbOpe, sqlRequest);
119
+ if (dbOpe.put) return putToSql(dbOpe, sqlRequest);
120
+ if (dbOpe.delete) return deleteToSql(dbOpe, sqlRequest);
121
+ if (dbOpe.execute) return executeToSql(dbOpe, sqlRequest);
122
+ if (dbOpe.begin) return beginToSql(dbOpe, sqlRequest);
123
+ if (dbOpe.commit) return commitToSql(dbOpe, sqlRequest);
124
+ if (dbOpe.passthrough) return passthroughToSql(dbOpe, sqlRequest);
125
+ }
126
+
127
+ // Parse operation object to sql string without any trasformation.
128
+ function passthroughToSql(dbOpe, sqlRequest) {
129
+
130
+ let result = "";
131
+
132
+ if (dbOpe.passthrough.command) {
133
+ result += dbOpe.passthrough.command;
134
+ }
135
+ else { throw new Error('command is missing.'); }
136
+
137
+ if (dbOpe.passthrough.params) addParams(dbOpe.passthrough.params, sqlRequest);
138
+
139
+ return result;
140
+ }
141
+
142
+ // Parse get operation object to sql string
143
+ function getToSql(dbOpe, sqlRequest) {
144
+ let _first = true;
145
+
146
+ let result = 'select'
147
+
148
+ if ((dbOpe.get.options) && (Object.keys(dbOpe.get.options).length > 0)) {
149
+ if (Array.isArray(dbOpe.get.options)) { for (const s of dbOpe.get.options) { result += ' ' + replaceLIMITToTOP(s); }}
150
+ else result += ' ' + replaceLIMITToTOP(dbOpe.get.options);
151
+ }
152
+
153
+ if ((dbOpe.get.fields) && (Object.keys(dbOpe.get.fields).length > 0)) {
154
+ if (Array.isArray(dbOpe.get.fields)) result += ' ' + dbOpe.get.fields.join(',')
155
+ else result += ' ' + dbOpe.get.fields;
156
+ }
157
+ else { throw new Error('fields is missing.'); }
158
+
159
+ result += ' from ' + fullyQualifiedTableName(dbOpe.get.schema);
160
+
161
+ if ((dbOpe.get.filters) && (Object.keys(dbOpe.get.filters).length > 0)) {
162
+ if (Array.isArray(dbOpe.get.filters)) result += ' where ' + dbOpe.get.filters.join(' ');
163
+ else result += ' where ' + dbOpe.get.filters;
164
+ }
165
+
166
+ if ((dbOpe.get.groups) && (Object.keys(dbOpe.get.groups).length > 0)) {
167
+ if (Array.isArray(dbOpe.get.groups)) result += ' group by ' + dbOpe.get.groups.join(', ');
168
+ else result += ' group by ' + dbOpe.get.groups;
169
+ }
170
+
171
+ if ((dbOpe.get.groupsFilters) && (Object.keys(dbOpe.get.groupsFilters).length > 0)) {
172
+ if (Array.isArray(dbOpe.get.groupsFilters)) result += ' having ' + dbOpe.get.groupsFilters.join(' ');
173
+ else result += ' having ' + dbOpe.get.groupsFilters;
174
+ }
175
+
176
+ if ((dbOpe.get.orderBy) && (Object.keys(dbOpe.get.orderBy).length > 0)) {
177
+ if (Array.isArray(dbOpe.get.orderBy)) result += ' order by ' + dbOpe.get.orderBy.join(', ');
178
+ else result += ' order by ' + dbOpe.get.orderBy;
179
+ }
180
+
181
+ if (dbOpe.get.params) addParams(dbOpe.get.params, sqlRequest);
182
+
183
+ result += ';'
184
+
185
+ return result;
186
+ }
187
+
188
+ // Parse patch operation object to sql string
189
+ function patchToSql(dbOpe, sqlRequest) {
190
+ let result = 'update ' + fullyQualifiedTableName(dbOpe.patch.schema);
191
+
192
+ if (dbOpe.patch.sets) { result += ' set ' + Object.entries(dbOpe.patch.sets).map(e => { return e[0] + '=' + stringifyValue(e[0], e[1], dbOpe.patch.schema) }).join(', '); }
193
+ else { throw new Error('sets is missing.'); }
194
+
195
+ if ((dbOpe.patch.filters) && (Object.keys(dbOpe.patch.filters).length > 0)) {
196
+ if (Array.isArray(dbOpe.patch.filters)) result += ' where ' + dbOpe.patch.filters.join(' ');
197
+ else result += ' where ' + dbOpe.patch.filters;
198
+ }
199
+
200
+ if (dbOpe.patch.params) addParams(dbOpe.patch.params, sqlRequest);
201
+
202
+ result += ';'
203
+
204
+ return result;
205
+ }
206
+
207
+ // Parse put (add) operation object to sql string
208
+ function putToSql(dbOpe, sqlRequest) {
209
+ let result = 'insert into ' + fullyQualifiedTableName(dbOpe.put.schema);
210
+
211
+ if ((dbOpe.put.sets) && (Object.keys(dbOpe.put.sets).length > 0)) {
212
+ let result_f = ' ('; let result_v = ' values (';
213
+ let _first = true;
214
+ for (const [key, value] of Object.entries(dbOpe.put.sets)) {
215
+ if (!_first) { result_f += ', '; result_v += ', '; } else { _first = false }
216
+ if (key || value) { result_f += key; result_v += stringifyValue(key, value, dbOpe.put.schema); }
217
+ }
218
+ result_f += ')'; result_v += ')';
219
+ result += result_f + result_v;
220
+ }
221
+ else { throw new Error('sets is missing.'); }
222
+
223
+ if (dbOpe.put.params) addParams(dbOpe.put.params, sqlRequest);
224
+
225
+ result += ';'
226
+
227
+ return result;
228
+ }
229
+
230
+ // Parse delete operation object to sql string
231
+ function deleteToSql(dbOpe, sqlRequest) {
232
+ let result = 'delete from ' + fullyQualifiedTableName(dbOpe.delete.schema);
233
+
234
+ if ((dbOpe.delete.filters) && (Object.keys(dbOpe.delete.filters).length > 0)) {
235
+ if (Array.isArray(dbOpe.delete.filters)) result += ' where ' + dbOpe.delete.filters.join(' ');
236
+ else result += ' where ' + dbOpe.delete.filters;
237
+ }
238
+
239
+ if (dbOpe.delete.params) addParams(dbOpe.delete.params, sqlRequest);
240
+
241
+ result += ';'
242
+
243
+ return result;
244
+ }
245
+
246
+ // Parse execute operation object to sql string
247
+ function executeToSql(dbOpe, sqlRequest) {
248
+ let result = "execute ";
249
+
250
+ if (dbOpe.execute.schema.procedure) {
251
+ result += dbOpe.execute.schema.procedure.command;
252
+ if (dbOpe.execute.arguments) result += (' ' + dbOpe.execute.arguments);
253
+ }
254
+ else { throw new Error('missing procedure/function name.'); }
255
+
256
+ if (dbOpe.execute.params) addParams(dbOpe.execute.params, sqlRequest);
257
+
258
+ result += ';'
259
+
260
+ return result;
261
+ }
262
+
263
+ // Parse begin operation object to sql string
264
+ function beginToSql(dbOpe, sqlRequest) {
265
+ return "BEGIN TRANSACTION;";
266
+ }
267
+
268
+ // Parse commit operation object to sql string
269
+ function commitToSql(dbOpe, sqlRequest) {
270
+ return "IF @@TRANCOUNT > 0 COMMIT TRANSACTION;";
271
+ }
272
+
273
+ // Add input parameters to pool.request
274
+ function addParams(params, sqlRequest) {
275
+ if (params) {
276
+ for (const [key, value] of Object.entries(params)) {
277
+ sqlRequest.input(key, value)
278
+ }
279
+ }
280
+ return;
274
281
  }
package/lib/mysql.js CHANGED
@@ -1,278 +1,306 @@
1
- 'use strict';
2
-
3
- import sql from 'mysql2/promise';
4
-
5
- const pools = {};
6
-
7
- // Common
8
- function stringifyValue(fieldName, value, tSchema) {
9
- if (value == undefined) { return 'null' }
10
- if (typeof value !== 'string' || value.trimStart().charAt(0) !== '\`') {
11
- if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
12
- if (tSchema.table.fields[fieldName].type == 'datetime') {
13
- if (typeof value == 'datetime' || typeof value == 'object') return `\'${value.toISOString().slice(0, 19).replace('T', ' ')}\'`;
14
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
15
- return value;
16
- }
17
- if (tSchema.table.fields[fieldName].type == 'boolean' && typeof value == 'boolean') return `\'${value}\'`;
18
- if (tSchema.table.fields[fieldName].type == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
19
- if (tSchema.table.fields[fieldName].type == 'uuid' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
20
- }
21
- else {
22
- // if (typeof value == 'datetime') return `\'${value.toISOString().slice(0, 19).replace('T', ' ')}\'`;
23
- if (typeof value == 'boolean') return `\'${value}\'`;
24
- if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
25
- }
26
- }
27
- return value;
28
- }
29
-
30
- // Create config object for pool
31
- export function prepareConnection(tSchema) {
32
- return {
33
- id: `${tSchema.server.realName}-${tSchema.database.realName}-${tSchema.server.user}`,
34
- host: ((tSchema.server.instance && tSchema.server.instance != 'DEFAULT') ? (tSchema.server.realName + '\\' + tSchema.server.instance) : tSchema.server.realName) ?? 'localhost',
35
- port: tSchema.server.port,
36
- user: tSchema.server.user,
37
- password: tSchema.server.password,
38
- database: tSchema.database.realName,
39
- ssl : {
40
- rejectUnauthorized: false
41
- },
42
- multipleStatements: true,
43
- connectionLimit: tSchema.server.connectionLimit
44
- };
45
- };
46
-
47
- // Close connection
48
- export async function closeConnection(connection) {
49
- let pool = pools[connection.id];
50
- if (pool) {
51
- pool.releaseConnection();
52
- connection.end();
53
- pools[connection.id] = undefined; // remove pool from pools
54
- }
55
- }
56
-
57
- // Close all connections
58
- export async function closeAllConnections() {
59
- for (let poolId in pools) {
60
- if (!pools.hasOwnProperty(poolId)) continue;
61
- let pool = pools[poolId];
62
- if (pool) {
63
- pool.end();
64
- pool = undefined; // remove pool from pools
65
- }
66
- }
67
- }
68
-
69
- // Query
70
- export async function query(connection, dbOpes) {
71
-
72
- // Prepare pool
73
- let pool = pools[connection.id]; // Try to get an existing pool
74
- if (!pool) {
75
- pool = new sql.createPool(connection); // Create new pool
76
- pools[connection.id] = pool; // add new pool to pools
77
- }
78
-
79
- // Prepare sql statement
80
- let sqlString = '';
81
- // if exists, input params will be added to request
82
- if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, pool); });
83
- else sqlString += ToSql(dbOpes, pool);
84
-
85
- // Run query
86
- let sqlresult = undefined;
87
- let sqlconn = undefined;
88
- try {
89
- sqlconn = await pool.getConnection();
90
- sqlresult = await sqlconn.query(sqlString);
91
- }
92
- catch(err) { throw(err); } // using original error
93
- finally { if (sqlconn) sqlconn.release(); }
94
-
95
- // Return single object if there is only 1 row
96
- if (sqlresult[0].length === 0) return;
97
- if (sqlresult[0].length === 1) return sqlresult[0][0];
98
- else return sqlresult[0];
99
- }
100
-
101
- // Normalize field name
102
- //function toFieldName(s) {
103
- // if ( s.trimStart().charAt(0) === '\`' ) return s;
104
- // else return `\`${s}\``;
105
- //}
106
-
107
- // Compose fully qualified table name
108
- function fullyQualifiedTableName(tSchema) {
109
- return (tSchema.database.realName + '.' + tSchema.table.realName);
110
- }
111
-
112
- // Parse oprations object to sql string
113
- function ToSql(dbOpe, sqlRequest) {
114
- if (dbOpe.get) return getToSql(dbOpe, sqlRequest);
115
- if (dbOpe.patch) return patchToSql(dbOpe, sqlRequest);
116
- if (dbOpe.put) return putToSql(dbOpe, sqlRequest);
117
- if (dbOpe.delete) return deleteToSql(dbOpe, sqlRequest);
118
- if (dbOpe.execute) return executeToSql(dbOpe, sqlRequest);
119
- if (dbOpe.begin) return beginToSql(dbOpe, sqlRequest);
120
- if (dbOpe.commit) return commitToSql(dbOpe, sqlRequest);
121
- if (dbOpe.passthrough) return passthroughToSql(dbOpe, sqlRequest);
122
- }
123
-
124
- // Parse operation object to sql string without any trasformation.
125
- function passthroughToSql(dbOpe, sqlRequest) {
126
-
127
- let result = "";
128
-
129
- if (dbOpe.passthrough.command) {
130
- result += dbOpe.passthrough.command;
131
- }
132
- else { throw new Error('command is missing.'); }
133
-
134
- if (dbOpe.passthrough.params) addParams(dbOpe.passthrough.params, sqlRequest);
135
-
136
- return result;
137
- }
138
-
139
- // Parse get operation object to sql string
140
- function getToSql(dbOpe, sqlRequest) {
141
- let _first = true;
142
-
143
- let result = 'select '
144
-
145
- if ((dbOpe.get.fields) && (Object.keys(dbOpe.get.fields).length > 0)) {
146
- if (Array.isArray(dbOpe.get.fields)) result += dbOpe.get.fields.join(', ');
147
- else result += dbOpe.get.fields;
148
- }
149
- else { throw new Error('fields is missing.'); }
150
-
151
- result += ' from ' + fullyQualifiedTableName(dbOpe.get.schema);
152
-
153
- if ((dbOpe.get.filters) && (Object.keys(dbOpe.get.filters).length > 0)) {
154
- if (Array.isArray(dbOpe.get.filters)) result += ' where ' + dbOpe.get.filters.join(' ');
155
- else result += ' where ' + dbOpe.get.filters;
156
- }
157
-
158
- if ((dbOpe.get.groups) && (Object.keys(dbOpe.get.groups).length > 0)) {
159
- if (Array.isArray(dbOpe.get.groups)) result += ' group by ' + dbOpe.get.groups.join(', ');
160
- else result += ' group by ' + dbOpe.get.groups;
161
- }
162
-
163
- if ((dbOpe.get.groupsFilters) && (Object.keys(dbOpe.get.groupsFilters).length > 0)) {
164
- if (Array.isArray(dbOpe.get.groupsFilters)) result += ' having ' + dbOpe.get.groupsFilters.join(' ');
165
- else result += ' having ' + dbOpe.get.groupsFilters;
166
- }
167
-
168
- if ((dbOpe.get.orderBy) && (Object.keys(dbOpe.get.orderBy).length > 0)) {
169
- if (Array.isArray(dbOpe.get.orderBy)) result += ' order by ' + dbOpe.get.orderBy.join(', ');
170
- else result += ' order by ' + dbOpe.get.orderBy;
171
- }
172
-
173
- if ((dbOpe.get.options) && (Object.keys(dbOpe.get.options).length > 0)) {
174
- if (Array.isArray(dbOpe.get.options)) result += ' ' + dbOpe.get.options.join(' ');
175
- else result += ' ' + dbOpe.get.options;
176
- }
177
-
178
- if (dbOpe.get.params) addParams(dbOpe.get.params, sqlRequest);
179
-
180
- result += ';'
181
-
182
- return result;
183
- }
184
-
185
- // Parse patch operation object to sql string
186
- function patchToSql(dbOpe, sqlRequest) {
187
- let result = 'update ' + fullyQualifiedTableName(dbOpe.patch.schema);
188
-
189
- if (dbOpe.patch.sets) { result += ' set ' + Object.entries(dbOpe.patch.sets).map(e => { return e[0] + '=' + stringifyValue(e[0], e[1], dbOpe.patch.schema) }).join(', '); }
190
- else { throw new Error('sets is missing.'); }
191
-
192
- if ((dbOpe.patch.filters) && (Object.keys(dbOpe.patch.filters).length > 0)) {
193
- if (Array.isArray(dbOpe.patch.filters)) result += ' where ' + dbOpe.patch.filters.join(' ');
194
- else result += ' where ' + dbOpe.patch.filters;
195
- }
196
-
197
- if (dbOpe.patch.params) addParams(dbOpe.patch.params, sqlRequest);
198
-
199
- result += ';'
200
-
201
- return result;
202
- }
203
-
204
- // Parse put (add) operation object to sql string
205
- function putToSql(dbOpe, sqlRequest) {
206
- let result = 'insert into ' + fullyQualifiedTableName(dbOpe.put.schema);
207
-
208
- if ((dbOpe.put.sets) && (Object.keys(dbOpe.put.sets).length > 0)) {
209
- let result_f = ' ('; let result_v = ' values (';
210
- let _first = true;
211
- for (const [key, value] of Object.entries(dbOpe.put.sets)) {
212
- if (!_first) { result_f += ', '; result_v += ', '; } else { _first = false }
213
- if (key || value) { result_f += key; result_v += stringifyValue(key, value, dbOpe.put.schema); }
214
- }
215
- result_f += ')'; result_v += ')';
216
- result += result_f + result_v;
217
- }
218
- else { throw new Error('sets is missing.'); }
219
-
220
- if (dbOpe.put.params) addParams(dbOpe.put.params, sqlRequest);
221
-
222
- result += ';'
223
-
224
- return result;
225
- }
226
-
227
- // Parse delete operation object to sql string
228
- function deleteToSql(dbOpe, sqlRequest) {
229
- let result = 'delete from ' + fullyQualifiedTableName(dbOpe.delete.schema);
230
-
231
- if ((dbOpe.delete.filters) && (Object.keys(dbOpe.delete.filters).length > 0)) {
232
- if (Array.isArray(dbOpe.delete.filters)) result += ' where ' + dbOpe.delete.filters.join(' ');
233
- else result += ' where ' + dbOpe.delete.filters;
234
- }
235
-
236
- if (dbOpe.delete.params) addParams(dbOpe.delete.params, sqlRequest);
237
-
238
- result += ';'
239
-
240
- return result;
241
- }
242
-
243
- // Parse execute operation object to sql string
244
- function executeToSql(dbOpe, sqlRequest) {
245
- let result = "CALL ";
246
-
247
- if (dbOpe.execute.schema.procedure) {
248
- result += dbOpe.execute.schema.procedure.command;
249
- if (dbOpe.execute.arguments) { result += ('(' + dbOpe.execute.arguments) + ')'; }
250
- }
251
- else { throw new Error('missing procedure/function name.'); }
252
-
253
- if (dbOpe.execute.params) addParams(dbOpe.execute.params, sqlRequest);
254
-
255
- result += ';'
256
-
257
- return result;
258
- }
259
-
260
- // Parse begin operation object to sql string
261
- function beginToSql(dbOpe, sqlRequest) {
262
- return "START TRANSACTION; ";
263
- }
264
-
265
- // Parse commit operation object to sql string
266
- function commitToSql(dbOpe, sqlRequest) {
267
- return " COMMIT;";
268
- }
269
-
270
- // Add input parameters to pool.request
271
- function addParams(params, sqlRequest) {
272
- if (params) {
273
- for (const [key, value] of Object.entries(params)) {
274
- sqlRequest.input(key, value)
275
- }
276
- }
277
- return;
1
+ 'use strict';
2
+
3
+ import sql from 'mysql2/promise';
4
+
5
+ // Regex
6
+ const _match_LIMIT = /(?:^|\W)(LIMIT )/ig
7
+ const _match_TOP = /(?:^|\W)(TOP )/ig
8
+
9
+ const pools = {};
10
+
11
+ // Common
12
+ function stringifyValue(fieldName, value, tSchema) {
13
+ if (value == undefined) { return 'null' }
14
+ if (typeof value !== 'string' || value.trimStart().charAt(0) !== '\`') {
15
+ if (tSchema.table.fields && tSchema.table.fields[fieldName] && tSchema.table.fields[fieldName].type) {
16
+ if (tSchema.table.fields[fieldName].type == 'datetime') {
17
+ if (typeof value == 'datetime' || typeof value == 'object') return `\'${value.toISOString().slice(0, 19).replace('T', ' ')}\'`;
18
+ if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
19
+ return value;
20
+ }
21
+ if (tSchema.table.fields[fieldName].type == 'boolean' && typeof value == 'boolean') return `\'${value}\'`;
22
+ if (tSchema.table.fields[fieldName].type == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
23
+ if (tSchema.table.fields[fieldName].type == 'uuid' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
24
+ }
25
+ else {
26
+ // if (typeof value == 'datetime') return `\'${value.toISOString().slice(0, 19).replace('T', ' ')}\'`;
27
+ if (typeof value == 'boolean') return `\'${value}\'`;
28
+ if (typeof value == 'string' && value.trimStart().charAt(0) !== '\'' && value.trimStart().charAt(0) !== '\"') return `\'${value}\'`;
29
+ }
30
+ }
31
+ return value;
32
+ }
33
+
34
+ // Create config object for pool
35
+ export function prepareConnection(tSchema) {
36
+ return {
37
+ id: `${tSchema.server.realName}-${tSchema.database.realName}-${tSchema.server.user}`,
38
+ host: ((tSchema.server.instance && tSchema.server.instance != 'DEFAULT') ? (tSchema.server.realName + '\\' + tSchema.server.instance) : tSchema.server.realName) ?? 'localhost',
39
+ port: tSchema.server.port,
40
+ user: tSchema.server.user,
41
+ password: tSchema.server.password,
42
+ database: tSchema.database.realName,
43
+ ssl: {
44
+ rejectUnauthorized: false
45
+ },
46
+ multipleStatements: true,
47
+ connectionLimit: tSchema.server.connectionLimit
48
+ };
49
+ };
50
+
51
+ // Close connection
52
+ export async function closeConnection(connection) {
53
+ let pool = pools[connection.id];
54
+ if (pool) {
55
+ pool.releaseConnection();
56
+ connection.end();
57
+ pools[connection.id] = undefined; // remove pool from pools
58
+ }
59
+ }
60
+
61
+ // Close all connections
62
+ export async function closeAllConnections() {
63
+ for (let poolId in pools) {
64
+ if (!pools.hasOwnProperty(poolId)) continue;
65
+ let pool = pools[poolId];
66
+ if (pool) {
67
+ pool.end();
68
+ pool = undefined; // remove pool from pools
69
+ }
70
+ }
71
+ }
72
+
73
+ // Query
74
+ export async function query(connection, dbOpes) {
75
+
76
+ // Prepare pool
77
+ let pool = pools[connection.id]; // Try to get an existing pool
78
+ if (!pool) {
79
+ pool = new sql.createPool(connection); // Create new pool
80
+ pools[connection.id] = pool; // add new pool to pools
81
+ }
82
+
83
+ // Prepare sql statement
84
+ let sqlString = '';
85
+ // if exists, input params will be added to request
86
+ if (Array.isArray(dbOpes)) dbOpes.forEach((dbOpe, index) => { sqlString += ToSql(dbOpe, pool); });
87
+ else sqlString += ToSql(dbOpes, pool);
88
+
89
+ // Run query
90
+ let sqlresult = undefined;
91
+ let sqlconn = undefined;
92
+ try {
93
+ sqlconn = await pool.getConnection();
94
+ sqlresult = await sqlconn.query(sqlString);
95
+ }
96
+ catch (err) { throw (err); } // using original error
97
+ finally { if (sqlconn) sqlconn.release(); }
98
+
99
+ // Return single object if there is only 1 row
100
+ if (sqlresult[0].length === 0) return;
101
+ if (sqlresult[0].length === 1) return sqlresult[0][0];
102
+ else return sqlresult[0];
103
+ }
104
+
105
+ // Normalize field name
106
+ //function toFieldName(s) {
107
+ // if ( s.trimStart().charAt(0) === '\`' ) return s;
108
+ // else return `\`${s}\``;
109
+ //}
110
+
111
+ // Compose fully qualified table name
112
+ function fullyQualifiedTableName(tSchema) {
113
+ return (tSchema.database.realName + '.' + tSchema.table.realName);
114
+ }
115
+
116
+
117
+ function containLIMIT(s) {
118
+ return s.match(_match_LIMIT);
119
+ };
120
+
121
+ function containTOP(s) {
122
+ return s.match(_match_TOP);
123
+ };
124
+
125
+ function replaceTOPToLIMIT(s) {
126
+ return s.replace(_match_TOP, ' LIMIT ')
127
+ }
128
+
129
+ // Parse oprations object to sql string
130
+ function ToSql(dbOpe, sqlRequest) {
131
+ if (dbOpe.get) return getToSql(dbOpe, sqlRequest);
132
+ if (dbOpe.patch) return patchToSql(dbOpe, sqlRequest);
133
+ if (dbOpe.put) return putToSql(dbOpe, sqlRequest);
134
+ if (dbOpe.delete) return deleteToSql(dbOpe, sqlRequest);
135
+ if (dbOpe.execute) return executeToSql(dbOpe, sqlRequest);
136
+ if (dbOpe.begin) return beginToSql(dbOpe, sqlRequest);
137
+ if (dbOpe.commit) return commitToSql(dbOpe, sqlRequest);
138
+ if (dbOpe.passthrough) return passthroughToSql(dbOpe, sqlRequest);
139
+ }
140
+
141
+ // Parse operation object to sql string without any trasformation.
142
+ function passthroughToSql(dbOpe, sqlRequest) {
143
+
144
+ let result = "";
145
+
146
+ if (dbOpe.passthrough.command) {
147
+ result += dbOpe.passthrough.command;
148
+ }
149
+ else { throw new Error('command is missing.'); }
150
+
151
+ if (dbOpe.passthrough.params) addParams(dbOpe.passthrough.params, sqlRequest);
152
+
153
+ return result;
154
+ }
155
+
156
+ // Parse get operation object to sql string
157
+ function getToSql(dbOpe, sqlRequest) {
158
+ let _first = true;
159
+
160
+ let result = 'select'
161
+
162
+ // omit 'limit' or 'top'
163
+ if ((dbOpe.get.options) && (Object.keys(dbOpe.get.options).length > 0)) {
164
+ if (Array.isArray(dbOpe.get.options)) {
165
+ for (const s of dbOpe.get.options) { if (!containLIMIT(s) && !containTOP(s)) result += ' ' + s; }
166
+ }
167
+ else if (!containLIMIT(dbOpe.get.options) && !containTOP(dbOpe.get.options)) result += ' ' + dbOpe.get.options;
168
+ }
169
+
170
+ if ((dbOpe.get.fields) && (Object.keys(dbOpe.get.fields).length > 0)) {
171
+ if (Array.isArray(dbOpe.get.fields)) result += ' ' + dbOpe.get.fields.join(',')
172
+ else result += ' ' + dbOpe.get.fields;
173
+ }
174
+ else { throw new Error('fields is missing.'); }
175
+
176
+ result += ' from ' + fullyQualifiedTableName(dbOpe.get.schema);
177
+
178
+ if ((dbOpe.get.filters) && (Object.keys(dbOpe.get.filters).length > 0)) {
179
+ if (Array.isArray(dbOpe.get.filters)) result += ' where ' + dbOpe.get.filters.join(' ');
180
+ else result += ' where ' + dbOpe.get.filters;
181
+ }
182
+
183
+ if ((dbOpe.get.groups) && (Object.keys(dbOpe.get.groups).length > 0)) {
184
+ if (Array.isArray(dbOpe.get.groups)) result += ' group by ' + dbOpe.get.groups.join(', ');
185
+ else result += ' group by ' + dbOpe.get.groups;
186
+ }
187
+
188
+ if ((dbOpe.get.groupsFilters) && (Object.keys(dbOpe.get.groupsFilters).length > 0)) {
189
+ if (Array.isArray(dbOpe.get.groupsFilters)) result += ' having ' + dbOpe.get.groupsFilters.join(' ');
190
+ else result += ' having ' + dbOpe.get.groupsFilters;
191
+ }
192
+
193
+ if ((dbOpe.get.orderBy) && (Object.keys(dbOpe.get.orderBy).length > 0)) {
194
+ if (Array.isArray(dbOpe.get.orderBy)) result += ' order by ' + dbOpe.get.orderBy.join(', ');
195
+ else result += ' order by ' + dbOpe.get.orderBy;
196
+ }
197
+
198
+ // search if 'limit' or 'top'
199
+ if ((dbOpe.get.options) && (Object.keys(dbOpe.get.options).length > 0)) {
200
+ if (Array.isArray(dbOpe.get.options)) {
201
+ for (const s of dbOpe.get.options) { if (containLIMIT(s) || containTOP(s)) result += ' ' + replaceTOPToLIMIT(s); }
202
+ }
203
+ else if (containLIMIT(dbOpe.get.options) || containTOP(dbOpe.get.options)) result += ' ' + replaceTOPToLIMIT(dbOpe.get.options);
204
+ }
205
+
206
+ if (dbOpe.get.params) addParams(dbOpe.get.params, sqlRequest);
207
+
208
+ result += ';'
209
+
210
+ return result;
211
+ }
212
+
213
+ // Parse patch operation object to sql string
214
+ function patchToSql(dbOpe, sqlRequest) {
215
+ let result = 'update ' + fullyQualifiedTableName(dbOpe.patch.schema);
216
+
217
+ if (dbOpe.patch.sets) { result += ' set ' + Object.entries(dbOpe.patch.sets).map(e => { return e[0] + '=' + stringifyValue(e[0], e[1], dbOpe.patch.schema) }).join(', '); }
218
+ else { throw new Error('sets is missing.'); }
219
+
220
+ if ((dbOpe.patch.filters) && (Object.keys(dbOpe.patch.filters).length > 0)) {
221
+ if (Array.isArray(dbOpe.patch.filters)) result += ' where ' + dbOpe.patch.filters.join(' ');
222
+ else result += ' where ' + dbOpe.patch.filters;
223
+ }
224
+
225
+ if (dbOpe.patch.params) addParams(dbOpe.patch.params, sqlRequest);
226
+
227
+ result += ';'
228
+
229
+ return result;
230
+ }
231
+
232
+ // Parse put (add) operation object to sql string
233
+ function putToSql(dbOpe, sqlRequest) {
234
+ let result = 'insert into ' + fullyQualifiedTableName(dbOpe.put.schema);
235
+
236
+ if ((dbOpe.put.sets) && (Object.keys(dbOpe.put.sets).length > 0)) {
237
+ let result_f = ' ('; let result_v = ' values (';
238
+ let _first = true;
239
+ for (const [key, value] of Object.entries(dbOpe.put.sets)) {
240
+ if (!_first) { result_f += ', '; result_v += ', '; } else { _first = false }
241
+ if (key || value) { result_f += key; result_v += stringifyValue(key, value, dbOpe.put.schema); }
242
+ }
243
+ result_f += ')'; result_v += ')';
244
+ result += result_f + result_v;
245
+ }
246
+ else { throw new Error('sets is missing.'); }
247
+
248
+ if (dbOpe.put.params) addParams(dbOpe.put.params, sqlRequest);
249
+
250
+ result += ';'
251
+
252
+ return result;
253
+ }
254
+
255
+ // Parse delete operation object to sql string
256
+ function deleteToSql(dbOpe, sqlRequest) {
257
+ let result = 'delete from ' + fullyQualifiedTableName(dbOpe.delete.schema);
258
+
259
+ if ((dbOpe.delete.filters) && (Object.keys(dbOpe.delete.filters).length > 0)) {
260
+ if (Array.isArray(dbOpe.delete.filters)) result += ' where ' + dbOpe.delete.filters.join(' ');
261
+ else result += ' where ' + dbOpe.delete.filters;
262
+ }
263
+
264
+ if (dbOpe.delete.params) addParams(dbOpe.delete.params, sqlRequest);
265
+
266
+ result += ';'
267
+
268
+ return result;
269
+ }
270
+
271
+ // Parse execute operation object to sql string
272
+ function executeToSql(dbOpe, sqlRequest) {
273
+ let result = "CALL ";
274
+
275
+ if (dbOpe.execute.schema.procedure) {
276
+ result += dbOpe.execute.schema.procedure.command;
277
+ if (dbOpe.execute.arguments) { result += ('(' + dbOpe.execute.arguments) + ')'; }
278
+ }
279
+ else { throw new Error('missing procedure/function name.'); }
280
+
281
+ if (dbOpe.execute.params) addParams(dbOpe.execute.params, sqlRequest);
282
+
283
+ result += ';'
284
+
285
+ return result;
286
+ }
287
+
288
+ // Parse begin operation object to sql string
289
+ function beginToSql(dbOpe, sqlRequest) {
290
+ return "START TRANSACTION; ";
291
+ }
292
+
293
+ // Parse commit operation object to sql string
294
+ function commitToSql(dbOpe, sqlRequest) {
295
+ return " COMMIT;";
296
+ }
297
+
298
+ // Add input parameters to pool.request
299
+ function addParams(params, sqlRequest) {
300
+ if (params) {
301
+ for (const [key, value] of Object.entries(params)) {
302
+ sqlRequest.input(key, value)
303
+ }
304
+ }
305
+ return;
278
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "db-crud-api",
3
- "version": "0.3.0",
3
+ "version": "0.3.6",
4
4
  "type": "module",
5
5
  "description": "CRUD api for database tables",
6
6
  "main": "index.js",