meadow 2.0.5 → 2.0.9

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.
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "optOut": false,
3
- "lastUpdateCheck": 1684948692058
3
+ "lastUpdateCheck": 1690759243854
4
4
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "numericVersion": 10000,
3
3
  "releaseNotes": "https://vscode-sqltools.mteixeira.dev/changelog#v-1-0-0",
4
- "run": 1684949902043,
4
+ "run": 1690759233978,
5
5
  "updated": false,
6
6
  "version": "1.0.0",
7
7
  "lastNotificationDate": 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meadow",
3
- "version": "2.0.5",
3
+ "version": "2.0.9",
4
4
  "description": "A data access library.",
5
5
  "main": "source/Meadow.js",
6
6
  "scripts": {
@@ -46,27 +46,28 @@
46
46
  },
47
47
  "homepage": "https://github.com/stevenvelozo/meadow",
48
48
  "devDependencies": {
49
- "alasql": "^3.1.0",
49
+ "alasql": "^4.1.3",
50
50
  "browserify": "^17.0.0",
51
51
  "chai": "4.3.7",
52
- "fable": "^3.0.46",
52
+ "fable": "^3.0.75",
53
53
  "gulp": "^4.0.2",
54
54
  "gulp-babel": "^8.0.0",
55
55
  "gulp-sourcemaps": "^3.0.0",
56
56
  "gulp-terser": "^2.1.0",
57
57
  "gulp-util": "^3.0.8",
58
- "meadow-connection-mysql": "^1.0.2",
58
+ "meadow-connection-mssql": "^1.0.4",
59
+ "meadow-connection-mysql": "^1.0.4",
59
60
  "mocha": "10.2.0",
60
- "mysql2": "^3.3.2",
61
+ "mysql2": "^3.5.2",
61
62
  "nyc": "^15.1.0",
62
63
  "vinyl-buffer": "^1.0.1",
63
64
  "vinyl-source-stream": "^2.0.0"
64
65
  },
65
66
  "dependencies": {
66
67
  "async": "3.2.4",
67
- "foxhound": "^2.0.3",
68
+ "foxhound": "^2.0.8",
68
69
  "is-my-json-valid": "2.20.6",
69
- "npm-check-updates": "^16.10.12",
70
+ "npm-check-updates": "^16.10.17",
70
71
  "simple-get": "^4.0.1"
71
72
  }
72
73
  }
package/source/Meadow.js CHANGED
@@ -135,6 +135,7 @@ var Meadow = function()
135
135
  'ALASQL': require(`./providers/Meadow-Provider-ALASQL.js`),
136
136
  'MeadowEndpoints': require(`./providers/Meadow-Provider-MeadowEndpoints.js`),
137
137
  'MySQL': require(`./providers/Meadow-Provider-MySQL.js`),
138
+ 'MSSQL': require(`./providers/Meadow-Provider-MSSQL.js`),
138
139
  'None': require(`./providers/Meadow-Provider-None.js`),
139
140
  });
140
141
  var setProvider = function(pProviderName)
@@ -0,0 +1,407 @@
1
+ // ##### Part of the **[retold](https://stevenvelozo.github.io/retold/)** system
2
+ /**
3
+ * @license MIT
4
+ * @author <steven@velozo.com>
5
+ */
6
+ var MeadowProvider = function ()
7
+ {
8
+ function createNew(pFable)
9
+ {
10
+ // If a valid Fable object isn't passed in, return a constructor
11
+ if (typeof (pFable) !== 'object')
12
+ {
13
+ return { new: createNew };
14
+ }
15
+ var _Fable = pFable;
16
+ var _GlobalLogLevel = 0;
17
+ if (_Fable.settings.MSSQL)
18
+ {
19
+ _GlobalLogLevel = _Fable.settings.MSSQL.GlobalLogLevel || 0;
20
+ }
21
+
22
+ /**
23
+ * Build a connection pool, shared within this provider.
24
+ * This may be more performant as a shared object.
25
+ */
26
+ var getSQLPool = function ()
27
+ {
28
+ // New-style default connection pool provider
29
+ // There are no legacy MSSQL open source connectors.
30
+ if (typeof (_Fable.MeadowMSSQLProvider) == 'object' && _Fable.MeadowMSSQLProvider.connected)
31
+ {
32
+ return _Fable.MeadowMSSQLProvider.pool;
33
+ }
34
+
35
+ return false;
36
+ };
37
+
38
+ // The Meadow marshaller also passes in the Schema as the third parameter, but this is a blunt function ATM.
39
+ var marshalRecordFromSourceToObject = function (pObject, pRecord)
40
+ {
41
+ // For now, crudely assign everything in pRecord to pObject
42
+ // This is safe in this context, and we don't want to slow down marshalling with millions of hasOwnProperty checks
43
+ for (var tmpColumn in pRecord)
44
+ {
45
+ pObject[tmpColumn] = pRecord[tmpColumn];
46
+ }
47
+ };
48
+
49
+ var getPreparedStatementFromQuery = function (pQuery)
50
+ {
51
+ // Create the MS SQL Prepared Statement class
52
+ let tmpPreparedStatement = _Fable.MeadowMSSQLProvider.preparedStatement;
53
+ // Map the Parameters to Types
54
+ let tmpParameterTypeKeys = Object.keys(pQuery.query.parameterTypes)
55
+ for (let i = 0; i < tmpParameterTypeKeys.length; i++)
56
+ {
57
+ let tmpParameterType = pQuery.query.parameterTypes[tmpParameterTypeKeys[i]];
58
+ if (_Fable.MeadowMSSQLProvider.MSSQL[tmpParameterType] === undefined)
59
+ {
60
+ tmpParameterType = 'Char';
61
+ }
62
+ // TODO: Decide how to filter better cleansing to this layer from the schema; we have access to proper lengths.
63
+ // BEFORE WE ADD THIS BEHAVIOR, DECIDE CONCISTENCY WITH OTHER PROVIDERS WHO ALLOW OVERFLOWING STRINGS
64
+ let tmpParameterEntry = false;
65
+ if ((tmpParameterType === 'Char') || (tmpParameterType === 'VarChar'))
66
+ {
67
+ tmpParameterEntry = _Fable.MeadowMSSQLProvider.MSSQL[tmpParameterType](64);
68
+ }
69
+ else
70
+ {
71
+ tmpParameterEntry = _Fable.MeadowMSSQLProvider.MSSQL[tmpParameterType];
72
+ }
73
+ tmpPreparedStatement.input(tmpParameterTypeKeys[i], tmpParameterEntry);
74
+ }
75
+
76
+ return tmpPreparedStatement;
77
+ };
78
+
79
+ var Create = function (pQuery, fCallback)
80
+ {
81
+ var tmpResult = pQuery.parameters.result;
82
+
83
+ pQuery.setDialect('MSSQL').buildCreateQuery();
84
+
85
+ // TODO: Test the query before executing
86
+ if (pQuery.logLevel > 0 || _GlobalLogLevel > 0)
87
+ {
88
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
89
+ }
90
+
91
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
92
+
93
+ let tmpQueryBody = `${pQuery.query.body} \nSELECT @@IDENTITY AS value;`
94
+
95
+ tmpPreparedStatement.prepare(tmpQueryBody,
96
+ (pPrepareError) =>
97
+ {
98
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
99
+ if (pPrepareError)
100
+ {
101
+ _Fable.log.error(`CREATE Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
102
+ }
103
+
104
+ tmpPreparedStatement.execute(pQuery.query.parameters,
105
+ (pPreparedExecutionError, pPreparedResult) =>
106
+ {
107
+ // release the connection after queries are executed
108
+ tmpPreparedStatement.unprepare(
109
+ (pPreparedStatementUnprepareError) =>
110
+ {
111
+ if (pPreparedStatementUnprepareError)
112
+ {
113
+ _Fable.log.error(`CREATE Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
114
+ }
115
+
116
+ tmpResult.error = pPreparedExecutionError;
117
+ if (pPreparedResult
118
+ && Array.isArray(pPreparedResult.recordset)
119
+ && (pPreparedResult.recordset.length > 0)
120
+ && (pPreparedResult.recordset[0].value))
121
+ {
122
+ tmpResult.value = pPreparedResult.recordset[0].value;
123
+ }
124
+ tmpResult.executed = true;
125
+
126
+ // TODO: Fix very old pattern by es6-izing this whole bash
127
+ return fCallback();
128
+ });
129
+ });
130
+ });
131
+ };
132
+
133
+ // This is a synchronous read, good for a few records.
134
+ // TODO: Add a pipe-able read for huge sets
135
+ var Read = function (pQuery, fCallback)
136
+ {
137
+ var tmpResult = pQuery.parameters.result;
138
+
139
+ pQuery.setDialect('MSSQL').buildReadQuery();
140
+
141
+ if (pQuery.logLevel > 0 ||
142
+ _GlobalLogLevel > 0)
143
+ {
144
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
145
+ }
146
+
147
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
148
+ tmpPreparedStatement.prepare(pQuery.query.body,
149
+ (pPrepareError) =>
150
+ {
151
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
152
+ if (pPrepareError)
153
+ {
154
+ _Fable.log.error(`READ Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
155
+ }
156
+
157
+ tmpPreparedStatement.execute(pQuery.query.parameters,
158
+ (pPreparedExecutionError, pPreparedResult) =>
159
+ {
160
+ // release the connection after queries are executed
161
+ tmpPreparedStatement.unprepare(
162
+ (pPreparedStatementUnprepareError) =>
163
+ {
164
+ if (pPreparedStatementUnprepareError)
165
+ {
166
+ _Fable.log.error(`READ Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
167
+ }
168
+
169
+ //_Fable.log.info(`Prepared statement returned...`, pPreparedResult);
170
+ tmpResult.error = pPreparedExecutionError;
171
+ try
172
+ {
173
+ tmpResult.value = pPreparedResult.recordset;
174
+ }
175
+ catch(pMarshalError)
176
+ {
177
+ _Fable.log.error(`READ Error marshaling prepared statement result: ${pMarshalError}`, pMarshalError);
178
+ }
179
+ tmpResult.executed = true;
180
+ return fCallback();
181
+ });
182
+ })
183
+ });
184
+ };
185
+
186
+ var Update = function (pQuery, fCallback)
187
+ {
188
+ var tmpResult = pQuery.parameters.result;
189
+
190
+ pQuery.setDialect('MSSQL').buildUpdateQuery();
191
+
192
+ if (pQuery.logLevel > 0 ||
193
+ _GlobalLogLevel > 0)
194
+ {
195
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
196
+ }
197
+
198
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
199
+ tmpPreparedStatement.prepare(pQuery.query.body,
200
+ (pPrepareError) =>
201
+ {
202
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
203
+ if (pPrepareError)
204
+ {
205
+ _Fable.log.error(`UPDATE Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
206
+ }
207
+
208
+ tmpPreparedStatement.execute(pQuery.query.parameters,
209
+ (pPreparedExecutionError, pPreparedResult) =>
210
+ {
211
+ // release the connection after queries are executed
212
+ tmpPreparedStatement.unprepare(
213
+ (pPreparedStatementUnprepareError) =>
214
+ {
215
+ if (pPreparedStatementUnprepareError)
216
+ {
217
+ _Fable.log.error(`UPDATE Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
218
+ }
219
+
220
+ //_Fable.log.info(`Prepared statement returned...`, pPreparedResult);
221
+ tmpResult.error = pPreparedExecutionError;
222
+ tmpResult.value = pPreparedResult;
223
+ tmpResult.executed = true;
224
+ return fCallback();
225
+ });
226
+ })
227
+ });
228
+ }
229
+
230
+ var Delete = function (pQuery, fCallback)
231
+ {
232
+ var tmpResult = pQuery.parameters.result;
233
+
234
+ pQuery.setDialect('MSSQL').buildDeleteQuery();
235
+
236
+ if (pQuery.logLevel > 0 ||
237
+ _GlobalLogLevel > 0)
238
+ {
239
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
240
+ }
241
+
242
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
243
+ tmpPreparedStatement.prepare(pQuery.query.body,
244
+ (pPrepareError) =>
245
+ {
246
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
247
+ if (pPrepareError)
248
+ {
249
+ _Fable.log.error(`DELETE Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
250
+ }
251
+
252
+ tmpPreparedStatement.execute(pQuery.query.parameters,
253
+ (pPreparedExecutionError, pPreparedResult) =>
254
+ {
255
+ // release the connection after queries are executed
256
+ tmpPreparedStatement.unprepare(
257
+ (pPreparedStatementUnprepareError) =>
258
+ {
259
+ if (pPreparedStatementUnprepareError)
260
+ {
261
+ _Fable.log.error(`DELETE Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
262
+ }
263
+
264
+ //_Fable.log.info(`Prepared statement returned...`, pPreparedResult);
265
+ tmpResult.error = pPreparedExecutionError;
266
+ tmpResult.value = false;
267
+ try
268
+ {
269
+ tmpResult.value = pPreparedResult.rowsAffected[0];
270
+ }
271
+ catch (pErrorGettingRowcount)
272
+ {
273
+ _Fable.log.warn('Error getting affected rowcount during delete query', { Body: pQuery.query.body, Parameters: pQuery.query.parameters });
274
+ }
275
+ tmpResult.executed = true;
276
+ return fCallback();
277
+ });
278
+ })
279
+ });
280
+ };
281
+
282
+ var Undelete = function (pQuery, fCallback)
283
+ {
284
+ var tmpResult = pQuery.parameters.result;
285
+
286
+ pQuery.setDialect('MSSQL').buildUndeleteQuery();
287
+
288
+ if (pQuery.logLevel > 0 ||
289
+ _GlobalLogLevel > 0)
290
+ {
291
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
292
+ }
293
+
294
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
295
+ tmpPreparedStatement.prepare(pQuery.query.body,
296
+ (pPrepareError) =>
297
+ {
298
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
299
+ if (pPrepareError)
300
+ {
301
+ _Fable.log.error(`UNDELETE Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
302
+ }
303
+
304
+ tmpPreparedStatement.execute(pQuery.query.parameters,
305
+ (pPreparedExecutionError, pPreparedResult) =>
306
+ {
307
+ // release the connection after queries are executed
308
+ tmpPreparedStatement.unprepare(
309
+ (pPreparedStatementUnprepareError) =>
310
+ {
311
+ if (pPreparedStatementUnprepareError)
312
+ {
313
+ _Fable.log.error(`UNDELETE Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
314
+ }
315
+
316
+ //_Fable.log.info(`Prepared statement returned...`, pPreparedResult);
317
+ tmpResult.error = pPreparedExecutionError;
318
+ tmpResult.value = false;
319
+ try
320
+ {
321
+ tmpResult.value = pPreparedResult.rowsAffected[0];
322
+ }
323
+ catch (pErrorGettingRowcount)
324
+ {
325
+ _Fable.log.warn('Error getting affected rowcount during undelete query', { Body: pQuery.query.body, Parameters: pQuery.query.parameters });
326
+ }
327
+ tmpResult.executed = true;
328
+ return fCallback();
329
+ });
330
+ })
331
+ });
332
+ };
333
+
334
+ var Count = function (pQuery, fCallback)
335
+ {
336
+ var tmpResult = pQuery.parameters.result;
337
+
338
+ pQuery.setDialect('MSSQL').buildCountQuery();
339
+
340
+ if (pQuery.logLevel > 0 ||
341
+ _GlobalLogLevel > 0)
342
+ {
343
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
344
+ }
345
+
346
+ let tmpPreparedStatement = getPreparedStatementFromQuery(pQuery);
347
+ tmpPreparedStatement.prepare(pQuery.query.body,
348
+ (pPrepareError) =>
349
+ {
350
+ // TODO: This will likely blow up the world. It will definitely happen when the schema doesn't generate good constraints from the inputs.
351
+ if (pPrepareError)
352
+ {
353
+ _Fable.log.error(`COUNT Error preparing prepared statement: ${pPrepareError}`, pPrepareError);
354
+ }
355
+
356
+ tmpPreparedStatement.execute(pQuery.query.parameters,
357
+ (pPreparedExecutionError, pPreparedResult) =>
358
+ {
359
+ // release the connection after queries are executed
360
+ tmpPreparedStatement.unprepare(
361
+ (pPreparedStatementUnprepareError) =>
362
+ {
363
+ if (pPreparedStatementUnprepareError)
364
+ {
365
+ _Fable.log.error(`COUNT Error unpreparing prepared statement: ${pPreparedStatementUnprepareError}`, pPreparedStatementUnprepareError);
366
+ }
367
+
368
+ //_Fable.log.info(`Prepared statement returned...`, pPreparedResult);
369
+ tmpResult.error = pPreparedExecutionError;
370
+ tmpResult.value = false;
371
+ try
372
+ {
373
+ tmpResult.value = pPreparedResult.recordset[0].Row_Count;
374
+ }
375
+ catch (pErrorGettingRowcount)
376
+ {
377
+ _Fable.log.warn('Error getting affected rowcount during count query', { Body: pQuery.query.body, Parameters: pQuery.query.parameters });
378
+ }
379
+ tmpResult.executed = true;
380
+ return fCallback();
381
+ });
382
+ })
383
+ });
384
+ };
385
+
386
+ var tmpNewProvider = (
387
+ {
388
+ marshalRecordFromSourceToObject: marshalRecordFromSourceToObject,
389
+
390
+ Create: Create,
391
+ Read: Read,
392
+ Update: Update,
393
+ Delete: Delete,
394
+ Undelete: Undelete,
395
+ Count: Count,
396
+
397
+ new: createNew
398
+ });
399
+
400
+
401
+ return tmpNewProvider;
402
+ }
403
+
404
+ return createNew();
405
+ };
406
+
407
+ module.exports = new MeadowProvider();