meadow 1.0.30 → 1.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/README.md CHANGED
@@ -121,4 +121,5 @@ meadow.doRead(queryDescription,
121
121
  console.log('Found customer ID '+customer.customerID+' who is named '+customer.name);
122
122
  }
123
123
  );
124
- ```
124
+ ```
125
+
@@ -0,0 +1,94 @@
1
+
2
+ var libMeadow = require('../source/Meadow.js');
3
+
4
+ var tmpFableSettings = (
5
+ {
6
+ LogStreams:
7
+ [
8
+ {
9
+ level: 'trace',
10
+ streamtype:'process.stdout',
11
+ },
12
+ {
13
+ level: 'trace',
14
+ path: __dirname+'/../tests.log'
15
+ }
16
+ ]
17
+ });
18
+
19
+ var libFable = require('fable').new(tmpFableSettings);
20
+ var libMeadow = require('../source/Meadow.js').new(libFable);
21
+
22
+ var _BookSchemaLocation = '../test/schemas/BookStore-MeadowSchema-Book.json';
23
+
24
+ var newMeadow = function()
25
+ {
26
+ return libMeadow.loadFromPackage(_BookSchemaLocation)
27
+ .setProvider('MeadowEndpoints');
28
+ };
29
+
30
+ var testMeadow = newMeadow();
31
+
32
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
33
+
34
+ /* READ
35
+ var tmpQuery = testMeadow.setProvider('MeadowEndpoints').query.addFilter('IDBook', 1);
36
+ tmpQuery.addFilter('PublicationYear',2008);
37
+ testMeadow.doRead(tmpQuery,
38
+ function(pError, pQuery, pRecord)
39
+ {
40
+ console.log(JSON.stringify(pRecord));
41
+ }
42
+ )
43
+ */
44
+
45
+ /* CREATE
46
+ var testMeadow = newMeadow();
47
+ var tmpQuery = testMeadow.query.clone().setLogLevel(5)
48
+ .addRecord({Title:'Blastoise', Type:'Pokemon'});
49
+
50
+ testMeadow.doCreate(tmpQuery,
51
+ function(pError, pQuery, pQueryRead, pRecord)
52
+ {
53
+ libFable.log.info('Record returned from Create:',pRecord);
54
+ }
55
+ )
56
+ */
57
+
58
+ /* UPDATE
59
+ var testMeadow = newMeadow();
60
+ var tmpQuery = testMeadow.query.setLogLevel(5)
61
+ .addRecord({IDBook:10001, Type:'Novella'});
62
+
63
+ testMeadow.doUpdate(tmpQuery,
64
+ function(pError, pQuery, pQueryRead, pRecord)
65
+ {
66
+ libFable.log.info('Record returned:',pRecord);
67
+ }
68
+ )
69
+ */
70
+
71
+ /* DELETE
72
+ var testMeadow = newMeadow();
73
+ var tmpQuery = testMeadow.query.clone().setLogLevel(5)
74
+ .addFilter('IDBook',10005);
75
+
76
+ testMeadow.doDelete(tmpQuery,
77
+ function(pError, pQuery, pResponse)
78
+ {
79
+ libFable.log.info('Affected record count returned:',pResponse);
80
+ }
81
+ )
82
+ */
83
+
84
+ /* COUNT
85
+ */
86
+
87
+ var testMeadow = newMeadow();
88
+ var tmpQuery = testMeadow.query.clone().addFilter('Type','Pokemon');
89
+ testMeadow.doCount(tmpQuery,
90
+ function(pError, pQuery, pResponse)
91
+ {
92
+ libFable.log.info('Record count returned:', pResponse);
93
+ }
94
+ )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meadow",
3
- "version": "1.0.30",
3
+ "version": "1.1.1",
4
4
  "description": "A data access library.",
5
5
  "main": "source/Meadow.js",
6
6
  "scripts": {
@@ -37,9 +37,10 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "async": "2.4.0",
40
- "fable": "^2.0.1",
41
- "foxhound": "~1.0.31",
40
+ "fable": "~1.0.1",
41
+ "foxhound": "~1.0.36",
42
42
  "is-my-json-valid": "2.16.0",
43
- "underscore": "1.8.3"
43
+ "simple-get": "^4.0.1",
44
+ "underscore": "^1.8.3"
44
45
  }
45
46
  }
@@ -0,0 +1,380 @@
1
+ // ##### Part of the **[retold](https://stevenvelozo.github.io/retold/)** system
2
+ /**
3
+ * @license MIT
4
+ * @author <steven@velozo.com>
5
+ */
6
+ var libSimpleGet = require('simple-get');
7
+ var libUnderscore = require('underscore');
8
+
9
+ var MeadowProvider = function()
10
+ {
11
+ function createNew(pFable)
12
+ {
13
+ // If a valid Fable object isn't passed in, return a constructor
14
+ if (typeof(pFable) !== 'object')
15
+ {
16
+ return {new: createNew};
17
+ }
18
+ var _Fable = pFable;
19
+ var _GlobalLogLevel = 0;
20
+
21
+ var _Dialect = 'MeadowEndpoints';
22
+
23
+ var _Headers = {};
24
+ var _Cookies = [];
25
+
26
+ var _EndpointSettings = (_Fable.settings.hasOwnProperty('MeadowEndpoints')) ? JSON.parse(JSON.stringify(_Fable.settings.MedaowEndpoints)) : (
27
+ {
28
+ ServerProtocol: 'http',
29
+ ServerAddress: '127.0.0.1',
30
+ ServerPort: '8086',
31
+ ServerEndpointPrefix: '1.0/'
32
+ }
33
+ )
34
+
35
+ var buildURL = function(pAddress)
36
+ {
37
+ return `${_EndpointSettings.ServerProtocol}://${_EndpointSettings.ServerAddress}:${_EndpointSettings.ServerPort}/${_EndpointSettings.ServerEndpointPrefix}${pAddress}`;
38
+ };
39
+
40
+ var buildRequestOptions = function(pQuery)
41
+ {
42
+ if (pQuery.logLevel > 0 ||
43
+ _GlobalLogLevel > 0)
44
+ {
45
+ _Fable.log.trace(pQuery.query.body, pQuery.query.records);
46
+ }
47
+
48
+ let tmpURL = buildURL(pQuery.query.body);
49
+
50
+ let tmpRequestOptions = (
51
+ {
52
+ url: tmpURL,
53
+ headers: libUnderscore.extend({cookie: ''}, _Headers)
54
+ });
55
+
56
+ tmpRequestOptions.headers.cookie = _Cookies.join(';');
57
+
58
+
59
+ if (pQuery.logLevel > 0 ||
60
+ _GlobalLogLevel > 0)
61
+ _Fable.log.debug(`Request options built...`,tmpRequestOptions);
62
+
63
+ return tmpRequestOptions;
64
+ };
65
+
66
+ // The Meadow marshaller also passes in the Schema as the third parameter, but this is a blunt function ATM.
67
+ var marshalRecordFromSourceToObject = function(pObject, pRecord)
68
+ {
69
+ for(var tmpColumn in pRecord)
70
+ {
71
+ pObject[tmpColumn] = pRecord[tmpColumn];
72
+ }
73
+ };
74
+
75
+ var Create = function(pQuery, fCallback)
76
+ {
77
+ var tmpResult = pQuery.parameters.result;
78
+ pQuery.setDialect(_Dialect).buildCreateQuery();
79
+
80
+ let tmpRequestOptions = buildRequestOptions(pQuery);
81
+
82
+ // TODO: Should this test for exactly one?
83
+ if (!pQuery.query.records.length > 0)
84
+ {
85
+ tmpResult.error = 'No records passed for proxying to Meadow-Endpoints.';
86
+
87
+ return fCallback();
88
+ }
89
+
90
+ tmpRequestOptions.body = pQuery.query.records[0];
91
+ tmpRequestOptions.json = true;
92
+
93
+ libSimpleGet.post(tmpRequestOptions, (pError, pResponse)=>
94
+ {
95
+ tmpResult.error = pError;
96
+ tmpResult.executed = true;
97
+
98
+ if (pQuery.logLevel > 0 ||
99
+ _GlobalLogLevel > 0)
100
+ _Fable.log.debug(`--> POST request connected`);
101
+
102
+ if (pError)
103
+ {
104
+ return fCallback(tmpResult);
105
+ }
106
+
107
+ let tmpData = '';
108
+
109
+ pResponse.on('data', (pChunk)=>
110
+ {
111
+ if (pQuery.logLevel > 0 ||
112
+ _GlobalLogLevel > 0)
113
+ _Fable.log.debug(`--> POST data chunk size ${pChunk.length}b received`);
114
+ tmpData += pChunk;
115
+ });
116
+
117
+ pResponse.on('end', ()=>
118
+ {
119
+ if (tmpData)
120
+ tmpResult.value = JSON.parse(tmpData);
121
+
122
+ // TODO Because this was proxied, read happens at this layer too. Inefficient -- fixable
123
+ let tmpIdentityColumn = `ID${pQuery.parameters.scope}`;
124
+ if (tmpResult.value.hasOwnProperty(tmpIdentityColumn))
125
+ tmpResult.value = tmpResult.value[tmpIdentityColumn];
126
+
127
+ if (pQuery.logLevel > 0 ||
128
+ _GlobalLogLevel > 0)
129
+ {
130
+ _Fable.log.debug(`==> POST completed data size ${tmpData.length}b received`,tmpResult);
131
+ }
132
+ return fCallback();
133
+ });
134
+ });
135
+ };
136
+
137
+ // This is a synchronous read, good for a few records.
138
+ // TODO: Add a pipe-able read for huge sets
139
+ var Read = function(pQuery, fCallback)
140
+ {
141
+ var tmpResult = pQuery.parameters.result;
142
+ pQuery.setDialect(_Dialect).buildReadQuery();
143
+
144
+ let tmpRequestOptions = buildRequestOptions(pQuery);
145
+
146
+ libSimpleGet.get(tmpRequestOptions, (pError, pResponse)=>
147
+ {
148
+ tmpResult.error = pError;
149
+ tmpResult.executed = true;
150
+
151
+ if (pQuery.logLevel > 0 ||
152
+ _GlobalLogLevel > 0)
153
+ _Fable.log.debug(`--> GET request connected`);
154
+
155
+ if (pError)
156
+ {
157
+ return fCallback(tmpResult);
158
+ }
159
+
160
+ let tmpData = '';
161
+
162
+ pResponse.on('data', (pChunk)=>
163
+ {
164
+ if (pQuery.logLevel > 0 ||
165
+ _GlobalLogLevel > 0)
166
+ _Fable.log.debug(`--> GET data chunk size ${pChunk.length}b received`);
167
+ tmpData += pChunk;
168
+ });
169
+
170
+ pResponse.on('end', ()=>
171
+ {
172
+ if (tmpData)
173
+ tmpResult.value = JSON.parse(tmpData);
174
+
175
+ if (pQuery.query.body.startsWith(`${pQuery.parameters.scope}/`))
176
+ {
177
+ // If this is not a plural read, make the result into an array.
178
+ tmpResult.value = [tmpResult.value];
179
+ }
180
+
181
+ if (pQuery.logLevel > 0 ||
182
+ _GlobalLogLevel > 0)
183
+ {
184
+ _Fable.log.debug(`==> GET completed data size ${tmpData.length}b received`,tmpResult);
185
+ }
186
+ fCallback();
187
+ });
188
+ });
189
+ };
190
+
191
+ var Update = function(pQuery, fCallback)
192
+ {
193
+ var tmpResult = pQuery.parameters.result;
194
+ pQuery.setDialect(_Dialect).buildUpdateQuery();
195
+
196
+ let tmpRequestOptions = buildRequestOptions(pQuery);
197
+
198
+ // TODO: Should this test for exactly one?
199
+ if (!pQuery.query.records.length > 0)
200
+ {
201
+ tmpResult.error = 'No records passed for proxying to Meadow-Endpoints.';
202
+
203
+ return fCallback();
204
+ }
205
+
206
+ tmpRequestOptions.body = pQuery.query.records[0];
207
+ tmpRequestOptions.json = true;
208
+
209
+ libSimpleGet.put(tmpRequestOptions, (pError, pResponse)=>
210
+ {
211
+ tmpResult.error = pError;
212
+ tmpResult.executed = true;
213
+
214
+ if (pQuery.logLevel > 0 ||
215
+ _GlobalLogLevel > 0)
216
+ _Fable.log.debug(`--> PUT request connected`);
217
+
218
+ if (pError)
219
+ {
220
+ return fCallback(tmpResult);
221
+ }
222
+
223
+ let tmpData = '';
224
+
225
+ pResponse.on('data', (pChunk)=>
226
+ {
227
+ if (pQuery.logLevel > 0 ||
228
+ _GlobalLogLevel > 0)
229
+ _Fable.log.debug(`--> PUT data chunk size ${pChunk.length}b received`);
230
+ tmpData += pChunk;
231
+ });
232
+
233
+ pResponse.on('end', ()=>
234
+ {
235
+ if (tmpData)
236
+ tmpResult.value = JSON.parse(tmpData);
237
+
238
+ // TODO Because this was proxied, read happens at this layer too. Inefficient -- fixable
239
+ let tmpIdentityColumn = `ID${pQuery.parameters.scope}`;
240
+ if (tmpResult.value.hasOwnProperty(tmpIdentityColumn))
241
+ tmpResult.value = tmpResult.value[tmpIdentityColumn];
242
+
243
+ if (pQuery.logLevel > 0 ||
244
+ _GlobalLogLevel > 0)
245
+ {
246
+ _Fable.log.debug(`==> PUT completed data size ${tmpData.length}b received`,tmpResult);
247
+ }
248
+ return fCallback();
249
+ });
250
+ });
251
+ }
252
+
253
+ var Delete = function(pQuery, fCallback)
254
+ {
255
+ var tmpResult = pQuery.parameters.result;
256
+ pQuery.setDialect(_Dialect).buildDeleteQuery();
257
+
258
+
259
+ let tmpRequestOptions = buildRequestOptions(pQuery);
260
+
261
+ libSimpleGet.delete(tmpRequestOptions, (pError, pResponse)=>
262
+ {
263
+ tmpResult.error = pError;
264
+ tmpResult.executed = true;
265
+
266
+ if (pQuery.logLevel > 0 ||
267
+ _GlobalLogLevel > 0)
268
+ _Fable.log.debug(`--> DEL request connected`);
269
+
270
+ if (pError)
271
+ {
272
+ return fCallback(tmpResult);
273
+ }
274
+
275
+ let tmpData = '';
276
+
277
+ pResponse.on('data', (pChunk)=>
278
+ {
279
+ if (pQuery.logLevel > 0 ||
280
+ _GlobalLogLevel > 0)
281
+ _Fable.log.debug(`--> DEL data chunk size ${pChunk.length}b received`);
282
+ tmpData += pChunk;
283
+ });
284
+
285
+ pResponse.on('end', ()=>
286
+ {
287
+ if (tmpData)
288
+ tmpResult.value = JSON.parse(tmpData);
289
+
290
+ if (tmpResult.value.hasOwnProperty('Count'))
291
+ tmpResult.value = tmpResult.value.Count;
292
+
293
+
294
+ if (pQuery.logLevel > 0 ||
295
+ _GlobalLogLevel > 0)
296
+ {
297
+ _Fable.log.debug(`==> DEL completed data size ${tmpData.length}b received`,tmpResult);
298
+ }
299
+ fCallback();
300
+ });
301
+ });
302
+ };
303
+
304
+ var Count = function(pQuery, fCallback)
305
+ {
306
+ var tmpResult = pQuery.parameters.result;
307
+ pQuery.setDialect(_Dialect).buildCountQuery();
308
+
309
+ let tmpRequestOptions = buildRequestOptions(pQuery);
310
+
311
+ libSimpleGet.get(tmpRequestOptions, (pError, pResponse)=>
312
+ {
313
+ tmpResult.error = pError;
314
+ tmpResult.executed = true;
315
+
316
+ if (pQuery.logLevel > 0 ||
317
+ _GlobalLogLevel > 0)
318
+ _Fable.log.debug(`--> GET request connected`);
319
+
320
+ if (pError)
321
+ {
322
+ return fCallback(tmpResult);
323
+ }
324
+
325
+ let tmpData = '';
326
+
327
+ pResponse.on('data', (pChunk)=>
328
+ {
329
+ if (pQuery.logLevel > 0 ||
330
+ _GlobalLogLevel > 0)
331
+ _Fable.log.debug(`--> GET data chunk size ${pChunk.length}b received`);
332
+ tmpData += pChunk;
333
+ });
334
+
335
+ pResponse.on('end', ()=>
336
+ {
337
+ if (tmpData)
338
+ tmpResult.value = JSON.parse(tmpData);
339
+
340
+ try
341
+ {
342
+ tmpResult.value = tmpResult.value.Count;
343
+ }
344
+ catch(pErrorGettingRowcount)
345
+ {
346
+ // This is an error state...
347
+ tmpResult.value = -1;
348
+ _Fable.log.warn('Error getting rowcount during count query',{Body:pQuery.query.body, Parameters:pQuery.query.parameters});
349
+ }
350
+
351
+ if (pQuery.logLevel > 0 ||
352
+ _GlobalLogLevel > 0)
353
+ {
354
+ _Fable.log.debug(`==> GET completed data size ${tmpData.length}b received`,tmpResult);
355
+ }
356
+ fCallback();
357
+ });
358
+ });
359
+ };
360
+
361
+ var tmpNewProvider = (
362
+ {
363
+ marshalRecordFromSourceToObject: marshalRecordFromSourceToObject,
364
+
365
+ Create: Create,
366
+ Read: Read,
367
+ Update: Update,
368
+ Delete: Delete,
369
+ Count: Count,
370
+
371
+ new: createNew
372
+ });
373
+
374
+ return tmpNewProvider;
375
+ }
376
+
377
+ return createNew();
378
+ };
379
+
380
+ module.exports = new MeadowProvider();