fable 3.0.45 → 3.0.47

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.
Files changed (49) hide show
  1. package/.browserslistrc +1 -1
  2. package/.config/configstore/update-notifier-npm.json +1 -1
  3. package/.config/vscode-sqltools/runningInfo.json +1 -1
  4. package/Dockerfile_LUXURYCode +4 -5
  5. package/dist/fable.compatible.js +277 -4005
  6. package/dist/fable.compatible.min.js +18 -30
  7. package/dist/fable.compatible.min.js.map +1 -1
  8. package/dist/fable.js +208 -3936
  9. package/dist/fable.min.js +18 -30
  10. package/dist/fable.min.js.map +1 -1
  11. package/gulpfile-config.json +2 -2
  12. package/package.json +7 -7
  13. package/retold-harness/bookstore-serve-api.js +41 -0
  14. package/retold-harness/configuration-bookstore-serve-api.js +30 -0
  15. package/retold-harness/model/manual_scripts/MySQL-Laden-Entry.sh +17 -0
  16. package/retold-harness/model/manual_scripts/my.cnf +4 -0
  17. package/retold-harness/model/sql_create/BookStore-DeleteAndRepopulateTables.sql +194 -0
  18. package/retold-harness/model/sql_create/MySQL-Security.sql +5 -0
  19. package/source/services/Fable-Service-MetaTemplate/MetaTemplate-StringParser.js +281 -0
  20. package/source/services/Fable-Service-MetaTemplate/MetaTemplate-WordTree.js +97 -0
  21. package/source/services/Fable-Service-MetaTemplate.js +20 -6
  22. package/source/services/Fable-Service-Operation-DefaultSettings.js +1 -1
  23. package/source/services/Fable-Service-Operation.js +4 -11
  24. package/test/MetaTemplating_tests.js +241 -29
  25. package/test/RestClient_test.js +1 -1
  26. package/retold-harness/Bookstore-Import-Books.sh +0 -4
  27. package/retold-harness/bookstore-configuration.json +0 -28
  28. package/retold-harness/bookstore-import-books-run.js +0 -9
  29. package/retold-harness/bookstore-import-books.js +0 -214
  30. package/retold-harness/bookstore-serve-meadow-endpoint-apis-IPC.js +0 -137
  31. package/retold-harness/bookstore-serve-meadow-endpoint-apis-run.js +0 -6
  32. package/retold-harness/bookstore-serve-meadow-endpoint-apis.js +0 -129
  33. package/retold-harness/data/books.csv +0 -10001
  34. package/retold-harness/model/json_schema/README.md +0 -1
  35. package/retold-harness/package.json +0 -22
  36. package/retold-harness/test_old/Tests.js +0 -3243
  37. package/retold-harness/test_old/untitled.js +0 -88
  38. /package/retold-harness/{MySQL-Laden-Entry.sh → docker_scripts/MySQL-Laden-Entry.sh} +0 -0
  39. /package/retold-harness/model/{json_schema/BookStore-Extended.json → Model-Extended.json} +0 -0
  40. /package/retold-harness/model/{json_schema/BookStore-PICT.json → Model-PICT.json} +0 -0
  41. /package/retold-harness/model/{json_schema/BookStore.json → Model.json} +0 -0
  42. /package/retold-harness/{bookstore-api-endpoint-exercises.paw → model/bookstore-api-endpoint-exercises.paw} +0 -0
  43. /package/retold-harness/{MySQL-Security.sql → model/manual_scripts/MySQL-Security.sql} +0 -0
  44. /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Author.json → meadow/Model-MeadowSchema-Author.json} +0 -0
  45. /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Book.json → meadow/Model-MeadowSchema-Book.json} +0 -0
  46. /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json → meadow/Model-MeadowSchema-BookAuthorJoin.json} +0 -0
  47. /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-BookPrice.json → meadow/Model-MeadowSchema-BookPrice.json} +0 -0
  48. /package/retold-harness/model/{meadow_schema/BookStore-MeadowSchema-Review.json → meadow/Model-MeadowSchema-Review.json} +0 -0
  49. /package/retold-harness/model/{meadow_schema → meadow}/README.md +0 -0
@@ -6,42 +6,46 @@
6
6
  * @author Steven Velozo <steven@velozo.com>
7
7
  */
8
8
 
9
- var libFable = require('../source/Fable.js');
9
+ const libFable = require('../source/Fable.js');
10
10
 
11
- var Chai = require("chai");
12
- var Expect = Chai.expect;
11
+ const Chai = require("chai");
12
+ const Expect = Chai.expect;
13
13
 
14
14
 
15
- var loadPrecedentModule = () =>
15
+ const loadMetaTemplateModule = () =>
16
16
  {
17
17
  let tmpFable = new libFable();
18
18
  return tmpFable.serviceManager.instantiateServiceProviderWithoutRegistration('MetaTemplate', {});
19
19
  };
20
20
 
21
- var configPrecedent = (pModule) =>
21
+ const configMetaTemplate = (pModule) =>
22
22
  {
23
+
24
+
23
25
  pModule.addPattern('<%', '%>', 'JUNKED_THIS_DATA');
24
26
  // This one gets the count of the inner string...
25
27
  pModule.addPattern('<%#', '%>', (pData)=>{return pData.length});
26
28
  // Replaces the string with the settings object...
27
29
  pModule.addPattern('<%=', '%>', (pData)=>{return JSON.stringify(pModule.settings);});
30
+ // Custom expression hashes
31
+ pModule.addPattern('<*', '*>', (pHash, pData)=>{return `pData is [${pData}] with a hash of [${pHash}]`});
32
+ pModule.addPattern('<^', '^>', (pHash, pData)=>{return `hash of [${pHash}] from pData is ${pData[pHash]}`});
28
33
  // This just escapes out pairs of $
29
34
  pModule.addPattern('$');
35
+ pModule.addPatternAsync('<%Async', '%>',
36
+ (pHash, pData, fCallback)=>
37
+ {
38
+ return fCallback(null, `ASYNC DATA IS [${pHash}]`);
39
+ });
40
+
30
41
  };
31
42
 
32
43
  suite
33
44
  (
34
45
  'Fable MetaTemplating',
35
- function()
46
+ () =>
36
47
  {
37
- var testFable = false;
38
-
39
- setup
40
- (
41
- function()
42
- {
43
- }
44
- );
48
+ setup (() => {});
45
49
 
46
50
  suite
47
51
  (
@@ -53,11 +57,11 @@ suite
53
57
  'No Matches...',
54
58
  (fDone) =>
55
59
  {
56
- var tmpTestString = 'ABC123';
57
- var tmpExpectedResult = tmpTestString;
58
- var testPrecedent = loadPrecedentModule();
59
- configPrecedent(testPrecedent);
60
- var tmpResult = testPrecedent.parseString(tmpTestString);
60
+ let tmpTestString = 'ABC123';
61
+ let tmpExpectedResult = tmpTestString;
62
+ let testMetaTemplate = loadMetaTemplateModule();
63
+ configMetaTemplate(testMetaTemplate);
64
+ let tmpResult = testMetaTemplate.parseString(tmpTestString);
61
65
  Expect(tmpResult).to.equal(tmpExpectedResult);
62
66
  fDone();
63
67
  }
@@ -67,11 +71,11 @@ suite
67
71
  'Count function...',
68
72
  (fDone) =>
69
73
  {
70
- var tmpTestString = 'There are <%#0123456789%> characters in here';
71
- var tmpExpectedResult = 'There are 10 characters in here';
72
- var testPrecedent = loadPrecedentModule();
73
- configPrecedent(testPrecedent);
74
- var tmpResult = testPrecedent.parseString(tmpTestString);
74
+ let tmpTestString = 'There are <%#0123456789%> characters in here';
75
+ let tmpExpectedResult = 'There are 10 characters in here';
76
+ let testMetaTemplate = loadMetaTemplateModule();
77
+ configMetaTemplate(testMetaTemplate);
78
+ let tmpResult = testMetaTemplate.parseString(tmpTestString);
75
79
  Expect(tmpResult).to.equal(tmpExpectedResult);
76
80
  fDone();
77
81
  }
@@ -81,15 +85,223 @@ suite
81
85
  'Multiple terms...',
82
86
  (fDone) =>
83
87
  {
84
- var tmpTestString = 'There are <%#12345%> characters in here and a $comment$ as well. And we <% Some data in here %> right up.';
85
- var tmpExpectedResult = 'There are 5 characters in here and a comment as well. And we JUNKED_THIS_DATA right up.';
86
- var testPrecedent = loadPrecedentModule();
87
- configPrecedent(testPrecedent);
88
- var tmpResult = testPrecedent.parseString(tmpTestString);
88
+ let tmpTestString = 'There are <%#12345%> characters in here and a $comment$ as well. And we <% Some data in here %> right up.';
89
+ let tmpExpectedResult = 'There are 5 characters in here and a comment as well. And we JUNKED_THIS_DATA right up.';
90
+ let testMetaTemplate = loadMetaTemplateModule();
91
+ configMetaTemplate(testMetaTemplate);
92
+ let tmpResult = testMetaTemplate.parseString(tmpTestString);
93
+ Expect(tmpResult).to.equal(tmpExpectedResult);
94
+ fDone();
95
+ }
96
+ );
97
+ test
98
+ (
99
+ 'Basic pattern replacement...',
100
+ (fDone) =>
101
+ {
102
+ let testMetaTemplate = loadMetaTemplateModule();
103
+
104
+ Expect(Object.keys(testMetaTemplate.ParseTree).length).to.equal(0, 'There should be an empty tree on initialization.');
105
+ configMetaTemplate(testMetaTemplate);
106
+ Expect(Object.keys(testMetaTemplate.ParseTree).length).to.equal(2, 'The tree should grow properly.');
107
+
108
+ //console.log(JSON.stringify(testMetaTemplate.tree,null,4));
109
+
110
+ let tmpResult = testMetaTemplate.parseString('');
111
+ Expect(tmpResult.length).to.equal(0, 'Parsing Empty Strings should Work...');
112
+
113
+ fDone();
114
+ }
115
+ );
116
+
117
+ test
118
+ (
119
+ 'Leveraging pData a bit...',
120
+ (fDone) =>
121
+ {
122
+ let tmpTestString = 'The <*SomeValue*> pData up in here and a $comment$ as well.';
123
+ let tmpExpectedResult = 'The pData is [Yikes] with a hash of [SomeValue] pData up in here and a comment as well.';
124
+ let testMetaTemplate = loadMetaTemplateModule();
125
+ configMetaTemplate(testMetaTemplate);
126
+ let tmpResult = testMetaTemplate.parseString(tmpTestString, 'Yikes');
127
+ Expect(tmpResult).to.equal(tmpExpectedResult);
128
+ fDone();
129
+ }
130
+ );
131
+ test
132
+ (
133
+ 'Leveraging pData a using subobjects...',
134
+ (fDone) =>
135
+ {
136
+ let tmpTestString = 'The <^SomeValue^> pData up in here and a $comment$ as well.';
137
+ let tmpExpectedResult = 'The hash of [SomeValue] from pData is AirbornLight pData up in here and a comment as well.';
138
+ let testMetaTemplate = loadMetaTemplateModule();
139
+ configMetaTemplate(testMetaTemplate);
140
+ let tmpResult = testMetaTemplate.parseString(tmpTestString, {SomeValue:'AirbornLight'});
89
141
  Expect(tmpResult).to.equal(tmpExpectedResult);
90
142
  fDone();
91
143
  }
92
144
  );
145
+ test
146
+ (
147
+ 'Async Function',
148
+ (fDone) =>
149
+ {
150
+ let tmpTestString = 'The <^SomeValue^> pData and Async <%AsyncThe Funny String%> up in here and a $comment$ as well.';
151
+ let tmpExpectedResult = 'The hash of [SomeValue] from pData is AirbornLight pData up in here and a comment as well.';
152
+ let testMetaTemplate = loadMetaTemplateModule();
153
+ configMetaTemplate(testMetaTemplate);
154
+ let tmpResult = testMetaTemplate.parseString(tmpTestString, {SomeValue:'AirbornLight'},
155
+ (pError, pValue) =>
156
+ {
157
+ Expect(pValue).to.equal('The hash of [SomeValue] from pData is AirbornLight pData and Async ASYNC DATA IS [The Funny String] up in here and a comment as well.');
158
+ return fDone();
159
+ });
160
+ }
161
+ );
162
+ test
163
+ (
164
+ 'Bad pattern start parameter...',
165
+ (fDone) =>
166
+ {
167
+ let testMetaTemplate = loadMetaTemplateModule();
168
+ configMetaTemplate(testMetaTemplate);
169
+ Expect(testMetaTemplate.addPattern('', '>', 'SHORTEST_MATCH')).to.equal(false);
170
+ fDone();
171
+ }
172
+ );
173
+ test
174
+ (
175
+ 'Bad pattern end parameter...',
176
+ (fDone) =>
177
+ {
178
+ let testMetaTemplate = loadMetaTemplateModule();
179
+ configMetaTemplate(testMetaTemplate);
180
+ Expect(testMetaTemplate.addPattern('<', '', 'SHORTEST_MATCH')).to.equal(false);
181
+ fDone();
182
+ }
183
+ );
184
+ test
185
+ (
186
+ 'Identifier fallback...',
187
+ (fDone) =>
188
+ {
189
+ let testMetaTemplate = loadMetaTemplateModule();
190
+ testMetaTemplate.addPattern('<', '>', 'SHORTEST_MATCH');
191
+ testMetaTemplate.addPattern('<<', '>', 'MEDIUM_MATCH');
192
+ testMetaTemplate.addPattern('<<EXTRALONG', '>', 'EXTRA_LONG_MATCH');
193
+
194
+ let tmpTestStrings = [
195
+ 'Match this <> and this <here> please.',
196
+ 'Match this SHORTEST_MATCH and this SHORTEST_MATCH please.',
197
+
198
+ 'Match this <<> and this <<here> please.',
199
+ 'Match this MEDIUM_MATCH and this MEDIUM_MATCH please.',
200
+
201
+ 'Match this <<EXTRA> and this <<here> please.',
202
+ 'Match this MEDIUM_MATCH and this MEDIUM_MATCH please.',
203
+
204
+ 'Match this <<EXTRALONG> and this <<here> please.',
205
+ 'Match this EXTRA_LONG_MATCH and this MEDIUM_MATCH please.',
206
+
207
+ 'Match this <<<<> and this <here> please.',
208
+ 'Match this MEDIUM_MATCH and this SHORTEST_MATCH please.'
209
+ ];
210
+
211
+ let tmpResult = '';
212
+ // Test every pair in TestStrings
213
+ for (let i = 0; i < tmpTestStrings.length; i+=2)
214
+ {
215
+ tmpResult = testMetaTemplate.parseString(tmpTestStrings[i]);
216
+ Expect(tmpResult).to.equal(tmpTestStrings[i+1]);
217
+ }
218
+ fDone();
219
+ }
220
+ );
221
+ test
222
+ (
223
+ 'Config magic example...',
224
+ (fDone) =>
225
+ {
226
+ // Use case is take a string with the following template expressions and translate them into the value from the environment variable if a default isn't passed in:
227
+ // 'Expressions like ${VariableWithDefault|DefaultValue} have a Default value after the pipe; others like ${VariableWithoutDefault} expressions do not have a Default value after the pipe. but should be processed properly.',
228
+ // 'Expressions like DefaultValue have a Default value after the pipe; others like VariableWithoutDefault expressions do not have a Default value after the pipe. but should be processed properly.',
229
+
230
+ // The usual case is just expressions in the string, but composability is fine.
231
+
232
+ let testMetaTemplate = loadMetaTemplateModule();
233
+
234
+ testMetaTemplate.addPattern('${', '}',
235
+ (pTemplateValue)=>
236
+ {
237
+ let tmpTemplateValue = pTemplateValue.trim();
238
+
239
+ let tmpSeparatorIndex = tmpTemplateValue.indexOf('|');
240
+
241
+ // If there is no pipe, the default value will end up being whatever the variable name is.
242
+ let tmpDefaultValue = tmpTemplateValue.substring(tmpSeparatorIndex+1);
243
+
244
+ let tmpEnvironmentVariableName = (tmpSeparatorIndex > -1) ? tmpTemplateValue.substring(0, tmpSeparatorIndex) : tmpTemplateValue;
245
+
246
+ if (process.env.hasOwnProperty(tmpEnvironmentVariableName))
247
+ {
248
+ return process.env[tmpEnvironmentVariableName];
249
+ }
250
+ else
251
+ {
252
+ return tmpDefaultValue;
253
+ }
254
+ });
255
+
256
+ let tmpTestStrings = [
257
+ 'Expressions like ${VariableWithDefault|DefaultValue} have a Default value after the pipe; others like ${VariableWithoutDefault} expressions do not have a Default value after the pipe. but should be processed properly.',
258
+ 'Expressions like DefaultValue have a Default value after the pipe; others like VariableWithoutDefault expressions do not have a Default value after the pipe. but should be processed properly.',
259
+
260
+ '${PATH}',
261
+ process.env.PATH,
262
+
263
+ 'AAA ${PATH}',
264
+ 'AAA '+process.env.PATH,
265
+
266
+ ' ${PATH} AAA ${PATH}',
267
+ ' '+process.env.PATH+' AAA '+process.env.PATH,
268
+
269
+ 'AAA ${PATH} BBB',
270
+ 'AAA '+process.env.PATH+' BBB',
271
+
272
+ 'AAA ${PATH} } BBB',
273
+ 'AAA '+process.env.PATH+' } BBB',
274
+
275
+ 'AAA ${ ${PATH} BBB',
276
+ // Two start parameters isn't okay ---
277
+ // ...it passes the pattern processor the following (without quotes):
278
+ // " ${PATH"
279
+ // Which is not going to match an environment variable. With the second
280
+ 'AAA ${PATH BBB',
281
+
282
+ '${PATH|Malarky Default Value} ZZZ',
283
+ process.env.PATH+' ZZZ',
284
+
285
+ '${THISISNOTANENVIRONMENTVARIABLE|Real Default Value} ZZZed',
286
+ 'Real Default Value ZZZed',
287
+
288
+ '${ THISISNOTANENVIRONMENTVARIABLETRIMMED|Real Trimmed Default Value } ZZZed',
289
+ 'Real Trimmed Default Value ZZZed',
290
+
291
+ '${PATH} BBB',
292
+ process.env.PATH+' BBB'
293
+ ];
294
+
295
+ let tmpResult = '';
296
+ // Test every pair in TestStrings
297
+ for (let i = 0; i < tmpTestStrings.length; i+=2)
298
+ {
299
+ tmpResult = testMetaTemplate.parseString(tmpTestStrings[i]);
300
+ Expect(tmpResult).to.equal(tmpTestStrings[i+1]);
301
+ }
302
+ fDone();
303
+ }
304
+ );
93
305
  }
94
306
  );
95
307
  }
@@ -43,7 +43,7 @@ suite
43
43
  {
44
44
  Expect(pBody).to.be.an('object');
45
45
  Expect(pBody.hasOwnProperty('Name')).to.equal(true);
46
- Expect(pBody.Name).to.equal('Suzanne Collins');
46
+ Expect(pBody.Name).to.equal('John Green');
47
47
  fTestComplete();
48
48
  });
49
49
  }
@@ -1,4 +0,0 @@
1
- #/bin/bash
2
-
3
- # Eventually this will delete the database too!
4
- node ./bookstore-import-books-run.js
@@ -1,28 +0,0 @@
1
- {
2
- "Product": "MeadowEndpointsTestBookStore",
3
- "ProductVersion": "1.0.0",
4
-
5
- "UUID":
6
- {
7
- "DataCenter": 0,
8
- "Worker": 0
9
- },
10
- "LogStreams":
11
- [
12
- {
13
- "streamtype": "console"
14
- }
15
- ],
16
-
17
- "APIServerPort": 8086,
18
-
19
- "MySQL":
20
- {
21
- "Server": "127.0.0.1",
22
- "Port": 3306,
23
- "User": "root",
24
- "Password": "123456789",
25
- "Database": "bookstore",
26
- "ConnectionPoolLimit": 20
27
- }
28
- }
@@ -1,9 +0,0 @@
1
- let tmpRun = require('./bookstore-import-books.js')(
2
- (pError)=>
3
- {
4
- if (pError)
5
- {
6
- console.log(`ERROR: ${pError}`, pError);
7
- }
8
- process.exit();
9
- });
@@ -1,214 +0,0 @@
1
- /*
2
- Import Books directly from CSV to SQL.
3
-
4
- An example of how to use the Meadow DALs directly.
5
- */
6
- /**
7
- * @author <steven@velozo.com>
8
- */
9
-
10
- // Server Settings
11
- const _Settings = require('./bookstore-configuration.json');
12
- // Fable is logging and settings
13
- const libFable = require('fable');
14
- // Official MySQL Client
15
- const libMySQL = require('mysql2');
16
- // Meadow is the DAL
17
- const libMeadow = require('meadow');
18
-
19
- const libAsync = require('async');
20
-
21
- let _Fable = libFable.new(_Settings);
22
- let _Meadow = libMeadow.new(_Fable);
23
-
24
- _Fable.log.info("Application is starting up...");
25
-
26
- _Fable.log.info("...Creating SQL Connection pools at "+_Fable.settings.MySQL.Server+"...");
27
- // Setup SQL Connection Pool
28
- _Fable.MeadowMySQLConnectionPool = libMySQL.createPool
29
- (
30
- {
31
- connectionLimit: _Fable.settings.MySQL.ConnectionPoolLimit,
32
- host: _Fable.settings.MySQL.Server,
33
- port: _Fable.settings.MySQL.Port,
34
- user: _Fable.settings.MySQL.User,
35
- password: _Fable.settings.MySQL.Password,
36
- database: _Fable.settings.MySQL.Database,
37
- namedPlaceholders: true
38
- }
39
- );
40
-
41
- // Create DAL objects
42
- let _DAL = {};
43
- const _BookStoreModel = require (__dirname+'/model/json_schema/BookStore-Extended.json');
44
- const _BookStoreTableList = Object.keys(_BookStoreModel.Tables);
45
- _Fable.log.info(`...Creating ${_BookStoreTableList.length} DAL entries...`);
46
- for (let i = 0; i < _BookStoreTableList.length; i++)
47
- {
48
- let tmpDALEntityName = _BookStoreTableList[i];
49
- _Fable.log.info(` -> Creating the ${tmpDALEntityName} DAL...`);
50
- _DAL[tmpDALEntityName] = _Meadow.loadFromPackage(__dirname+'/model/meadow_schema/BookStore-MeadowSchema-'+tmpDALEntityName+'.json');
51
- _DAL[tmpDALEntityName].setProvider('MySQL');
52
- _DAL[tmpDALEntityName].setIDUser(99999);
53
- }
54
-
55
- const libPapa = require('papaparse');
56
- const libFS = require('fs');
57
-
58
- const _BookData = libFS.readFileSync(`${__dirname}/data/books.csv`, 'utf8');
59
-
60
- let tmpBookMap = {};
61
- let tmpAuthorMap = {};
62
-
63
- let fImportBooks = (fCallback) =>
64
- {
65
- console.log('Import operation executing...');
66
- let tmpCallback = (typeof(fCallback) == 'function') ? fCallback : ()=>{};
67
-
68
- libPapa.parse(_BookData,
69
- {
70
- delimiter: ",",
71
- header: true,
72
- complete:
73
- (pResults) =>
74
- {
75
- libAsync.waterfall([
76
- (fStageComplete) =>
77
- {
78
- // Enumerate and insert each book
79
- libAsync.eachLimit(pResults.data, 10,
80
- (pBookDataRow, fCallback) =>
81
- {
82
- let tmpRecordToCreate = (
83
- {
84
- Title: pBookDataRow.original_title,
85
- PublicationYear: isNaN(parseInt(pBookDataRow.original_publication_year, 10)) ? 0 : parseInt(pBookDataRow.original_publication_year, 10),
86
- ISBN: pBookDataRow.isbn,
87
- Type: 'Paper',
88
- Genre: 'UNKNOWN',
89
- Language: pBookDataRow.language_code,
90
- ImageURL: pBookDataRow.image_url
91
- });
92
- let tmpQuery = _DAL.Book.query;
93
- //tmpQuery.setLogLevel(5);
94
- tmpQuery.addRecord(tmpRecordToCreate);
95
- _DAL.Book.doCreate(tmpQuery,
96
- (pError, pQuery, pQueryRead, pRecord)=>
97
- {
98
- // Add it to the book map
99
- if (!pError)
100
- {
101
- tmpBookMap[pBookDataRow.id] = pRecord.IDBook;
102
- //_Fable.log.info('Imported book ID '+pRecord.IDBook+' title ['+pRecord.Title+']');
103
- }
104
- fCallback(pError);
105
- });
106
-
107
- },
108
- (pError)=>
109
- {
110
- _Fable.log.info('...Book Import operation complete!');
111
- fStageComplete()
112
- });
113
- },
114
- (fStageComplete) =>
115
- {
116
- // Enumerate and insert each author
117
- libAsync.eachLimit(pResults.data, 10,
118
- (pBookDataRow, fCallback) =>
119
- {
120
- if (!pBookDataRow.hasOwnProperty('authors'))
121
- return fCallback();
122
-
123
- let tmpAuthorsToCreate = pBookDataRow.authors.split(',');
124
-
125
- libAsync.eachLimit(tmpAuthorsToCreate, 1,
126
- (pAuthor, fAuthorInsertCallback)=>
127
- {
128
- if (tmpAuthorMap.hasOwnProperty(pAuthor))
129
- {
130
- return fAuthorInsertCallback();
131
- }
132
- else
133
- {
134
- tmpAuthorMap[pAuthor] = false;
135
- }
136
- let tmpRecordToCreate = (
137
- {
138
- Name: pAuthor
139
- });
140
- let tmpQuery = _DAL.Author.query.addRecord(tmpRecordToCreate);
141
- _DAL.Author.doCreate(tmpQuery,
142
- (pError, pQuery, pQueryRead, pRecord)=>
143
- {
144
- if (!pError)
145
- {
146
- tmpAuthorMap[pRecord.Name] = pRecord.IDAuthor;
147
- //_Fable.log.info('Imported Author ID '+pRecord.IDAuthor+' named ['+pRecord.Name+']');
148
- }
149
- return fAuthorInsertCallback(pError);
150
- });
151
- },
152
- (pError)=>
153
- {
154
- return fCallback(pError);
155
- });
156
- },
157
- (pError)=>
158
- {
159
- _Fable.log.info('...Author Import operation complete!');
160
- fStageComplete();
161
- });
162
- },
163
- (fStageComplete) =>
164
- {
165
- // Create Book->Author joins
166
- libAsync.eachLimit(pResults.data, 10,
167
- (pBookDataRow, fCallback) =>
168
- {
169
- if (!pBookDataRow.hasOwnProperty('authors'))
170
- return fCallback();
171
-
172
- let tmpAuthorJoinsToCreate = pBookDataRow.authors.split(',');
173
-
174
- libAsync.eachLimit(tmpAuthorJoinsToCreate, 1,
175
- (pAuthor, fAuthorJoinInsertCallback)=>
176
- {
177
- let tmpRecordToCreate = (
178
- {
179
- IDBook: tmpBookMap[pBookDataRow.id],
180
- IDAuthor: tmpAuthorMap[pAuthor]
181
- });
182
- let tmpQuery = _DAL.BookAuthorJoin.query.addRecord(tmpRecordToCreate);
183
- _DAL.BookAuthorJoin.doCreate(tmpQuery,
184
- (pError, pQuery, pQueryRead, pRecord)=>
185
- {
186
- if (!pError)
187
- {
188
- //_Fable.log.info(`Joined author ${pAuthor} ID ${pRecord.IDAuthor} to book ID ${pRecord.IDBook}`);
189
- }
190
- return fAuthorJoinInsertCallback(pError);
191
- });
192
- },
193
- (pError)=>
194
- {
195
- return fCallback(pError);
196
- });
197
- },
198
- (pError)=>
199
- {
200
- _Fable.log.info('...Join Import operation complete!');
201
- return fStageComplete(pError);
202
- });
203
- }
204
- ],
205
- (pError)=>
206
- {
207
- _Fable.log.info('Full import operation has completed!')
208
- tmpCallback(pError);
209
- });
210
- }
211
- });
212
- }
213
-
214
- module.exports = fImportBooks;