pure-orm 2.2.0 → 4.0.0-0

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 (135) hide show
  1. package/.eslintrc.json +2 -2
  2. package/README.md +169 -242
  3. package/examples/basic/bo/person.js +4 -3
  4. package/examples/basic/dao/person.js +1 -2
  5. package/examples/basic/db.js +6 -15
  6. package/examples/basic/orm.js +8 -0
  7. package/examples/blog/bo/article.js +5 -2
  8. package/examples/blog/bo/article_tag.js +5 -2
  9. package/examples/blog/bo/article_tags.js +4 -3
  10. package/examples/blog/bo/articles.js +4 -3
  11. package/examples/blog/bo/person.js +4 -2
  12. package/examples/blog/bo/tag.js +4 -2
  13. package/examples/blog/business-objects.js +1 -10
  14. package/examples/blog/orm.js +14 -0
  15. package/examples/order/bo/line-item.js +5 -2
  16. package/examples/order/bo/line-items.js +4 -3
  17. package/examples/order/bo/order.js +5 -2
  18. package/examples/order/bo/orders.js +4 -3
  19. package/examples/order/bo/product-variant.js +5 -2
  20. package/examples/order/bo/product-variants.js +4 -3
  21. package/examples/order/bo/product.js +5 -2
  22. package/examples/order/bo/products.js +4 -3
  23. package/examples/order/bo/utm-source.js +4 -2
  24. package/examples/order/orm.js +20 -0
  25. package/examples/order-more/bo/actual-product-variant.js +5 -2
  26. package/examples/order-more/bo/actual-product-variants.js +4 -3
  27. package/examples/order-more/bo/color.js +5 -2
  28. package/examples/order-more/bo/colors.js +4 -3
  29. package/examples/order-more/bo/customer.js +5 -2
  30. package/examples/order-more/bo/customers.js +4 -3
  31. package/examples/order-more/bo/gender.js +5 -2
  32. package/examples/order-more/bo/genders.js +4 -3
  33. package/examples/order-more/bo/inventory-level.js +5 -2
  34. package/examples/order-more/bo/inventory-levels.js +4 -3
  35. package/examples/order-more/bo/line-item.js +5 -2
  36. package/examples/order-more/bo/line-items.js +4 -3
  37. package/examples/order-more/bo/order.js +5 -2
  38. package/examples/order-more/bo/orders.js +4 -3
  39. package/examples/order-more/bo/parcel-event.js +5 -2
  40. package/examples/order-more/bo/parcel-events.js +4 -3
  41. package/examples/order-more/bo/parcel-line-item.js +5 -2
  42. package/examples/order-more/bo/parcel-line-items.js +4 -3
  43. package/examples/order-more/bo/parcel.js +5 -2
  44. package/examples/order-more/bo/parcels.js +4 -3
  45. package/examples/order-more/bo/physical-address.js +5 -2
  46. package/examples/order-more/bo/physical-addresses.js +4 -3
  47. package/examples/order-more/bo/product-variant-image.js +5 -2
  48. package/examples/order-more/bo/product-variant-images.js +4 -3
  49. package/examples/order-more/bo/product-variant.js +5 -2
  50. package/examples/order-more/bo/product-variants.js +4 -3
  51. package/examples/order-more/bo/product.js +5 -2
  52. package/examples/order-more/bo/products.js +4 -3
  53. package/examples/order-more/bo/refund.js +5 -2
  54. package/examples/order-more/bo/refunds.js +4 -3
  55. package/examples/order-more/bo/shipment-actual-product-variant.js +5 -2
  56. package/examples/order-more/bo/shipment-actual-product-variants.js +4 -3
  57. package/examples/order-more/bo/shipment.js +5 -2
  58. package/examples/order-more/bo/shipments.js +4 -3
  59. package/examples/order-more/bo/size.js +5 -2
  60. package/examples/order-more/bo/sizes.js +4 -3
  61. package/examples/order-more/bo/utm-medium.js +4 -2
  62. package/examples/order-more/bo/utm-source.js +4 -2
  63. package/examples/order-more/orm.js +49 -0
  64. package/package.json +4 -2
  65. package/src/bo.js +393 -0
  66. package/src/{bo/base-bo.spec.js → bo.spec.js} +73 -37
  67. package/src/factory.js +167 -0
  68. package/src/factory.spec.js +11 -0
  69. package/src/index.js +49 -6
  70. package/test-utils/five/bo/line-item.js +5 -2
  71. package/test-utils/five/bo/line-items.js +4 -3
  72. package/test-utils/five/bo/order.js +5 -2
  73. package/test-utils/five/bo/orders.js +4 -3
  74. package/test-utils/five/bo/parcel-event.js +5 -2
  75. package/test-utils/five/bo/parcel-events.js +4 -3
  76. package/test-utils/five/bo/parcel-line-item.js +5 -2
  77. package/test-utils/five/bo/parcel-line-items.js +4 -3
  78. package/test-utils/five/bo/parcel.js +5 -2
  79. package/test-utils/five/bo/parcels.js +4 -3
  80. package/test-utils/five/orm.js +19 -0
  81. package/test-utils/nine/bo/feature-switch.js +5 -2
  82. package/test-utils/nine/bo/feature-switches.js +4 -3
  83. package/test-utils/nine/orm.js +9 -0
  84. package/test-utils/six/bo/customer.js +5 -2
  85. package/test-utils/six/bo/customers.js +4 -3
  86. package/test-utils/six/bo/line-item.js +5 -2
  87. package/test-utils/six/bo/line-items.js +4 -3
  88. package/test-utils/six/bo/order.js +5 -2
  89. package/test-utils/six/bo/orders.js +4 -3
  90. package/test-utils/six/bo/parcel-line-item.js +5 -2
  91. package/test-utils/six/bo/parcel-line-items.js +4 -3
  92. package/test-utils/six/bo/parcel.js +5 -2
  93. package/test-utils/six/bo/parcels.js +4 -3
  94. package/test-utils/six/orm.js +19 -0
  95. package/test-utils/thirteen/bo/audience.js +21 -0
  96. package/test-utils/thirteen/bo/audiences.js +10 -0
  97. package/{examples/basic → test-utils/thirteen}/bo/base.js +0 -0
  98. package/test-utils/thirteen/bo/brand.js +21 -0
  99. package/test-utils/thirteen/bo/brands.js +10 -0
  100. package/test-utils/thirteen/bo/categories.js +13 -0
  101. package/test-utils/thirteen/bo/category.js +21 -0
  102. package/test-utils/thirteen/bo/member.js +21 -0
  103. package/test-utils/thirteen/bo/members.js +10 -0
  104. package/test-utils/thirteen/bo/passion.js +21 -0
  105. package/test-utils/thirteen/bo/passions.js +10 -0
  106. package/test-utils/thirteen/bo/product.js +22 -0
  107. package/test-utils/thirteen/bo/products.js +10 -0
  108. package/test-utils/thirteen/bo/recommendation-audience.js +27 -0
  109. package/test-utils/thirteen/bo/recommendation-audiences.js +10 -0
  110. package/test-utils/thirteen/bo/recommendation.js +33 -0
  111. package/test-utils/thirteen/bo/recommendations.js +10 -0
  112. package/test-utils/thirteen/orm.js +25 -0
  113. package/test-utils/thirteen/results.json +74 -0
  114. package/test-utils/twelve/bo/member.js +5 -2
  115. package/test-utils/twelve/bo/members.js +4 -3
  116. package/test-utils/twelve/bo/prompt.js +5 -2
  117. package/test-utils/twelve/bo/prompts.js +4 -3
  118. package/test-utils/twelve/orm.js +10 -0
  119. package/examples/basic/business-objects.js +0 -9
  120. package/examples/basic/dao/base.js +0 -9
  121. package/examples/blog/bo/base.js +0 -5
  122. package/examples/order/bo/base.js +0 -5
  123. package/examples/order/business-objects.js +0 -11
  124. package/examples/order-more/bo/base.js +0 -5
  125. package/examples/order-more/business-objects.js +0 -26
  126. package/src/bo/base-bo-collection.js +0 -15
  127. package/src/bo/base-bo.js +0 -379
  128. package/src/dao/base-dao.js +0 -146
  129. package/src/dao/base-dao.spec.js +0 -6
  130. package/src/util/helpers.js +0 -28
  131. package/src/util/helpers.spec.js +0 -6
  132. package/test-utils/five/business-objects.js +0 -11
  133. package/test-utils/nine/business-objects.js +0 -7
  134. package/test-utils/six/business-objects.js +0 -11
  135. package/test-utils/twelve/business-objects.js +0 -8
@@ -1,11 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/utm-source'),
5
- require('./bo/order'),
6
- require('./bo/line-item'),
7
- require('./bo/product-variant'),
8
- require('./bo/product')
9
- ];
10
-
11
- module.exports = getBusinessObjects;
@@ -1,5 +0,0 @@
1
- const { createBaseBO } = require('pure-orm');
2
- const getBusinessObjects = require('../business-objects');
3
-
4
- const constructor = createBaseBO({ getBusinessObjects });
5
- module.exports = constructor;
@@ -1,26 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/inventory-level'),
5
- require('./bo/actual-product-variant'),
6
- require('./bo/product-variant'),
7
- require('./bo/product-variant-image'),
8
- require('./bo/product'),
9
- require('./bo/size'),
10
- require('./bo/color'),
11
- require('./bo/gender'),
12
- require('./bo/shipment'),
13
- require('./bo/shipment-actual-product-variant'),
14
- require('./bo/refund'),
15
- require('./bo/order'),
16
- require('./bo/line-item'),
17
- require('./bo/customer'),
18
- require('./bo/physical-address'),
19
- require('./bo/utm-source'),
20
- require('./bo/utm-medium'),
21
- require('./bo/parcel-line-item'),
22
- require('./bo/parcel'),
23
- require('./bo/parcel-event')
24
- ];
25
-
26
- module.exports = getBusinessObjects;
@@ -1,15 +0,0 @@
1
- class BaseBoCollection {
2
- constructor(props = {}) {
3
- this.models = props.models || [];
4
- }
5
-
6
- static get displayName() {
7
- return `${this.Bo.displayName}s`;
8
- }
9
-
10
- filter(predicate) {
11
- return new this.constructor({ models: this.models.filter(predicate) });
12
- }
13
- }
14
-
15
- module.exports = BaseBoCollection;
package/src/bo/base-bo.js DELETED
@@ -1,379 +0,0 @@
1
- const camelCase = require('camelcase');
2
-
3
- module.exports = ({ getBusinessObjects }) =>
4
- class Base {
5
- constructor(props) {
6
- Object.assign(this, props);
7
- }
8
-
9
- static primaryKey() {
10
- const primaryKey = this.sqlColumnsData.filter(x => x.primaryKey);
11
- return primaryKey.length > 0 ? primaryKey : ['id'];
12
- }
13
-
14
- static get columns() {
15
- return this.sqlColumnsData.map(
16
- x => x.property || camelCase(x.column || x)
17
- );
18
- }
19
-
20
- static get sqlColumns() {
21
- return this.sqlColumnsData.map(x => x.column || x);
22
- }
23
-
24
- static get references() {
25
- return this.sqlColumnsData
26
- .filter(x => x.references)
27
- .reduce(
28
- (accum, item) =>
29
- Object.assign({}, accum, {
30
- [item.property || camelCase(item.column || item)]: item.references
31
- }),
32
- {}
33
- );
34
- }
35
-
36
- static get displayName() {
37
- return camelCase(this.tableName);
38
- }
39
-
40
- static getPrefixedColumnNames() {
41
- return this.sqlColumns.map(col => `${this.tableName}#${col}`);
42
- }
43
-
44
- static getSQLSelectClause() {
45
- return this.getPrefixedColumnNames()
46
- .map(
47
- (prefixed, index) =>
48
- `"${this.tableName}".${this.sqlColumns[index]} as "${prefixed}"`
49
- )
50
- .join(', ');
51
- }
52
-
53
- /*
54
- * Make objects (based on special table#column names) from flat database
55
- * return value.
56
- */
57
- static objectifyDatabaseResult(result) {
58
- return Object.keys(result).reduce((obj, text) => {
59
- const tableName =
60
- text.indexOf('#') > -1 ? text.split('#')[0] : this.tableName;
61
- const column = text.indexOf('#') > -1 ? text.split('#')[1] : text;
62
- obj[tableName] = obj[tableName] || {};
63
- obj[tableName][column] = result[text];
64
- return obj;
65
- }, {});
66
- }
67
-
68
- static mapToBos(objectified) {
69
- return Object.keys(objectified).map(tableName => {
70
- const Bo = getBusinessObjects().find(bo => bo.tableName === tableName);
71
- if (!Bo) {
72
- throw Error(`No business object with table name "${tableName}"`);
73
- }
74
- const propified = Object.keys(objectified[tableName]).reduce(
75
- (obj, column) => {
76
- let propertyName = Bo.columns[Bo.sqlColumns.indexOf(column)];
77
- if (!propertyName) {
78
- if (column.startsWith('meta_')) {
79
- propertyName = camelCase(column);
80
- } else {
81
- throw Error(
82
- `No property name for "${column}" in business object "${
83
- Bo.displayName
84
- }". Non-spec'd columns must begin with "meta_".`
85
- );
86
- }
87
- }
88
- obj[propertyName] = objectified[tableName][column];
89
- return obj;
90
- },
91
- {}
92
- );
93
- return new Bo(propified);
94
- });
95
- }
96
-
97
- /*
98
- * Clump array of flat objects into groups based on id of root
99
- * In:
100
- * [
101
- * [Article {id: 32}, ArticleTag {id: 54}]
102
- * [Article {id: 32}, ArticleTag {id: 55}]
103
- * [Article {id: 33}, ArticleTag {id: 56}]
104
- * ]
105
- * Out:
106
- * [
107
- * [
108
- * [Article {id: 32}, ArticleTag {id: 54}]
109
- * [Article {id: 32}, ArticleTag {id: 55}]
110
- * ]
111
- * [
112
- * [Article {id: 33}, ArticleTag {id: 56}]
113
- * ]
114
- * ]
115
- */
116
- static clumpIntoGroups(processed) {
117
- const clumps = processed.reduce((accum, item) => {
118
- const id = this.primaryKey()
119
- .map(key => item.find(x => x.constructor === this)[key])
120
- .join('@');
121
- if (accum.has(id)) {
122
- accum.set(id, [...accum.get(id), item]);
123
- } else {
124
- accum.set(id, [item]);
125
- }
126
- return accum;
127
- }, new Map());
128
- return [...clumps.values()];
129
- }
130
-
131
- /*
132
- * In:
133
- * [
134
- * [Article {id: 32}, ArticleTag {id: 54}]
135
- * [Article {id: 32}, ArticleTag {id: 55}]
136
- * ]
137
- * Out:
138
- * Article {id: 32, ArticleTags articleTags: [ArticleTag {id: 54}, ArticleTag {id: 55}]
139
- */
140
- static nestClump(clump) {
141
- clump = clump.map(x => Object.values(x)); // clump wasn't actually what I have documented
142
- const root = clump[0][0];
143
- clump = clump.map(row => row.filter((item, index) => index !== 0));
144
- const built = { [root.constructor.displayName]: root };
145
-
146
- let nodes = [root];
147
-
148
- // Wowzer is this both CPU and Memory inefficient
149
- clump.forEach(array => {
150
- array.forEach(_bo => {
151
- const nodeAlreadySeen = nodes.find(
152
- x =>
153
- x.constructor.name === _bo.constructor.name &&
154
- x.getId() === _bo.getId()
155
- );
156
- const bo = nodeAlreadySeen || _bo;
157
- const isNodeAlreadySeen = !!nodeAlreadySeen;
158
- const nodePointingToIt = nodes.find(node => {
159
- const indexes = Object.values(node.constructor.references)
160
- .map((x, i) => (x === bo.constructor ? i : null))
161
- .filter(x => x != null);
162
- if (!indexes.length) {
163
- return false;
164
- }
165
- for (const index of indexes) {
166
- const property = Object.keys(node.constructor.references)[index];
167
- if (node[property] === bo.id) {
168
- return true;
169
- }
170
- }
171
- return false;
172
- });
173
- // For first obj type which is has an instance in nodes array,
174
- // get its index in nodes array
175
- const indexOfOldestParent = array.reduce((answer, obj) => {
176
- if (answer != null) {
177
- return answer;
178
- }
179
- const index = nodes.findIndex(
180
- n => n.constructor === obj.constructor
181
- );
182
- if (index !== -1) {
183
- return index;
184
- }
185
- return null;
186
- }, null);
187
- const parentHeirarchy = [
188
- ...nodes.slice(0, indexOfOldestParent + 1).reverse(),
189
- root
190
- ];
191
- const nodeItPointsTo = parentHeirarchy.find(parent => {
192
- const index = Object.values(bo.constructor.references).indexOf(
193
- parent.constructor
194
- );
195
- if (index === -1) {
196
- return false;
197
- }
198
- const property = Object.keys(bo.constructor.references)[index];
199
- return bo[property] === parent.id;
200
- });
201
- if (isNodeAlreadySeen) {
202
- if (nodeItPointsTo && !nodePointingToIt) {
203
- nodes = [bo, ...nodes];
204
- return;
205
- }
206
- // If the nodePointingToIt (eg, parcel_event) is part of an
207
- // existing collection on this node (eg, parcel) which is a
208
- // nodeAlreadySeen, early return so we don't create it (parcel) on
209
- // the nodePointingToIt (parcel_event), since it (parcel) has been
210
- // shown to be the parent (of parcel_events).
211
- const ec = bo[nodePointingToIt.BoCollection.displayName];
212
- if (ec && ec.models.find(m => m === nodePointingToIt)) {
213
- nodes = [bo, ...nodes];
214
- return;
215
- }
216
- }
217
- if (nodePointingToIt) {
218
- nodePointingToIt[bo.constructor.displayName] = bo;
219
- } else if (nodeItPointsTo) {
220
- let collection = nodeItPointsTo[bo.BoCollection.displayName];
221
- if (collection) {
222
- collection.models.push(bo);
223
- } else {
224
- nodeItPointsTo[bo.BoCollection.displayName] = new bo.BoCollection(
225
- { models: [bo] }
226
- );
227
- }
228
- } else {
229
- if (!bo.getId()) {
230
- // If the join is fruitless; todo: add a test for this path
231
- return;
232
- }
233
- throw Error(
234
- `Could not find how this BO fits: ${JSON.stringify(bo)}`
235
- );
236
- }
237
- nodes = [bo, ...nodes];
238
- });
239
- });
240
-
241
- return built;
242
- }
243
-
244
- static createFromDatabase(_result) {
245
- const result = Array.isArray(_result) ? _result : [_result];
246
- const objectified = result.map(this.objectifyDatabaseResult.bind(this));
247
- const boified = objectified.map(this.mapToBos.bind(this));
248
- const clumps = this.clumpIntoGroups(boified);
249
- const nested = clumps.map(this.nestClump.bind(this));
250
- const models = nested.map(n => Object.values(n)[0]);
251
- return new new this().BoCollection({ models });
252
- }
253
-
254
- static createOneFromDatabase(_result) {
255
- const collection = this.createFromDatabase(_result);
256
- if (collection.models.length > 1) {
257
- throw Error('Got more than one.');
258
- } else if (collection.models.length === 0) {
259
- throw Error('Did not get one.');
260
- }
261
- return collection.models[0];
262
- }
263
-
264
- static createOneOrNoneFromDatabase(_result) {
265
- if (!_result) {
266
- return _result;
267
- }
268
- const collection = this.createFromDatabase(_result);
269
- if (collection.models.length > 1) {
270
- throw Error('Got more than one.');
271
- }
272
- return collection.models[0];
273
- }
274
-
275
- static createManyFromDatabase(_result) {
276
- const collection = this.createFromDatabase(_result);
277
- if (collection.models.length === 0) {
278
- throw Error('Did not get at least one.');
279
- }
280
- return collection;
281
- }
282
-
283
- getSqlInsertParts() {
284
- const columns = this.constructor.sqlColumns
285
- .filter(
286
- (column, index) => this[this.constructor.columns[index]] != null
287
- )
288
- .map(col => `"${col}"`)
289
- .join(', ');
290
- const values = this.constructor.columns
291
- .map(column => this[column])
292
- .filter(value => value != null);
293
- const valuesVar = values.map((value, index) => `$${index + 1}`);
294
- return { columns, values, valuesVar };
295
- }
296
-
297
- getSqlUpdateParts(on = 'id') {
298
- const clauseArray = this.constructor.sqlColumns
299
- .filter(
300
- (sqlColumn, index) => this[this.constructor.columns[index]] != null
301
- )
302
- .map((sqlColumn, index) => `"${sqlColumn}" = $${index + 1}`);
303
- const clause = clauseArray.join(', ');
304
- const idVar = `$${clauseArray.length + 1}`;
305
- const _values = this.constructor.columns
306
- .map(column => this[column])
307
- .filter(value => value != null);
308
- const values = [..._values, this[on]];
309
- return { clause, idVar, values };
310
- }
311
-
312
- getMatchingParts() {
313
- const whereClause = this.constructor.columns
314
- .map((col, index) =>
315
- this[col] != null
316
- ? `"${this.constructor.tableName}"."${
317
- this.constructor.sqlColumns[index]
318
- }"`
319
- : null
320
- )
321
- .filter(x => x != null)
322
- .map((x, i) => `${x} = $${i + 1}`)
323
- .join(' AND ');
324
- const values = this.constructor.columns
325
- .map(col => (this[col] != null ? this[col] : null))
326
- .filter(x => x != null);
327
- return { whereClause, values };
328
- }
329
-
330
- // This one returns an object, which allows it to be more versatile.
331
- // Todo: make this one even better and use it instead of the one above.
332
- getMatchingPartsObject() {
333
- const whereClause = this.constructor.columns
334
- .map((col, index) =>
335
- this[col] != null
336
- ? `"${this.constructor.tableName}"."${
337
- this.constructor.sqlColumns[index]
338
- }"`
339
- : null
340
- )
341
- .filter(x => x != null)
342
- .map((x, i) => `${x} = $(${i + 1})`)
343
- .join(' AND ');
344
- const values = this.constructor.columns
345
- .map(col => (this[col] != null ? this[col] : null))
346
- .filter(x => x != null)
347
- .reduce(
348
- (accum, val, index) => Object.assign({}, accum, { [index + 1]: val }),
349
- {}
350
- );
351
- return { whereClause, values };
352
- }
353
-
354
- getNewWith(sqlColumns, values) {
355
- const Constructor = this.constructor;
356
- const boKeys = sqlColumns.map(
357
- key => Constructor.columns[Constructor.sqlColumns.indexOf(key)]
358
- );
359
- const boData = boKeys.reduce((data, key, index) => {
360
- data[key] = values[index];
361
- return data;
362
- }, {});
363
- return new Constructor(boData);
364
- }
365
-
366
- getValueBySqlColumn(sqlColumn) {
367
- return this[
368
- this.constructor.columns[this.constructor.sqlColumns.indexOf(sqlColumn)]
369
- ];
370
- }
371
-
372
- // Returns unique identifier of bo (the values of the primary keys)
373
- getId() {
374
- return this.constructor
375
- .primaryKey()
376
- .map(key => this[key])
377
- .join('');
378
- }
379
- };
@@ -1,146 +0,0 @@
1
- /*
2
- * A wrapper function returning the base data access abstraction.
3
- */
4
- module.exports = ({ db: closureDB, logError: closureLogError }) =>
5
- class BaseDAO {
6
- constructor({ db, logError } = {}) {
7
- this.db = db || closureDB;
8
- this.logError = logError || closureLogError;
9
- this.ensureExists = this.getOrCreate; // alias
10
- this.manyOrNone = this.any; // alias
11
- this.errorHandler = this.errorHandler.bind(this);
12
- }
13
-
14
- /* Nice abstractions over this.db ---------------------------------------*/
15
- /* ----------------------------------------------------------------------*/
16
-
17
- one(query, values, errorHandler = this.errorHandler) {
18
- return this.db
19
- .many(query, values)
20
- .then(rows => this.Bo.createOneFromDatabase(rows))
21
- .catch(errorHandler);
22
- }
23
-
24
- oneOrNone(query, values, errorHandler = this.errorHandler) {
25
- return this.db
26
- .any(query, values)
27
- .then(rows => this.Bo.createOneOrNoneFromDatabase(rows))
28
- .catch(errorHandler);
29
- }
30
-
31
- many(query, values, errorHandler = this.errorHandler) {
32
- return this.db
33
- .any(query, values)
34
- .then(rows => this.Bo.createManyFromDatabase(rows))
35
- .catch(errorHandler);
36
- }
37
-
38
- any(query, values, errorHandler = this.errorHandler) {
39
- return this.db
40
- .any(query, values)
41
- .then(rows => this.Bo.createFromDatabase(rows))
42
- .catch(errorHandler);
43
- }
44
-
45
- none(query, values, errorHandler = this.errorHandler) {
46
- return this.db
47
- .none(query, values)
48
- .then(() => null)
49
- .catch(errorHandler);
50
- }
51
-
52
- /* Piecemeal endings if using this.db directly --------------------------*/
53
- /* ----------------------------------------------------------------------*/
54
-
55
- errorHandler(err) {
56
- if (!err.name === 'QueryResultError') {
57
- this.logError(err);
58
- }
59
- throw err;
60
- }
61
-
62
- /* Built-in basic DAO methods -------------------------------------------*/
63
- /* ----------------------------------------------------------------------*/
64
-
65
- // Standard create
66
- create(bo) {
67
- const { columns, values, valuesVar } = bo.getSqlInsertParts();
68
- const query = `
69
- INSERT INTO "${bo.constructor.tableName}" ( ${columns} )
70
- VALUES ( ${valuesVar} )
71
- RETURNING ${bo.constructor.getSQLSelectClause()};
72
- `;
73
- return this.one(query, values);
74
- }
75
-
76
- // Standard update
77
- update(bo, { on = 'id' } = {}) {
78
- const { clause, idVar, values } = bo.getSqlUpdateParts(on);
79
- const query = `
80
- UPDATE "${bo.constructor.tableName}"
81
- SET ${clause}
82
- WHERE "${bo.constructor.tableName}".${on} = ${idVar}
83
- RETURNING ${bo.constructor.getSQLSelectClause()};
84
- `;
85
- return this.one(query, values);
86
- }
87
-
88
- // Standard delete
89
- delete(bo) {
90
- const id = bo.id;
91
- const query = `
92
- DELETE FROM "${bo.constructor.tableName}"
93
- WHERE "${bo.constructor.tableName}".id = ${id}
94
- `;
95
- return this.none(query);
96
- }
97
-
98
- deleteMatching(bo) {
99
- const { whereClause, values } = bo.getMatchingParts();
100
- const query = `
101
- DELETE FROM "${bo.constructor.tableName}"
102
- WHERE ${whereClause};
103
- `;
104
- return this.none(query, values);
105
- }
106
-
107
- getMatching(bo) {
108
- const { whereClause, values } = bo.getMatchingParts();
109
- const query = `
110
- SELECT ${bo.constructor.getSQLSelectClause()}
111
- FROM "${bo.constructor.tableName}"
112
- WHERE ${whereClause};
113
- `;
114
- return this.one(query, values);
115
- }
116
-
117
- getOneOrNoneMatching(bo) {
118
- const { whereClause, values } = bo.getMatchingParts();
119
- const query = `
120
- SELECT ${bo.constructor.getSQLSelectClause()}
121
- FROM "${bo.constructor.tableName}"
122
- WHERE ${whereClause};
123
- `;
124
- return this.oneOrNone(query, values);
125
- }
126
-
127
- getAnyMatching(bo) {
128
- const { whereClause, values } = bo.getMatchingParts();
129
- const query = `
130
- SELECT ${bo.constructor.getSQLSelectClause()}
131
- FROM "${bo.constructor.tableName}"
132
- WHERE ${whereClause};
133
- `;
134
- return this.any(query, values);
135
- }
136
-
137
- getAllMatching(bo) {
138
- const { whereClause, values } = bo.getMatchingParts();
139
- const query = `
140
- SELECT ${bo.constructor.getSQLSelectClause()}
141
- FROM "${bo.constructor.tableName}"
142
- WHERE ${whereClause};
143
- `;
144
- return this.many(query, values);
145
- }
146
- };
@@ -1,6 +0,0 @@
1
- const createBaseDAO = require('./base-dao');
2
-
3
- test('TODO: Add DAO tests', () => {
4
- void createBaseDAO;
5
- expect(1).toBe(1);
6
- });
@@ -1,28 +0,0 @@
1
- // Previously keys and values were parsed from the error string, but the
2
- // presence of commas in the values section messed it up. So now, it
3
- // returns just gets the keys from the error message and gets the values
4
- // from the business object (previously did not accept a business object).
5
- const getColumnsValuesFromInsertErrorOLD = (error = '') => {
6
- let keys, values;
7
- try {
8
- const results = /.*Key.*\((.*)\)=.*\((.*)\).*/g.exec(error);
9
- const [, keyString, valueString] = results;
10
- keys = keyString.split(', ');
11
- values = valueString.split(', ');
12
- } catch (_err) {}
13
- return [keys, values];
14
- };
15
- void getColumnsValuesFromInsertErrorOLD;
16
-
17
- const getColumnsValuesFromInsertError = (error = '', bo) => {
18
- let keys, values;
19
- try {
20
- const results = /.*Key.*\((.*)\)=.*\((.*)\).*/g.exec(error);
21
- const [, keyString] = results;
22
- keys = keyString.split(', ');
23
- values = keys.map(key => bo.getValueBySqlColumn(key));
24
- } catch (_err) {}
25
- return [keys, values];
26
- };
27
-
28
- module.exports.getColumnsValuesFromInsertError = getColumnsValuesFromInsertError;
@@ -1,6 +0,0 @@
1
- const { getColumnsValuesFromInsertError } = require('./helpers');
2
-
3
- test('TODO: Add helpers tests', () => {
4
- void getColumnsValuesFromInsertError;
5
- expect(1).toBe(1);
6
- });
@@ -1,11 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/order'),
5
- require('./bo/line-item'),
6
- require('./bo/parcel-line-item'),
7
- require('./bo/parcel'),
8
- require('./bo/parcel-event')
9
- ];
10
-
11
- module.exports = getBusinessObjects;
@@ -1,7 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/feature-switch')
5
- ];
6
-
7
- module.exports = getBusinessObjects;
@@ -1,11 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/parcel'),
5
- require('./bo/parcel-line-item'),
6
- require('./bo/line-item'),
7
- require('./bo/order'),
8
- require('./bo/customer')
9
- ];
10
-
11
- module.exports = getBusinessObjects;
@@ -1,8 +0,0 @@
1
- /* eslint-disable global-require */
2
- const getBusinessObjects = () => [
3
- // These need to be imported here to get around circular dependencies
4
- require('./bo/prompt'),
5
- require('./bo/member')
6
- ];
7
-
8
- module.exports = getBusinessObjects;