pure-orm 4.0.2 → 4.1.4

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 (209) hide show
  1. package/.benchmarks/bench-core-baseline.json +303 -0
  2. package/.eslintrc.json +20 -10
  3. package/README.md +0 -7
  4. package/coverage/clover.xml +1493 -1232
  5. package/coverage/coverage-final.json +103 -103
  6. package/coverage/lcov-report/dist/src/core.js.html +590 -383
  7. package/coverage/lcov-report/dist/src/driver-integrations/index.html +20 -20
  8. package/coverage/lcov-report/dist/src/driver-integrations/pgp.js.html +52 -52
  9. package/coverage/lcov-report/dist/src/index.html +28 -28
  10. package/coverage/lcov-report/dist/src/index.js.html +2 -2
  11. package/coverage/lcov-report/dist/src/orm.js.html +392 -209
  12. package/coverage/lcov-report/dist/test-utils/blog/entities.js.html +1 -1
  13. package/coverage/lcov-report/dist/test-utils/blog/index.html +1 -1
  14. package/coverage/lcov-report/dist/test-utils/blog/models/article.js.html +15 -15
  15. package/coverage/lcov-report/dist/test-utils/blog/models/article_tag.js.html +2 -2
  16. package/coverage/lcov-report/dist/test-utils/blog/models/index.html +1 -1
  17. package/coverage/lcov-report/dist/test-utils/blog/models/person.js.html +13 -13
  18. package/coverage/lcov-report/dist/test-utils/blog/models/tag.js.html +1 -1
  19. package/coverage/lcov-report/dist/test-utils/five/entities.js.html +1 -1
  20. package/coverage/lcov-report/dist/test-utils/five/index.html +1 -1
  21. package/coverage/lcov-report/dist/test-utils/five/models/index.html +1 -1
  22. package/coverage/lcov-report/dist/test-utils/five/models/line-item.js.html +4 -4
  23. package/coverage/lcov-report/dist/test-utils/five/models/order.js.html +3 -3
  24. package/coverage/lcov-report/dist/test-utils/five/models/parcel-event.js.html +6 -6
  25. package/coverage/lcov-report/dist/test-utils/five/models/parcel-line-item.js.html +7 -7
  26. package/coverage/lcov-report/dist/test-utils/five/models/parcel.js.html +2 -2
  27. package/coverage/lcov-report/dist/test-utils/fourteen/entities.js.html +1 -1
  28. package/coverage/lcov-report/dist/test-utils/fourteen/index.html +1 -1
  29. package/coverage/lcov-report/dist/test-utils/fourteen/models/customer.js.html +1 -1
  30. package/coverage/lcov-report/dist/test-utils/fourteen/models/index.html +1 -1
  31. package/coverage/lcov-report/dist/test-utils/fourteen/models/person.js.html +1 -1
  32. package/coverage/lcov-report/dist/test-utils/nine/entities.js.html +1 -1
  33. package/coverage/lcov-report/dist/test-utils/nine/index.html +1 -1
  34. package/coverage/lcov-report/dist/test-utils/nine/models/feature-switch.js.html +6 -6
  35. package/coverage/lcov-report/dist/test-utils/nine/models/index.html +1 -1
  36. package/coverage/lcov-report/dist/test-utils/order/entities.js.html +9 -9
  37. package/coverage/lcov-report/dist/test-utils/order/index.html +1 -1
  38. package/coverage/lcov-report/dist/test-utils/order/models/index.html +14 -14
  39. package/coverage/lcov-report/dist/test-utils/order/models/line-item.js.html +11 -11
  40. package/coverage/lcov-report/dist/test-utils/order/models/order.js.html +41 -41
  41. package/coverage/lcov-report/dist/test-utils/order/models/product-variant.js.html +18 -18
  42. package/coverage/lcov-report/dist/test-utils/order/models/product.js.html +17 -17
  43. package/coverage/lcov-report/dist/test-utils/order/models/utm-source.js.html +12 -12
  44. package/coverage/lcov-report/dist/test-utils/order-more/entities.js.html +1 -1
  45. package/coverage/lcov-report/dist/test-utils/order-more/index.html +1 -1
  46. package/coverage/lcov-report/dist/test-utils/order-more/models/actual-product-variant.js.html +3 -3
  47. package/coverage/lcov-report/dist/test-utils/order-more/models/color.js.html +6 -6
  48. package/coverage/lcov-report/dist/test-utils/order-more/models/customer.js.html +3 -3
  49. package/coverage/lcov-report/dist/test-utils/order-more/models/gender.js.html +4 -4
  50. package/coverage/lcov-report/dist/test-utils/order-more/models/index.html +23 -23
  51. package/coverage/lcov-report/dist/test-utils/order-more/models/inventory-level.js.html +11 -11
  52. package/coverage/lcov-report/dist/test-utils/order-more/models/line-item.js.html +15 -15
  53. package/coverage/lcov-report/dist/test-utils/order-more/models/order.js.html +39 -39
  54. package/coverage/lcov-report/dist/test-utils/order-more/models/parcel-event.js.html +6 -6
  55. package/coverage/lcov-report/dist/test-utils/order-more/models/parcel-line-item.js.html +7 -7
  56. package/coverage/lcov-report/dist/test-utils/order-more/models/parcel.js.html +2 -2
  57. package/coverage/lcov-report/dist/test-utils/order-more/models/physical-address.js.html +12 -12
  58. package/coverage/lcov-report/dist/test-utils/order-more/models/product-variant-image.js.html +7 -7
  59. package/coverage/lcov-report/dist/test-utils/order-more/models/product-variant.js.html +22 -22
  60. package/coverage/lcov-report/dist/test-utils/order-more/models/product.js.html +11 -11
  61. package/coverage/lcov-report/dist/test-utils/order-more/models/refund.js.html +11 -11
  62. package/coverage/lcov-report/dist/test-utils/order-more/models/shipment-actual-product-variant.js.html +9 -9
  63. package/coverage/lcov-report/dist/test-utils/order-more/models/shipment.js.html +4 -4
  64. package/coverage/lcov-report/dist/test-utils/order-more/models/size.js.html +4 -4
  65. package/coverage/lcov-report/dist/test-utils/order-more/models/utm-medium.js.html +15 -15
  66. package/coverage/lcov-report/dist/test-utils/order-more/models/utm-source.js.html +17 -17
  67. package/coverage/lcov-report/dist/test-utils/six/entities.js.html +1 -1
  68. package/coverage/lcov-report/dist/test-utils/six/index.html +1 -1
  69. package/coverage/lcov-report/dist/test-utils/six/models/customer.js.html +3 -3
  70. package/coverage/lcov-report/dist/test-utils/six/models/index.html +21 -21
  71. package/coverage/lcov-report/dist/test-utils/six/models/line-item.js.html +10 -10
  72. package/coverage/lcov-report/dist/test-utils/six/models/order.js.html +13 -13
  73. package/coverage/lcov-report/dist/test-utils/six/models/parcel-line-item.js.html +2 -2
  74. package/coverage/lcov-report/dist/test-utils/six/models/parcel.js.html +2 -2
  75. package/coverage/lcov-report/dist/test-utils/thirteen/entities.js.html +1 -1
  76. package/coverage/lcov-report/dist/test-utils/thirteen/index.html +1 -1
  77. package/coverage/lcov-report/dist/test-utils/thirteen/models/audience.js.html +2 -2
  78. package/coverage/lcov-report/dist/test-utils/thirteen/models/brand.js.html +2 -2
  79. package/coverage/lcov-report/dist/test-utils/thirteen/models/category.js.html +1 -1
  80. package/coverage/lcov-report/dist/test-utils/thirteen/models/index.html +14 -14
  81. package/coverage/lcov-report/dist/test-utils/thirteen/models/member.js.html +2 -2
  82. package/coverage/lcov-report/dist/test-utils/thirteen/models/passion.js.html +2 -2
  83. package/coverage/lcov-report/dist/test-utils/thirteen/models/product.js.html +10 -10
  84. package/coverage/lcov-report/dist/test-utils/thirteen/models/recommendation-audience.js.html +2 -2
  85. package/coverage/lcov-report/dist/test-utils/thirteen/models/recommendation.js.html +2 -2
  86. package/coverage/lcov-report/dist/test-utils/three/index.html +1 -1
  87. package/coverage/lcov-report/dist/test-utils/three/results.js.html +1 -1
  88. package/coverage/lcov-report/dist/test-utils/twelve/entities.js.html +1 -1
  89. package/coverage/lcov-report/dist/test-utils/twelve/index.html +1 -1
  90. package/coverage/lcov-report/dist/test-utils/twelve/models/index.html +1 -1
  91. package/coverage/lcov-report/dist/test-utils/twelve/models/member.js.html +1 -1
  92. package/coverage/lcov-report/dist/test-utils/twelve/models/prompt.js.html +2 -2
  93. package/coverage/lcov-report/dist/test-utils/two/index.html +1 -1
  94. package/coverage/lcov-report/dist/test-utils/two/results.js.html +1 -1
  95. package/coverage/lcov-report/index.html +103 -103
  96. package/coverage/lcov-report/src/core.ts.html +841 -415
  97. package/coverage/lcov-report/src/driver-integrations/index.html +20 -20
  98. package/coverage/lcov-report/src/driver-integrations/pgp.ts.html +63 -63
  99. package/coverage/lcov-report/src/index.html +28 -28
  100. package/coverage/lcov-report/src/index.ts.html +1 -1
  101. package/coverage/lcov-report/src/orm.ts.html +388 -298
  102. package/coverage/lcov-report/test-utils/blog/entities.ts.html +1 -1
  103. package/coverage/lcov-report/test-utils/blog/index.html +1 -1
  104. package/coverage/lcov-report/test-utils/blog/models/article.ts.html +15 -15
  105. package/coverage/lcov-report/test-utils/blog/models/article_tag.ts.html +2 -2
  106. package/coverage/lcov-report/test-utils/blog/models/index.html +1 -1
  107. package/coverage/lcov-report/test-utils/blog/models/person.ts.html +13 -13
  108. package/coverage/lcov-report/test-utils/blog/models/tag.ts.html +1 -1
  109. package/coverage/lcov-report/test-utils/five/entities.ts.html +1 -1
  110. package/coverage/lcov-report/test-utils/five/index.html +1 -1
  111. package/coverage/lcov-report/test-utils/five/models/index.html +1 -1
  112. package/coverage/lcov-report/test-utils/five/models/line-item.ts.html +4 -4
  113. package/coverage/lcov-report/test-utils/five/models/order.ts.html +3 -3
  114. package/coverage/lcov-report/test-utils/five/models/parcel-event.ts.html +6 -6
  115. package/coverage/lcov-report/test-utils/five/models/parcel-line-item.ts.html +7 -7
  116. package/coverage/lcov-report/test-utils/five/models/parcel.ts.html +2 -2
  117. package/coverage/lcov-report/test-utils/fourteen/entities.ts.html +1 -1
  118. package/coverage/lcov-report/test-utils/fourteen/index.html +1 -1
  119. package/coverage/lcov-report/test-utils/fourteen/models/customer.ts.html +1 -1
  120. package/coverage/lcov-report/test-utils/fourteen/models/index.html +1 -1
  121. package/coverage/lcov-report/test-utils/fourteen/models/person.ts.html +1 -1
  122. package/coverage/lcov-report/test-utils/nine/entities.ts.html +1 -1
  123. package/coverage/lcov-report/test-utils/nine/index.html +1 -1
  124. package/coverage/lcov-report/test-utils/nine/models/feature-switch.ts.html +8 -8
  125. package/coverage/lcov-report/test-utils/nine/models/index.html +1 -1
  126. package/coverage/lcov-report/test-utils/order/entities.ts.html +2 -2
  127. package/coverage/lcov-report/test-utils/order/index.html +1 -1
  128. package/coverage/lcov-report/test-utils/order/models/index.html +14 -14
  129. package/coverage/lcov-report/test-utils/order/models/line-item.ts.html +5 -5
  130. package/coverage/lcov-report/test-utils/order/models/order.ts.html +36 -36
  131. package/coverage/lcov-report/test-utils/order/models/product-variant.ts.html +13 -13
  132. package/coverage/lcov-report/test-utils/order/models/product.ts.html +13 -13
  133. package/coverage/lcov-report/test-utils/order/models/utm-source.ts.html +8 -8
  134. package/coverage/lcov-report/test-utils/order-more/entities.ts.html +1 -1
  135. package/coverage/lcov-report/test-utils/order-more/index.html +1 -1
  136. package/coverage/lcov-report/test-utils/order-more/models/actual-product-variant.ts.html +3 -3
  137. package/coverage/lcov-report/test-utils/order-more/models/color.ts.html +6 -6
  138. package/coverage/lcov-report/test-utils/order-more/models/customer.ts.html +3 -3
  139. package/coverage/lcov-report/test-utils/order-more/models/gender.ts.html +4 -4
  140. package/coverage/lcov-report/test-utils/order-more/models/index.html +23 -23
  141. package/coverage/lcov-report/test-utils/order-more/models/inventory-level.ts.html +11 -11
  142. package/coverage/lcov-report/test-utils/order-more/models/line-item.ts.html +15 -15
  143. package/coverage/lcov-report/test-utils/order-more/models/order.ts.html +45 -45
  144. package/coverage/lcov-report/test-utils/order-more/models/parcel-event.ts.html +6 -6
  145. package/coverage/lcov-report/test-utils/order-more/models/parcel-line-item.ts.html +7 -7
  146. package/coverage/lcov-report/test-utils/order-more/models/parcel.ts.html +2 -2
  147. package/coverage/lcov-report/test-utils/order-more/models/physical-address.ts.html +12 -12
  148. package/coverage/lcov-report/test-utils/order-more/models/product-variant-image.ts.html +7 -7
  149. package/coverage/lcov-report/test-utils/order-more/models/product-variant.ts.html +22 -22
  150. package/coverage/lcov-report/test-utils/order-more/models/product.ts.html +11 -11
  151. package/coverage/lcov-report/test-utils/order-more/models/refund.ts.html +11 -11
  152. package/coverage/lcov-report/test-utils/order-more/models/shipment-actual-product-variant.ts.html +9 -9
  153. package/coverage/lcov-report/test-utils/order-more/models/shipment.ts.html +4 -4
  154. package/coverage/lcov-report/test-utils/order-more/models/size.ts.html +4 -4
  155. package/coverage/lcov-report/test-utils/order-more/models/utm-medium.ts.html +15 -15
  156. package/coverage/lcov-report/test-utils/order-more/models/utm-source.ts.html +17 -17
  157. package/coverage/lcov-report/test-utils/six/entities.ts.html +1 -1
  158. package/coverage/lcov-report/test-utils/six/index.html +1 -1
  159. package/coverage/lcov-report/test-utils/six/models/customer.ts.html +3 -3
  160. package/coverage/lcov-report/test-utils/six/models/index.html +21 -21
  161. package/coverage/lcov-report/test-utils/six/models/line-item.ts.html +10 -10
  162. package/coverage/lcov-report/test-utils/six/models/order.ts.html +13 -13
  163. package/coverage/lcov-report/test-utils/six/models/parcel-line-item.ts.html +2 -2
  164. package/coverage/lcov-report/test-utils/six/models/parcel.ts.html +2 -2
  165. package/coverage/lcov-report/test-utils/thirteen/entities.ts.html +1 -1
  166. package/coverage/lcov-report/test-utils/thirteen/index.html +1 -1
  167. package/coverage/lcov-report/test-utils/thirteen/models/audience.ts.html +2 -2
  168. package/coverage/lcov-report/test-utils/thirteen/models/brand.ts.html +2 -2
  169. package/coverage/lcov-report/test-utils/thirteen/models/category.ts.html +1 -1
  170. package/coverage/lcov-report/test-utils/thirteen/models/index.html +14 -14
  171. package/coverage/lcov-report/test-utils/thirteen/models/member.ts.html +2 -2
  172. package/coverage/lcov-report/test-utils/thirteen/models/passion.ts.html +2 -2
  173. package/coverage/lcov-report/test-utils/thirteen/models/product.ts.html +10 -10
  174. package/coverage/lcov-report/test-utils/thirteen/models/recommendation-audience.ts.html +2 -2
  175. package/coverage/lcov-report/test-utils/thirteen/models/recommendation.ts.html +2 -2
  176. package/coverage/lcov-report/test-utils/three/index.html +1 -1
  177. package/coverage/lcov-report/test-utils/three/results.js.html +1 -1
  178. package/coverage/lcov-report/test-utils/twelve/entities.ts.html +1 -1
  179. package/coverage/lcov-report/test-utils/twelve/index.html +1 -1
  180. package/coverage/lcov-report/test-utils/twelve/models/index.html +1 -1
  181. package/coverage/lcov-report/test-utils/twelve/models/member.ts.html +1 -1
  182. package/coverage/lcov-report/test-utils/twelve/models/prompt.ts.html +2 -2
  183. package/coverage/lcov-report/test-utils/two/index.html +1 -1
  184. package/coverage/lcov-report/test-utils/two/results.js.html +1 -1
  185. package/coverage/lcov.info +2136 -1991
  186. package/dist/example/data-access/person.d.ts +1 -1
  187. package/dist/src/core.d.ts +13 -7
  188. package/dist/src/core.js +258 -189
  189. package/dist/src/core.spec.js +413 -0
  190. package/dist/src/driver-integrations/index.d.ts +5 -5
  191. package/dist/src/driver-integrations/pgp.spec.d.ts +1 -0
  192. package/dist/src/driver-integrations/pgp.spec.js +376 -0
  193. package/dist/src/orm.d.ts +9 -9
  194. package/dist/src/orm.js +137 -76
  195. package/dist/src/orm.spec.js +535 -85
  196. package/dist/test-utils/nine/models/feature-switch.d.ts +2 -2
  197. package/dist/test-utils/nine/models/feature-switch.ts +2 -2
  198. package/example/data-access/person.ts +1 -1
  199. package/package.json +9 -6
  200. package/scripts/bench-core.js +636 -0
  201. package/scripts/check-bench-scenarios.js +47 -0
  202. package/src/core.spec.ts +485 -2
  203. package/src/core.ts +369 -227
  204. package/src/driver-integrations/index.ts +5 -5
  205. package/src/driver-integrations/pgp.spec.ts +444 -0
  206. package/src/driver-integrations/pgp.ts +5 -5
  207. package/src/orm.spec.ts +592 -88
  208. package/src/orm.ts +173 -143
  209. package/test-utils/nine/models/feature-switch.ts +2 -2
@@ -20,24 +20,24 @@
20
20
  </h1>
21
21
  <div class='clearfix'>
22
22
  <div class='fl pad1y space-right2'>
23
- <span class="strong">95.31% </span>
23
+ <span class="strong">98.9% </span>
24
24
  <span class="quiet">Statements</span>
25
- <span class='fraction'>183/192</span>
25
+ <span class='fraction'>270/273</span>
26
26
  </div>
27
27
  <div class='fl pad1y space-right2'>
28
- <span class="strong">86.61% </span>
28
+ <span class="strong">90.98% </span>
29
29
  <span class="quiet">Branches</span>
30
- <span class='fraction'>97/112</span>
30
+ <span class='fraction'>111/122</span>
31
31
  </div>
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">98.04% </span>
33
+ <span class="strong">100% </span>
34
34
  <span class="quiet">Functions</span>
35
- <span class='fraction'>50/51</span>
35
+ <span class='fraction'>31/31</span>
36
36
  </div>
37
37
  <div class='fl pad1y space-right2'>
38
- <span class="strong">95.53% </span>
38
+ <span class="strong">98.8% </span>
39
39
  <span class="quiet">Lines</span>
40
- <span class='fraction'>171/179</span>
40
+ <span class='fraction'>248/251</span>
41
41
  </div>
42
42
  </div>
43
43
  <p class="quiet">
@@ -379,59 +379,136 @@
379
379
  <a name='L331'></a><a href='#L331'>331</a>
380
380
  <a name='L332'></a><a href='#L332'>332</a>
381
381
  <a name='L333'></a><a href='#L333'>333</a>
382
- <a name='L334'></a><a href='#L334'>334</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
383
- <span class="cline-any cline-yes">2x</span>
384
- <span class="cline-any cline-yes">2x</span>
385
- <span class="cline-any cline-neutral">&nbsp;</span>
386
- <span class="cline-any cline-yes">2x</span>
387
- <span class="cline-any cline-yes">2x</span>
388
- <span class="cline-any cline-yes">2x</span>
389
- <span class="cline-any cline-yes">2x</span>
390
- <span class="cline-any cline-yes">34x</span>
391
- <span class="cline-any cline-yes">227x</span>
392
- <span class="cline-any cline-yes">227x</span>
393
- <span class="cline-any cline-yes">227x</span>
394
- <span class="cline-any cline-yes">227x</span>
395
- <span class="cline-any cline-yes">1793x</span>
396
- <span class="cline-any cline-yes">1580x</span>
397
- <span class="cline-any cline-neutral">&nbsp;</span>
398
- <span class="cline-any cline-neutral">&nbsp;</span>
399
- <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <a name='L334'></a><a href='#L334'>334</a>
383
+ <a name='L335'></a><a href='#L335'>335</a>
384
+ <a name='L336'></a><a href='#L336'>336</a>
385
+ <a name='L337'></a><a href='#L337'>337</a>
386
+ <a name='L338'></a><a href='#L338'>338</a>
387
+ <a name='L339'></a><a href='#L339'>339</a>
388
+ <a name='L340'></a><a href='#L340'>340</a>
389
+ <a name='L341'></a><a href='#L341'>341</a>
390
+ <a name='L342'></a><a href='#L342'>342</a>
391
+ <a name='L343'></a><a href='#L343'>343</a>
392
+ <a name='L344'></a><a href='#L344'>344</a>
393
+ <a name='L345'></a><a href='#L345'>345</a>
394
+ <a name='L346'></a><a href='#L346'>346</a>
395
+ <a name='L347'></a><a href='#L347'>347</a>
396
+ <a name='L348'></a><a href='#L348'>348</a>
397
+ <a name='L349'></a><a href='#L349'>349</a>
398
+ <a name='L350'></a><a href='#L350'>350</a>
399
+ <a name='L351'></a><a href='#L351'>351</a>
400
+ <a name='L352'></a><a href='#L352'>352</a>
401
+ <a name='L353'></a><a href='#L353'>353</a>
402
+ <a name='L354'></a><a href='#L354'>354</a>
403
+ <a name='L355'></a><a href='#L355'>355</a>
404
+ <a name='L356'></a><a href='#L356'>356</a>
405
+ <a name='L357'></a><a href='#L357'>357</a>
406
+ <a name='L358'></a><a href='#L358'>358</a>
407
+ <a name='L359'></a><a href='#L359'>359</a>
408
+ <a name='L360'></a><a href='#L360'>360</a>
409
+ <a name='L361'></a><a href='#L361'>361</a>
410
+ <a name='L362'></a><a href='#L362'>362</a>
411
+ <a name='L363'></a><a href='#L363'>363</a>
412
+ <a name='L364'></a><a href='#L364'>364</a>
413
+ <a name='L365'></a><a href='#L365'>365</a>
414
+ <a name='L366'></a><a href='#L366'>366</a>
415
+ <a name='L367'></a><a href='#L367'>367</a>
416
+ <a name='L368'></a><a href='#L368'>368</a>
417
+ <a name='L369'></a><a href='#L369'>369</a>
418
+ <a name='L370'></a><a href='#L370'>370</a>
419
+ <a name='L371'></a><a href='#L371'>371</a>
420
+ <a name='L372'></a><a href='#L372'>372</a>
421
+ <a name='L373'></a><a href='#L373'>373</a>
422
+ <a name='L374'></a><a href='#L374'>374</a>
423
+ <a name='L375'></a><a href='#L375'>375</a>
424
+ <a name='L376'></a><a href='#L376'>376</a>
425
+ <a name='L377'></a><a href='#L377'>377</a>
426
+ <a name='L378'></a><a href='#L378'>378</a>
427
+ <a name='L379'></a><a href='#L379'>379</a>
428
+ <a name='L380'></a><a href='#L380'>380</a>
429
+ <a name='L381'></a><a href='#L381'>381</a>
430
+ <a name='L382'></a><a href='#L382'>382</a>
431
+ <a name='L383'></a><a href='#L383'>383</a>
432
+ <a name='L384'></a><a href='#L384'>384</a>
433
+ <a name='L385'></a><a href='#L385'>385</a>
434
+ <a name='L386'></a><a href='#L386'>386</a>
435
+ <a name='L387'></a><a href='#L387'>387</a>
436
+ <a name='L388'></a><a href='#L388'>388</a>
437
+ <a name='L389'></a><a href='#L389'>389</a>
438
+ <a name='L390'></a><a href='#L390'>390</a>
439
+ <a name='L391'></a><a href='#L391'>391</a>
440
+ <a name='L392'></a><a href='#L392'>392</a>
441
+ <a name='L393'></a><a href='#L393'>393</a>
442
+ <a name='L394'></a><a href='#L394'>394</a>
443
+ <a name='L395'></a><a href='#L395'>395</a>
444
+ <a name='L396'></a><a href='#L396'>396</a>
445
+ <a name='L397'></a><a href='#L397'>397</a>
446
+ <a name='L398'></a><a href='#L398'>398</a>
447
+ <a name='L399'></a><a href='#L399'>399</a>
448
+ <a name='L400'></a><a href='#L400'>400</a>
449
+ <a name='L401'></a><a href='#L401'>401</a>
450
+ <a name='L402'></a><a href='#L402'>402</a>
451
+ <a name='L403'></a><a href='#L403'>403</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-yes">3x</span>
453
+ <span class="cline-any cline-yes">3x</span>
400
454
  <span class="cline-any cline-neutral">&nbsp;</span>
455
+ <span class="cline-any cline-yes">3x</span>
456
+ <span class="cline-any cline-yes">3x</span>
457
+ <span class="cline-any cline-yes">3x</span>
458
+ <span class="cline-any cline-yes">3x</span>
459
+ <span class="cline-any cline-yes">125x</span>
460
+ <span class="cline-any cline-yes">509x</span>
461
+ <span class="cline-any cline-yes">509x</span>
462
+ <span class="cline-any cline-yes">509x</span>
463
+ <span class="cline-any cline-yes">509x</span>
464
+ <span class="cline-any cline-yes">4796x</span>
465
+ <span class="cline-any cline-yes">4339x</span>
401
466
  <span class="cline-any cline-neutral">&nbsp;</span>
402
- <span class="cline-any cline-yes">213x</span>
403
467
  <span class="cline-any cline-neutral">&nbsp;</span>
404
- <span class="cline-any cline-yes">1793x</span>
405
- <span class="cline-any cline-yes">1793x</span>
406
- <span class="cline-any cline-yes">1793x</span>
407
- <span class="cline-any cline-yes">227x</span>
408
- <span class="cline-any cline-yes">227x</span>
409
- <span class="cline-any cline-yes">1793x</span>
410
- <span class="cline-any cline-yes">227x</span>
411
- <span class="cline-any cline-yes">227x</span>
412
468
  <span class="cline-any cline-neutral">&nbsp;</span>
413
- <span class="cline-any cline-yes">227x</span>
414
- <span class="cline-any cline-yes">3611x</span>
415
- <span class="cline-any cline-yes">3611x</span>
416
469
  <span class="cline-any cline-neutral">&nbsp;</span>
417
470
  <span class="cline-any cline-neutral">&nbsp;</span>
418
- <span class="cline-any cline-yes">227x</span>
419
- <span class="cline-any cline-yes">1793x</span>
420
- <span class="cline-any cline-yes">201x</span>
471
+ <span class="cline-any cline-yes">457x</span>
421
472
  <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-yes">4796x</span>
474
+ <span class="cline-any cline-yes">4796x</span>
475
+ <span class="cline-any cline-yes">4796x</span>
476
+ <span class="cline-any cline-yes">509x</span>
477
+ <span class="cline-any cline-yes">509x</span>
478
+ <span class="cline-any cline-yes">4796x</span>
479
+ <span class="cline-any cline-yes">509x</span>
480
+ <span class="cline-any cline-yes">509x</span>
481
+ <span class="cline-any cline-yes">509x</span>
482
+ <span class="cline-any cline-yes">1x</span>
483
+ <span class="cline-any cline-yes">1x</span>
484
+ <span class="cline-any cline-yes">2x</span>
485
+ <span class="cline-any cline-yes">2x</span>
486
+ <span class="cline-any cline-yes">2x</span>
422
487
  <span class="cline-any cline-neutral">&nbsp;</span>
423
- <span class="cline-any cline-yes">227x</span>
424
- <span class="cline-any cline-yes">1793x</span>
425
488
  <span class="cline-any cline-neutral">&nbsp;</span>
426
- <span class="cline-any cline-yes">227x</span>
489
+ <span class="cline-any cline-yes">1x</span>
427
490
  <span class="cline-any cline-neutral">&nbsp;</span>
491
+ <span class="cline-any cline-yes">509x</span>
492
+ <span class="cline-any cline-yes">509x</span>
493
+ <span class="cline-any cline-yes">509x</span>
494
+ <span class="cline-any cline-yes">4796x</span>
495
+ <span class="cline-any cline-yes">392x</span>
496
+ <span class="cline-any cline-yes">392x</span>
428
497
  <span class="cline-any cline-neutral">&nbsp;</span>
429
498
  <span class="cline-any cline-neutral">&nbsp;</span>
430
499
  <span class="cline-any cline-neutral">&nbsp;</span>
431
500
  <span class="cline-any cline-neutral">&nbsp;</span>
432
501
  <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-yes">509x</span>
503
+ <span class="cline-any cline-yes">509x</span>
504
+ <span class="cline-any cline-yes">509x</span>
505
+ <span class="cline-any cline-yes">4796x</span>
506
+ <span class="cline-any cline-yes">4796x</span>
433
507
  <span class="cline-any cline-neutral">&nbsp;</span>
508
+ <span class="cline-any cline-yes">509x</span>
509
+ <span class="cline-any cline-yes">4796x</span>
434
510
  <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-yes">509x</span>
435
512
  <span class="cline-any cline-neutral">&nbsp;</span>
436
513
  <span class="cline-any cline-neutral">&nbsp;</span>
437
514
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -439,156 +516,200 @@
439
516
  <span class="cline-any cline-neutral">&nbsp;</span>
440
517
  <span class="cline-any cline-neutral">&nbsp;</span>
441
518
  <span class="cline-any cline-neutral">&nbsp;</span>
442
- <span class="cline-any cline-yes">34x</span>
443
- <span class="cline-any cline-yes">227x</span>
444
- <span class="cline-any cline-yes">227x</span>
445
519
  <span class="cline-any cline-neutral">&nbsp;</span>
446
- <span class="cline-any cline-yes">34x</span>
447
- <span class="cline-any cline-yes">1435x</span>
448
- <span class="cline-any cline-yes">1435x</span>
449
- <span class="cline-any cline-no">&nbsp;</span>
450
520
  <span class="cline-any cline-neutral">&nbsp;</span>
451
- <span class="cline-any cline-yes">1435x</span>
452
521
  <span class="cline-any cline-neutral">&nbsp;</span>
453
- <span class="cline-any cline-yes">34x</span>
454
- <span class="cline-any cline-yes">227x</span>
455
- <span class="cline-any cline-yes">227x</span>
456
522
  <span class="cline-any cline-neutral">&nbsp;</span>
457
- <span class="cline-any cline-yes">34x</span>
458
- <span class="cline-any cline-yes">42896x</span>
459
- <span class="cline-any cline-yes">42896x</span>
460
- <span class="cline-any cline-no">&nbsp;</span>
461
523
  <span class="cline-any cline-neutral">&nbsp;</span>
462
- <span class="cline-any cline-yes">42896x</span>
463
524
  <span class="cline-any cline-neutral">&nbsp;</span>
464
- <span class="cline-any cline-yes">34x</span>
465
- <span class="cline-any cline-yes">42895x</span>
466
525
  <span class="cline-any cline-neutral">&nbsp;</span>
467
526
  <span class="cline-any cline-neutral">&nbsp;</span>
468
527
  <span class="cline-any cline-neutral">&nbsp;</span>
469
528
  <span class="cline-any cline-neutral">&nbsp;</span>
470
529
  <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-yes">125x</span>
531
+ <span class="cline-any cline-yes">509x</span>
532
+ <span class="cline-any cline-yes">509x</span>
471
533
  <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-yes">125x</span>
535
+ <span class="cline-any cline-yes">164x</span>
536
+ <span class="cline-any cline-yes">164x</span>
537
+ <span class="cline-any cline-yes">1x</span>
472
538
  <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-yes">163x</span>
473
540
  <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-yes">125x</span>
542
+ <span class="cline-any cline-yes">509x</span>
543
+ <span class="cline-any cline-yes">509x</span>
474
544
  <span class="cline-any cline-neutral">&nbsp;</span>
545
+ <span class="cline-any cline-yes">125x</span>
546
+ <span class="cline-any cline-yes">495x</span>
547
+ <span class="cline-any cline-yes">495x</span>
548
+ <span class="cline-any cline-yes">1x</span>
475
549
  <span class="cline-any cline-neutral">&nbsp;</span>
476
- <span class="cline-any cline-yes">34x</span>
477
- <span class="cline-any cline-yes">188x</span>
478
- <span class="cline-any cline-yes">39x</span>
479
- <span class="cline-any cline-yes">1434x</span>
480
- <span class="cline-any cline-yes">39x</span>
481
- <span class="cline-any cline-yes">39x</span>
550
+ <span class="cline-any cline-yes">494x</span>
482
551
  <span class="cline-any cline-neutral">&nbsp;</span>
483
- <span class="cline-any cline-yes">39x</span>
484
- <span class="cline-any cline-yes">188x</span>
485
- <span class="cline-any cline-yes">21304x</span>
552
+ <span class="cline-any cline-yes">125x</span>
553
+ <span class="cline-any cline-yes">102x</span>
486
554
  <span class="cline-any cline-neutral">&nbsp;</span>
555
+ <span class="cline-any cline-yes">125x</span>
556
+ <span class="cline-any cline-yes">125x</span>
557
+ <span class="cline-any cline-yes">509x</span>
558
+ <span class="cline-any cline-yes">509x</span>
559
+ <span class="cline-any cline-yes">509x</span>
560
+ <span class="cline-any cline-yes">392x</span>
561
+ <span class="cline-any cline-yes">392x</span>
487
562
  <span class="cline-any cline-neutral">&nbsp;</span>
488
- <span class="cline-any cline-yes">1246x</span>
489
- <span class="cline-any cline-yes">1246x</span>
490
- <span class="cline-any cline-yes">1246x</span>
491
- <span class="cline-any cline-yes">29445x</span>
492
- <span class="cline-any cline-yes">28144x</span>
493
- <span class="cline-any cline-yes">28144x</span>
494
- <span class="cline-any cline-yes">29445x</span>
495
- <span class="cline-any cline-yes">28597x</span>
496
563
  <span class="cline-any cline-neutral">&nbsp;</span>
497
- <span class="cline-any cline-yes">848x</span>
498
- <span class="cline-any cline-yes">849x</span>
499
- <span class="cline-any cline-yes">849x</span>
500
- <span class="cline-any cline-yes">822x</span>
501
564
  <span class="cline-any cline-neutral">&nbsp;</span>
502
565
  <span class="cline-any cline-neutral">&nbsp;</span>
503
- <span class="cline-any cline-yes">26x</span>
566
+ <span class="cline-any cline-yes">509x</span>
504
567
  <span class="cline-any cline-neutral">&nbsp;</span>
568
+ <span class="cline-any cline-yes">125x</span>
569
+ <span class="cline-any cline-yes">1459x</span>
570
+ <span class="cline-any cline-yes">1459x</span>
571
+ <span class="cline-any cline-yes">1459x</span>
572
+ <span class="cline-any cline-yes">1459x</span>
573
+ <span class="cline-any cline-yes">1291x</span>
505
574
  <span class="cline-any cline-neutral">&nbsp;</span>
506
575
  <span class="cline-any cline-neutral">&nbsp;</span>
507
- <span class="cline-any cline-yes">1246x</span>
508
- <span class="cline-any cline-yes">12590x</span>
509
- <span class="cline-any cline-yes">10448x</span>
576
+ <span class="cline-any cline-yes">1459x</span>
510
577
  <span class="cline-any cline-neutral">&nbsp;</span>
511
- <span class="cline-any cline-yes">49133x</span>
512
- <span class="cline-any cline-yes">2142x</span>
513
- <span class="cline-any cline-yes">1203x</span>
578
+ <span class="cline-any cline-yes">125x</span>
579
+ <span class="cline-any cline-yes">44x</span>
580
+ <span class="cline-any cline-yes">44x</span>
581
+ <span class="cline-any cline-yes">44x</span>
582
+ <span class="cline-any cline-yes">926x</span>
583
+ <span class="cline-any cline-no">&nbsp;</span>
514
584
  <span class="cline-any cline-neutral">&nbsp;</span>
515
- <span class="cline-any cline-yes">939x</span>
585
+ <span class="cline-any cline-yes">926x</span>
586
+ <span class="cline-any cline-yes">926x</span>
587
+ <span class="cline-any cline-yes">1x</span>
516
588
  <span class="cline-any cline-neutral">&nbsp;</span>
517
- <span class="cline-any cline-yes">1246x</span>
589
+ <span class="cline-any cline-yes">925x</span>
590
+ <span class="cline-any cline-yes">925x</span>
591
+ <span class="cline-any cline-yes">925x</span>
592
+ <span class="cline-any cline-yes">925x</span>
593
+ <span class="cline-any cline-yes">148x</span>
594
+ <span class="cline-any cline-yes">148x</span>
595
+ <span class="cline-any cline-yes">148x</span>
518
596
  <span class="cline-any cline-neutral">&nbsp;</span>
519
597
  <span class="cline-any cline-neutral">&nbsp;</span>
520
598
  <span class="cline-any cline-neutral">&nbsp;</span>
521
- <span class="cline-any cline-yes">1246x</span>
522
- <span class="cline-any cline-yes">6559x</span>
523
- <span class="cline-any cline-yes">2788x</span>
524
- <span class="cline-any cline-yes">2788x</span>
525
- <span class="cline-any cline-yes">6559x</span>
526
- <span class="cline-any cline-yes">6150x</span>
527
599
  <span class="cline-any cline-neutral">&nbsp;</span>
528
- <span class="cline-any cline-yes">409x</span>
529
- <span class="cline-any cline-yes">410x</span>
530
- <span class="cline-any cline-yes">410x</span>
531
- <span class="cline-any cline-yes">355x</span>
600
+ <span class="cline-any cline-yes">148x</span>
601
+ <span class="cline-any cline-yes">148x</span>
532
602
  <span class="cline-any cline-neutral">&nbsp;</span>
603
+ <span class="cline-any cline-yes">925x</span>
604
+ <span class="cline-any cline-yes">925x</span>
605
+ <span class="cline-any cline-yes">2x</span>
606
+ <span class="cline-any cline-yes">1x</span>
533
607
  <span class="cline-any cline-neutral">&nbsp;</span>
534
- <span class="cline-any cline-yes">54x</span>
535
608
  <span class="cline-any cline-neutral">&nbsp;</span>
536
- <span class="cline-any cline-yes">1246x</span>
537
- <span class="cline-any cline-yes">614x</span>
538
- <span class="cline-any cline-yes">75x</span>
539
- <span class="cline-any cline-yes">75x</span>
609
+ <span class="cline-any cline-yes">1x</span>
540
610
  <span class="cline-any cline-neutral">&nbsp;</span>
541
611
  <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-yes">924x</span>
542
613
  <span class="cline-any cline-neutral">&nbsp;</span>
543
614
  <span class="cline-any cline-neutral">&nbsp;</span>
544
615
  <span class="cline-any cline-neutral">&nbsp;</span>
545
616
  <span class="cline-any cline-neutral">&nbsp;</span>
546
- <span class="cline-any cline-yes">539x</span>
547
- <span class="cline-any cline-yes">539x</span>
617
+ <span class="cline-any cline-yes">42x</span>
618
+ <span class="cline-any cline-yes">42x</span>
619
+ <span class="cline-any cline-yes">147x</span>
548
620
  <span class="cline-any cline-neutral">&nbsp;</span>
549
- <span class="cline-any cline-yes">539x</span>
550
- <span class="cline-any cline-yes">61x</span>
551
- <span class="cline-any cline-yes">61x</span>
621
+ <span class="cline-any cline-yes">42x</span>
552
622
  <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-yes">125x</span>
624
+ <span class="cline-any cline-yes">213x</span>
625
+ <span class="cline-any cline-yes">213x</span>
626
+ <span class="cline-any cline-yes">1459x</span>
627
+ <span class="cline-any cline-yes">1459x</span>
628
+ <span class="cline-any cline-yes">1459x</span>
629
+ <span class="cline-any cline-yes">1459x</span>
630
+ <span class="cline-any cline-yes">1291x</span>
631
+ <span class="cline-any cline-yes">1291x</span>
632
+ <span class="cline-any cline-yes">276x</span>
633
+ <span class="cline-any cline-yes">276x</span>
553
634
  <span class="cline-any cline-neutral">&nbsp;</span>
554
635
  <span class="cline-any cline-neutral">&nbsp;</span>
555
- <span class="cline-any cline-yes">1110x</span>
556
- <span class="cline-any cline-yes">761x</span>
636
+ <span class="cline-any cline-yes">1015x</span>
637
+ <span class="cline-any cline-yes">1015x</span>
638
+ <span class="cline-any cline-yes">726x</span>
639
+ <span class="cline-any cline-yes">726x</span>
557
640
  <span class="cline-any cline-neutral">&nbsp;</span>
558
- <span class="cline-any cline-yes">349x</span>
559
- <span class="cline-any cline-yes">228x</span>
560
- <span class="cline-any cline-yes">228x</span>
561
- <span class="cline-any cline-yes">149x</span>
562
641
  <span class="cline-any cline-neutral">&nbsp;</span>
563
642
  <span class="cline-any cline-neutral">&nbsp;</span>
564
- <span class="cline-any cline-yes">79x</span>
565
- <span class="cline-any cline-yes">79x</span>
643
+ <span class="cline-any cline-yes">168x</span>
566
644
  <span class="cline-any cline-neutral">&nbsp;</span>
567
645
  <span class="cline-any cline-neutral">&nbsp;</span>
646
+ <span class="cline-any cline-yes">168x</span>
647
+ <span class="cline-any cline-yes">168x</span>
568
648
  <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-yes">565x</span>
650
+ <span class="cline-any cline-yes">565x</span>
651
+ <span class="cline-any cline-yes">2768x</span>
652
+ <span class="cline-any cline-yes">2768x</span>
569
653
  <span class="cline-any cline-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-yes">565x</span>
655
+ <span class="cline-any cline-yes">565x</span>
570
656
  <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-yes">565x</span>
658
+ <span class="cline-any cline-yes">565x</span>
571
659
  <span class="cline-any cline-neutral">&nbsp;</span>
572
- <span class="cline-any cline-yes">121x</span>
660
+ <span class="cline-any cline-yes">565x</span>
573
661
  <span class="cline-any cline-neutral">&nbsp;</span>
574
- <span class="cline-any cline-yes">121x</span>
662
+ <span class="cline-any cline-yes">213x</span>
575
663
  <span class="cline-any cline-neutral">&nbsp;</span>
664
+ <span class="cline-any cline-yes">125x</span>
665
+ <span class="cline-any cline-yes">213x</span>
666
+ <span class="cline-any cline-yes">213x</span>
667
+ <span class="cline-any cline-yes">213x</span>
576
668
  <span class="cline-any cline-no">&nbsp;</span>
577
669
  <span class="cline-any cline-neutral">&nbsp;</span>
578
- <span class="cline-any cline-yes">989x</span>
670
+ <span class="cline-any cline-yes">213x</span>
671
+ <span class="cline-any cline-yes">213x</span>
579
672
  <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-yes">213x</span>
580
674
  <span class="cline-any cline-neutral">&nbsp;</span>
581
- <span class="cline-any cline-yes">39x</span>
675
+ <span class="cline-any cline-yes">125x</span>
676
+ <span class="cline-any cline-yes">64x</span>
677
+ <span class="cline-any cline-yes">64x</span>
678
+ <span class="cline-any cline-yes">64x</span>
582
679
  <span class="cline-any cline-neutral">&nbsp;</span>
583
680
  <span class="cline-any cline-neutral">&nbsp;</span>
681
+ <span class="cline-any cline-yes">64x</span>
584
682
  <span class="cline-any cline-neutral">&nbsp;</span>
683
+ <span class="cline-any cline-yes">64x</span>
585
684
  <span class="cline-any cline-neutral">&nbsp;</span>
685
+ <span class="cline-any cline-yes">125x</span>
686
+ <span class="cline-any cline-yes">540x</span>
687
+ <span class="cline-any cline-yes">37x</span>
586
688
  <span class="cline-any cline-neutral">&nbsp;</span>
689
+ <span class="cline-any cline-yes">540x</span>
587
690
  <span class="cline-any cline-neutral">&nbsp;</span>
691
+ <span class="cline-any cline-yes">125x</span>
692
+ <span class="cline-any cline-yes">540x</span>
588
693
  <span class="cline-any cline-neutral">&nbsp;</span>
694
+ <span class="cline-any cline-yes">540x</span>
695
+ <span class="cline-any cline-yes">540x</span>
696
+ <span class="cline-any cline-yes">355x</span>
697
+ <span class="cline-any cline-yes">355x</span>
698
+ <span class="cline-any cline-yes">355x</span>
589
699
  <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-yes">540x</span>
701
+ <span class="cline-any cline-yes">540x</span>
702
+ <span class="cline-any cline-yes">321x</span>
703
+ <span class="cline-any cline-yes">321x</span>
590
704
  <span class="cline-any cline-neutral">&nbsp;</span>
705
+ <span class="cline-any cline-yes">540x</span>
706
+ <span class="cline-any cline-yes">540x</span>
707
+ <span class="cline-any cline-yes">355x</span>
708
+ <span class="cline-any cline-yes">355x</span>
591
709
  <span class="cline-any cline-neutral">&nbsp;</span>
710
+ <span class="cline-any cline-yes">540x</span>
711
+ <span class="cline-any cline-yes">538x</span>
712
+ <span class="cline-any cline-yes">538x</span>
592
713
  <span class="cline-any cline-neutral">&nbsp;</span>
593
714
  <span class="cline-any cline-neutral">&nbsp;</span>
594
715
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -599,103 +720,120 @@
599
720
  <span class="cline-any cline-neutral">&nbsp;</span>
600
721
  <span class="cline-any cline-neutral">&nbsp;</span>
601
722
  <span class="cline-any cline-neutral">&nbsp;</span>
602
- <span class="cline-any cline-yes">34x</span>
603
- <span class="cline-any cline-yes">22x</span>
604
- <span class="cline-any cline-yes">22x</span>
605
- <span class="cline-any cline-yes">22x</span>
606
- <span class="cline-any cline-yes">188x</span>
607
- <span class="cline-any cline-yes">188x</span>
723
+ <span class="cline-any cline-yes">125x</span>
608
724
  <span class="cline-any cline-neutral">&nbsp;</span>
609
- <span class="cline-any cline-yes">188x</span>
610
- <span class="cline-any cline-yes">149x</span>
725
+ <span class="cline-any cline-yes">44x</span>
726
+ <span class="cline-any cline-yes">44x</span>
727
+ <span class="cline-any cline-yes">44x</span>
728
+ <span class="cline-any cline-yes">42x</span>
729
+ <span class="cline-any cline-yes">42x</span>
730
+ <span class="cline-any cline-yes">147x</span>
611
731
  <span class="cline-any cline-neutral">&nbsp;</span>
732
+ <span class="cline-any cline-yes">42x</span>
733
+ <span class="cline-any cline-yes">42x</span>
734
+ <span class="cline-any cline-yes">147x</span>
735
+ <span class="cline-any cline-yes">147x</span>
736
+ <span class="cline-any cline-yes">147x</span>
737
+ <span class="cline-any cline-yes">147x</span>
612
738
  <span class="cline-any cline-neutral">&nbsp;</span>
613
- <span class="cline-any cline-yes">39x</span>
739
+ <span class="cline-any cline-yes">42x</span>
740
+ <span class="cline-any cline-yes">42x</span>
741
+ <span class="cline-any cline-yes">42x</span>
742
+ <span class="cline-any cline-yes">42x</span>
743
+ <span class="cline-any cline-yes">42x</span>
744
+ <span class="cline-any cline-yes">42x</span>
745
+ <span class="cline-any cline-yes">42x</span>
746
+ <span class="cline-any cline-yes">42x</span>
747
+ <span class="cline-any cline-yes">42x</span>
748
+ <span class="cline-any cline-yes">42x</span>
614
749
  <span class="cline-any cline-neutral">&nbsp;</span>
615
- <span class="cline-any cline-yes">188x</span>
750
+ <span class="cline-any cline-yes">42x</span>
751
+ <span class="cline-any cline-yes">213x</span>
752
+ <span class="cline-any cline-yes">213x</span>
753
+ <span class="cline-any cline-yes">213x</span>
754
+ <span class="cline-any cline-yes">213x</span>
755
+ <span class="cline-any cline-yes">64x</span>
756
+ <span class="cline-any cline-yes">64x</span>
757
+ <span class="cline-any cline-yes">64x</span>
616
758
  <span class="cline-any cline-neutral">&nbsp;</span>
617
- <span class="cline-any cline-yes">22x</span>
759
+ <span class="cline-any cline-yes">213x</span>
760
+ <span class="cline-any cline-yes">213x</span>
761
+ <span class="cline-any cline-yes">64x</span>
762
+ <span class="cline-any cline-yes">64x</span>
618
763
  <span class="cline-any cline-neutral">&nbsp;</span>
619
- <span class="cline-any cline-yes">34x</span>
620
- <span class="cline-any cline-yes">188x</span>
621
- <span class="cline-any cline-yes">1434x</span>
622
- <span class="cline-any cline-yes">1434x</span>
623
- <span class="cline-any cline-yes">6747x</span>
624
- <span class="cline-any cline-yes">6747x</span>
625
- <span class="cline-any cline-no">&nbsp;</span>
626
- <span class="cline-any cline-no">&nbsp;</span>
764
+ <span class="cline-any cline-yes">213x</span>
765
+ <span class="cline-any cline-yes">565x</span>
766
+ <span class="cline-any cline-yes">565x</span>
767
+ <span class="cline-any cline-yes">565x</span>
768
+ <span class="cline-any cline-yes">565x</span>
769
+ <span class="cline-any cline-yes">565x</span>
770
+ <span class="cline-any cline-yes">565x</span>
771
+ <span class="cline-any cline-yes">258x</span>
627
772
  <span class="cline-any cline-neutral">&nbsp;</span>
773
+ <span class="cline-any cline-yes">307x</span>
774
+ <span class="cline-any cline-yes">562x</span>
775
+ <span class="cline-any cline-yes">562x</span>
776
+ <span class="cline-any cline-yes">562x</span>
777
+ <span class="cline-any cline-yes">11x</span>
628
778
  <span class="cline-any cline-neutral">&nbsp;</span>
629
- <span class="cline-any cline-no">&nbsp;</span>
779
+ <span class="cline-any cline-yes">551x</span>
780
+ <span class="cline-any cline-yes">551x</span>
630
781
  <span class="cline-any cline-neutral">&nbsp;</span>
782
+ <span class="cline-any cline-yes">551x</span>
783
+ <span class="cline-any cline-yes">540x</span>
631
784
  <span class="cline-any cline-neutral">&nbsp;</span>
632
- <span class="cline-any cline-yes">6747x</span>
633
- <span class="cline-any cline-yes">6747x</span>
634
785
  <span class="cline-any cline-neutral">&nbsp;</span>
635
- <span class="cline-any cline-yes">1434x</span>
636
786
  <span class="cline-any cline-neutral">&nbsp;</span>
637
787
  <span class="cline-any cline-neutral">&nbsp;</span>
638
788
  <span class="cline-any cline-neutral">&nbsp;</span>
639
789
  <span class="cline-any cline-neutral">&nbsp;</span>
640
790
  <span class="cline-any cline-neutral">&nbsp;</span>
641
791
  <span class="cline-any cline-neutral">&nbsp;</span>
642
- <span class="cline-any cline-yes">34x</span>
643
- <span class="cline-any cline-yes">188x</span>
644
- <span class="cline-any cline-yes">6747x</span>
645
- <span class="cline-any cline-yes">6747x</span>
646
- <span class="cline-any cline-yes">6747x</span>
647
- <span class="cline-any cline-no">&nbsp;</span>
648
792
  <span class="cline-any cline-neutral">&nbsp;</span>
649
- <span class="cline-any cline-yes">6747x</span>
650
- <span class="cline-any cline-yes">6747x</span>
651
- <span class="cline-any cline-yes">6747x</span>
652
793
  <span class="cline-any cline-neutral">&nbsp;</span>
653
794
  <span class="cline-any cline-neutral">&nbsp;</span>
654
- <span class="cline-any cline-yes">34x</span>
655
- <span class="cline-any cline-yes">22x</span>
656
- <span class="cline-any cline-yes">22x</span>
657
- <span class="cline-any cline-yes">22x</span>
658
- <span class="cline-any cline-yes">22x</span>
659
- <span class="cline-any cline-yes">22x</span>
660
- <span class="cline-any cline-yes">39x</span>
661
- <span class="cline-any cline-yes">22x</span>
662
- <span class="cline-any cline-yes">22x</span>
795
+ <span class="cline-any cline-yes">42x</span>
796
+ <span class="cline-any cline-yes">42x</span>
797
+ <span class="cline-any cline-yes">64x</span>
663
798
  <span class="cline-any cline-neutral">&nbsp;</span>
664
- <span class="cline-any cline-yes">34x</span>
665
- <span class="cline-any cline-yes">4x</span>
666
- <span class="cline-any cline-yes">2x</span>
799
+ <span class="cline-any cline-yes">42x</span>
800
+ <span class="cline-any cline-yes">42x</span>
667
801
  <span class="cline-any cline-neutral">&nbsp;</span>
802
+ <span class="cline-any cline-yes">125x</span>
803
+ <span class="cline-any cline-yes">10x</span>
804
+ <span class="cline-any cline-yes">5x</span>
668
805
  <span class="cline-any cline-neutral">&nbsp;</span>
669
- <span class="cline-any cline-yes">2x</span>
670
806
  <span class="cline-any cline-neutral">&nbsp;</span>
671
- <span class="cline-any cline-yes">2x</span>
807
+ <span class="cline-any cline-yes">5x</span>
672
808
  <span class="cline-any cline-neutral">&nbsp;</span>
673
- <span class="cline-any cline-yes">34x</span>
674
809
  <span class="cline-any cline-yes">5x</span>
675
- <span class="cline-any cline-yes">1x</span>
676
810
  <span class="cline-any cline-neutral">&nbsp;</span>
677
- <span class="cline-any cline-yes">4x</span>
678
- <span class="cline-any cline-yes">4x</span>
811
+ <span class="cline-any cline-yes">125x</span>
812
+ <span class="cline-any cline-yes">17x</span>
813
+ <span class="cline-any cline-yes">2x</span>
814
+ <span class="cline-any cline-neutral">&nbsp;</span>
815
+ <span class="cline-any cline-yes">15x</span>
816
+ <span class="cline-any cline-yes">15x</span>
679
817
  <span class="cline-any cline-no">&nbsp;</span>
680
818
  <span class="cline-any cline-neutral">&nbsp;</span>
819
+ <span class="cline-any cline-yes">15x</span>
681
820
  <span class="cline-any cline-yes">4x</span>
682
- <span class="cline-any cline-yes">2x</span>
683
821
  <span class="cline-any cline-neutral">&nbsp;</span>
684
- <span class="cline-any cline-yes">2x</span>
822
+ <span class="cline-any cline-yes">11x</span>
685
823
  <span class="cline-any cline-neutral">&nbsp;</span>
686
- <span class="cline-any cline-yes">34x</span>
824
+ <span class="cline-any cline-yes">125x</span>
825
+ <span class="cline-any cline-yes">8x</span>
687
826
  <span class="cline-any cline-yes">3x</span>
688
- <span class="cline-any cline-yes">1x</span>
689
827
  <span class="cline-any cline-neutral">&nbsp;</span>
690
- <span class="cline-any cline-yes">2x</span>
828
+ <span class="cline-any cline-yes">5x</span>
691
829
  <span class="cline-any cline-neutral">&nbsp;</span>
692
- <span class="cline-any cline-yes">34x</span>
830
+ <span class="cline-any cline-yes">125x</span>
831
+ <span class="cline-any cline-yes">9x</span>
693
832
  <span class="cline-any cline-yes">3x</span>
694
- <span class="cline-any cline-yes">1x</span>
695
833
  <span class="cline-any cline-neutral">&nbsp;</span>
696
- <span class="cline-any cline-yes">2x</span>
834
+ <span class="cline-any cline-yes">6x</span>
697
835
  <span class="cline-any cline-neutral">&nbsp;</span>
698
- <span class="cline-any cline-yes">34x</span>
836
+ <span class="cline-any cline-yes">125x</span>
699
837
  <span class="cline-any cline-neutral">&nbsp;</span>
700
838
  <span class="cline-any cline-neutral">&nbsp;</span>
701
839
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -704,14 +842,14 @@
704
842
  <span class="cline-any cline-neutral">&nbsp;</span>
705
843
  <span class="cline-any cline-neutral">&nbsp;</span>
706
844
  <span class="cline-any cline-neutral">&nbsp;</span>
707
- <span class="cline-any cline-yes">227x</span>
845
+ <span class="cline-any cline-yes">509x</span>
708
846
  <span class="cline-any cline-neutral">&nbsp;</span>
709
847
  <span class="cline-any cline-neutral">&nbsp;</span>
710
- <span class="cline-any cline-yes">227x</span>
848
+ <span class="cline-any cline-yes">509x</span>
711
849
  <span class="cline-any cline-neutral">&nbsp;</span>
712
850
  <span class="cline-any cline-neutral">&nbsp;</span>
713
851
  <span class="cline-any cline-neutral">&nbsp;</span>
714
- <span class="cline-any cline-yes">2x</span>
852
+ <span class="cline-any cline-yes">3x</span>
715
853
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">"use strict";
716
854
  var __importDefault = (this &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >this.__importDefault)</span> || function (mod) {
717
855
  return (mod &amp;&amp; mod.__esModule) ? <span class="branch-0 cbranch-no" title="branch not covered" >mod </span>: { "default": mod };
@@ -724,7 +862,7 @@ const createCore = ({ entities: externalEntities }) =&gt; {
724
862
  const tableName = d.tableName;
725
863
  const displayName = d.displayName || (0, camelcase_1.default)(d.tableName);
726
864
  const collectionDisplayName = d.collectionDisplayName || `${displayName}s`;
727
- const columns = (typeof d.columns === 'function' ? <span class="branch-0 cbranch-no" title="branch not covered" >d.columns() </span>: d.columns).map((d) =&gt; {
865
+ const columns = (typeof d.columns === 'function' ? d.columns() : d.columns).map((d) =&gt; {
728
866
  if (typeof d === 'string') {
729
867
  return {
730
868
  column: d,
@@ -740,19 +878,35 @@ const createCore = ({ entities: externalEntities }) =&gt; {
740
878
  const Model = d.Model;
741
879
  const Collection = d.Collection;
742
880
  const pkColumnsData = columns.filter((x) =&gt; x.primaryKey);
743
- const _primaryKeys = pkColumnsData.map(<span class="fstat-no" title="function not covered" >(x</span>) =&gt; <span class="cstat-no" title="statement not covered" >x.column)</span>;
744
- const primaryKeys = _primaryKeys.length &gt; 0 ? <span class="branch-0 cbranch-no" title="branch not covered" >_primaryKeys </span>: ['id'];
745
- // Returns unique identifier of model (the values of the primary keys)
881
+ const _primaryKeys = pkColumnsData.map((x) =&gt; x.column);
882
+ const primaryKeys = _primaryKeys.length &gt; 0 ? _primaryKeys : ['id'];
746
883
  const getPkId = (model) =&gt; {
747
- return primaryKeys
748
- .map((key) =&gt; model[key])
749
- .join('');
884
+ let id = '';
885
+ for (let i = 0; i &lt; primaryKeys.length; i++) {
886
+ const part = model[primaryKeys[i]];
887
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (part !== void 0 &amp;&amp; part !== null) {
888
+ id += String(part);
889
+ }
890
+ }
891
+ return id;
750
892
  };
751
- const references = columns
752
- .filter((x) =&gt; x.references)
753
- .reduce((accum, item) =&gt; Object.assign({}, accum, {
754
- [item.property]: item.references
755
- }), {});
893
+ const references = {};
894
+ const referencesEntries = [];
895
+ for (const col of columns) {
896
+ if (col.references) {
897
+ references[col.property] = col.references;
898
+ referencesEntries.push({
899
+ property: col.property,
900
+ ModelClass: col.references
901
+ });
902
+ }
903
+ }
904
+ const columnToPropertyMap = new Map();
905
+ const propertyToColumnMap = new Map();
906
+ for (let i = 0; i &lt; columnNames.length; i++) {
907
+ columnToPropertyMap.set(columnNames[i], propertyNames[i]);
908
+ propertyToColumnMap.set(propertyNames[i], columnNames[i]);
909
+ }
756
910
  const selectColumnsClause = prefixedColumnNames
757
911
  .map((prefixed, index) =&gt; `"${tableName}".${columnNames[index]} as "${prefixed}"`)
758
912
  .join(', ');
@@ -769,7 +923,10 @@ const createCore = ({ entities: externalEntities }) =&gt; {
769
923
  primaryKeys,
770
924
  references,
771
925
  selectColumnsClause,
772
- getPkId
926
+ getPkId,
927
+ columnToPropertyMap,
928
+ propertyToColumnMap,
929
+ referencesEntries
773
930
  };
774
931
  });
775
932
  const tableNameToEntityMap = entities.reduce((map, entity) =&gt; {
@@ -778,8 +935,8 @@ const createCore = ({ entities: externalEntities }) =&gt; {
778
935
  }, new Map());
779
936
  const getEntityByTableName = (tableName) =&gt; {
780
937
  const entity = tableNameToEntityMap.get(tableName);
781
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!entity) {
782
- <span class="cstat-no" title="statement not covered" > throw new Error(`Could not find entity for table ${tableName}`);</span>
938
+ if (!entity) {
939
+ throw new Error(`Could not find entity for table ${tableName}`);
783
940
  }
784
941
  return entity;
785
942
  };
@@ -789,208 +946,258 @@ const createCore = ({ entities: externalEntities }) =&gt; {
789
946
  }, new Map());
790
947
  const getEntityByModelClass = (Model) =&gt; {
791
948
  const entity = modelToEntityMap.get(Model);
792
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!entity) {
793
- <span class="cstat-no" title="statement not covered" > throw new Error(`Could not find entity for class ${Model}`);</span>
949
+ if (!entity) {
950
+ throw new Error(`Could not find entity for class ${Model}`);
794
951
  }
795
952
  return entity;
796
953
  };
797
954
  const getEntityByModel = (model) =&gt; {
798
955
  return getEntityByModelClass(model.constructor);
799
956
  };
800
- /*
801
- * In:
802
- * [
803
- * [Article {id: 32}, ArticleTag {id: 54}]
804
- * [Article {id: 32}, ArticleTag {id: 55}]
805
- * ]
806
- * Out:
807
- * Article {id: 32, ArticleTags articleTags: [ArticleTag {id: 54}, ArticleTag {id: 55}]
808
- */
809
- const nestClump = (clump) =&gt; {
810
- clump = clump.map((x) =&gt; Object.values(x));
811
- const root = clump[0][0];
812
- clump = clump.map((row) =&gt; row.filter((item, index) =&gt; index !== 0));
813
- const built = { [getEntityByModel(root).displayName]: root };
814
- let nodes = [root];
815
- // Wowzer is this both CPU and Memory inefficient
816
- clump.forEach((array) =&gt; {
817
- array.forEach((_model) =&gt; {
818
- const nodeAlreadySeen = nodes.find((x) =&gt; x.constructor.name === _model.constructor.name &amp;&amp;
819
- getEntityByModel(x).getPkId(x) ===
820
- getEntityByModel(_model).getPkId(_model));
821
- const model = nodeAlreadySeen || _model;
822
- const isNodeAlreadySeen = !!nodeAlreadySeen;
823
- const nodePointingToIt = nodes.find((node) =&gt; {
824
- const indexes = Object.values(getEntityByModel(node).references)
825
- .map((x, i) =&gt; x === model.constructor ? i : null)
826
- .filter((x, i) =&gt; x != null);
827
- if (!indexes.length) {
828
- return false;
829
- }
830
- for (const index of indexes) {
831
- const property = Object.keys(getEntityByModel(node).references)[index];
832
- if (node[property] === model.id) {
833
- return true;
834
- }
835
- }
836
- return false;
837
- });
838
- // For first obj type which is has an instance in nodes array,
839
- // get its index in nodes array
840
- const indexOfOldestParent = array.reduce((answer, obj) =&gt; {
841
- if (answer != null) {
842
- return answer;
843
- }
844
- const index = nodes.findIndex((n) =&gt; n.constructor === obj.constructor);
845
- if (index !== -1) {
846
- return index;
847
- }
848
- return null;
849
- }, null) || 0;
850
- const parentHeirarchy = [
851
- root,
852
- ...nodes.slice(0, indexOfOldestParent + 1).reverse()
853
- ];
854
- const nodeItPointsTo = parentHeirarchy.find((parent) =&gt; {
855
- const indexes = Object.values(getEntityByModel(model).references)
856
- .map((x, i) =&gt; x === parent.constructor ? i : null)
857
- .filter((x, i) =&gt; x != null);
858
- if (!indexes.length) {
859
- return false;
860
- }
861
- for (const index of indexes) {
862
- const property = Object.keys(getEntityByModel(model).references)[index];
863
- if (model[property] === parent.id) {
864
- return true;
865
- }
866
- }
867
- return false;
868
- });
869
- if (isNodeAlreadySeen) {
870
- if (nodeItPointsTo &amp;&amp; !nodePointingToIt) {
871
- nodes = [model, ...nodes];
872
- return;
873
- }
874
- // If the nodePointingToIt (eg, parcel_event) is part of an
875
- // existing collection on this node (eg, parcel) which is a
876
- // nodeAlreadySeen, early return so we don't create it (parcel) on
877
- // the nodePointingToIt (parcel_event), since it (parcel) has been
878
- // shown to be the parent (of parcel_events).
879
- <span class="missing-if-branch" title="else path not taken" >E</span>if (nodePointingToIt) {
880
- const ec = model[getEntityByModel(nodePointingToIt)
881
- .collectionDisplayName];
882
- if (ec &amp;&amp; ec.models.find((m) =&gt; m === nodePointingToIt)) {
883
- nodes = [model, ...nodes];
884
- return;
885
- }
886
- }
957
+ const entityReferencePlans = new Map();
958
+ for (let i = 0; i &lt; entities.length; i++) {
959
+ const entity = entities[i];
960
+ const plans = new Array(entity.referencesEntries.length);
961
+ for (let j = 0; j &lt; entity.referencesEntries.length; j++) {
962
+ const ref = entity.referencesEntries[j];
963
+ plans[j] = {
964
+ property: ref.property,
965
+ targetEntity: getEntityByModelClass(ref.ModelClass)
966
+ };
967
+ }
968
+ entityReferencePlans.set(entity, plans);
969
+ }
970
+ const getPkIdFromRow = (row, primaryKeyRowKeys) =&gt; {
971
+ let id = '';
972
+ for (let i = 0; i &lt; primaryKeyRowKeys.length; i++) {
973
+ const part = row[primaryKeyRowKeys[i]];
974
+ if (part !== void 0 &amp;&amp; part !== null) {
975
+ id += String(part);
976
+ }
977
+ }
978
+ return id;
979
+ };
980
+ const buildEntityRowPlans = (sampleRow) =&gt; {
981
+ const plansByTable = new Map();
982
+ const tableOrder = [];
983
+ for (const text in sampleRow) {
984
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!Object.prototype.hasOwnProperty.call(sampleRow, text)) {
985
+ <span class="cstat-no" title="statement not covered" > continue;</span>
986
+ }
987
+ const hashIndex = text.indexOf('#');
988
+ if (hashIndex === -1) {
989
+ throw new Error('Column names must be namespaced to table');
990
+ }
991
+ const tableName = text.substring(0, hashIndex);
992
+ const column = text.substring(hashIndex + 1);
993
+ let plan = plansByTable.get(tableName);
994
+ if (!plan) {
995
+ const entity = getEntityByTableName(tableName);
996
+ const primaryKeyRowKeys = entity.primaryKeys.map((pk) =&gt; `${tableName}#${pk}`);
997
+ plan = {
998
+ entity,
999
+ columnPlans: [],
1000
+ primaryKeyRowKeys
1001
+ };
1002
+ plansByTable.set(tableName, plan);
1003
+ tableOrder.push(tableName);
1004
+ }
1005
+ let propertyName = plan.entity.columnToPropertyMap.get(column);
1006
+ if (!propertyName) {
1007
+ if (column.startsWith('meta_')) {
1008
+ propertyName = (0, camelcase_1.default)(column);
887
1009
  }
888
- if (nodePointingToIt) {
889
- nodePointingToIt[getEntityByModel(model).displayName] = model;
1010
+ else {
1011
+ throw Error(`No property name for "${column}" in business object "${plan.entity.displayName}". Non-spec'd columns must begin with "meta_".`);
890
1012
  }
891
- else if (nodeItPointsTo) {
892
- let collection = nodeItPointsTo[getEntityByModel(model).collectionDisplayName];
893
- if (collection) {
894
- collection.models.push(model);
895
- }
896
- else {
897
- const Collection = getEntityByModel(model).Collection;
898
- nodeItPointsTo[getEntityByModel(model).collectionDisplayName] =
899
- new Collection({
900
- models: [model]
901
- });
902
- }
1013
+ }
1014
+ plan.columnPlans.push({
1015
+ rowKey: text,
1016
+ propertyName
1017
+ });
1018
+ }
1019
+ const orderedPlans = new Array(tableOrder.length);
1020
+ for (let i = 0; i &lt; tableOrder.length; i++) {
1021
+ orderedPlans[i] = plansByTable.get(tableOrder[i]);
1022
+ }
1023
+ return orderedPlans;
1024
+ };
1025
+ const materializeModelsFromRow = (row, entityRowPlans, rootScopedModelsByEntity, rowModels, rowModelPkIds, rowCreatedWithPkIndexes) =&gt; {
1026
+ rowCreatedWithPkIndexes.length = 0;
1027
+ for (let i = 0; i &lt; entityRowPlans.length; i++) {
1028
+ const plan = entityRowPlans[i];
1029
+ const pkId = getPkIdFromRow(row, plan.primaryKeyRowKeys);
1030
+ rowModelPkIds[i] = pkId;
1031
+ if (pkId) {
1032
+ let modelsForEntity = rootScopedModelsByEntity.get(plan.entity);
1033
+ if (!modelsForEntity) {
1034
+ modelsForEntity = new Map();
1035
+ rootScopedModelsByEntity.set(plan.entity, modelsForEntity);
903
1036
  }
904
1037
  else {
905
- <span class="missing-if-branch" title="else path not taken" >E</span>if (!getEntityByModel(model).getPkId(model)) {
906
- // If the join is fruitless; todo: add a test for this path
907
- return;
1038
+ const existing = modelsForEntity.get(pkId);
1039
+ if (existing) {
1040
+ rowModels[i] = existing;
1041
+ continue;
908
1042
  }
909
- <span class="cstat-no" title="statement not covered" > throw Error(`Could not find how this BO fits: ${JSON.stringify(model)} ${getEntityByModel(model).tableName}`);</span>
910
1043
  }
911
- nodes = [model, ...nodes];
912
- });
913
- });
914
- return built;
1044
+ }
1045
+ else <span class="missing-if-branch" title="else path not taken" >E</span>if (i !== 0) {
1046
+ // No primary key means this is typically an outer-joined null row.
1047
+ // Skip model construction for non-root entities since it cannot link.
1048
+ rowModels[i] = void 0;
1049
+ continue;
1050
+ }
1051
+ const props = {};
1052
+ for (let j = 0; j &lt; plan.columnPlans.length; j++) {
1053
+ const columnPlan = plan.columnPlans[j];
1054
+ props[columnPlan.propertyName] = row[columnPlan.rowKey];
1055
+ }
1056
+ const model = new plan.entity.Model(props);
1057
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (pkId) {
1058
+ // modelsForEntity is guaranteed to be initialized above for pk rows.
1059
+ rootScopedModelsByEntity.get(plan.entity).set(pkId, model);
1060
+ rowCreatedWithPkIndexes.push(i);
1061
+ }
1062
+ rowModels[i] = model;
1063
+ }
1064
+ return rowModels[0];
1065
+ };
1066
+ const getRootScopeKey = (row, rootEntity, rootPrimaryKeys) =&gt; {
1067
+ let rootScopeKey = '';
1068
+ for (let i = 0; i &lt; rootPrimaryKeys.length; i++) {
1069
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (i &gt; 0) {
1070
+ <span class="cstat-no" title="statement not covered" > rootScopeKey += '@';</span>
1071
+ }
1072
+ const value = row[`${rootEntity.tableName}#${rootPrimaryKeys[i]}`];
1073
+ rootScopeKey += value === void 0 || value === null ? <span class="branch-0 cbranch-no" title="branch not covered" >'' </span>: String(value);
1074
+ }
1075
+ return rootScopeKey;
1076
+ };
1077
+ const ensureRootScopeState = (rootScopeKey, rootScopeStateByKey) =&gt; {
1078
+ let state = rootScopeStateByKey.get(rootScopeKey);
1079
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (!state) {
1080
+ state = {
1081
+ modelsByEntity: new Map()
1082
+ };
1083
+ rootScopeStateByKey.set(rootScopeKey, state);
1084
+ }
1085
+ return state;
1086
+ };
1087
+ const ensureCollectionMembership = (rootScopeState) =&gt; {
1088
+ if (!rootScopeState.collectionMembership) {
1089
+ rootScopeState.collectionMembership = new WeakMap();
1090
+ }
1091
+ return rootScopeState.collectionMembership;
1092
+ };
1093
+ const linkSourceToTarget = ({ sourceEntity, sourceModel, sourceModelPkId, targetEntity, targetModel, collectionMembership }) =&gt; {
1094
+ sourceModel[targetEntity.displayName] =
1095
+ targetModel;
1096
+ let collection = targetModel[sourceEntity.collectionDisplayName];
1097
+ if (!collection) {
1098
+ const Collection = sourceEntity.Collection;
1099
+ collection = new Collection({ models: [] });
1100
+ targetModel[sourceEntity.collectionDisplayName] = collection;
1101
+ }
1102
+ let byCollection = collectionMembership.get(targetModel);
1103
+ if (!byCollection) {
1104
+ byCollection = new Map();
1105
+ collectionMembership.set(targetModel, byCollection);
1106
+ }
1107
+ let memberIds = byCollection.get(sourceEntity);
1108
+ if (!memberIds) {
1109
+ memberIds = new Set();
1110
+ byCollection.set(sourceEntity, memberIds);
1111
+ }
1112
+ if (!memberIds.has(sourceModelPkId)) {
1113
+ collection.models.push(sourceModel);
1114
+ memberIds.add(sourceModelPkId);
1115
+ }
915
1116
  };
916
1117
  /*
917
- * Clump array of flat objects into groups based on id of root
918
- * In:
919
- * [
920
- * [Article {id: 32}, ArticleTag {id: 54}]
921
- * [Article {id: 32}, ArticleTag {id: 55}]
922
- * [Article {id: 33}, ArticleTag {id: 56}]
923
- * ]
924
- * Out:
925
- * [
926
- * [
927
- * [Article {id: 32}, ArticleTag {id: 54}]
928
- * [Article {id: 32}, ArticleTag {id: 55}]
929
- * ]
930
- * [
931
- * [Article {id: 33}, ArticleTag {id: 56}]
932
- * ]
933
- * ]
1118
+ * createFromDatabase architecture:
1119
+ * 1) Compile row plans once (column -&gt; property mapping per entity/table).
1120
+ * 2) Materialize models per row with scoped de-duplication by root scope key.
1121
+ * 3) Index models by root scope + entity + entity primary key.
1122
+ * 4) Link refs incrementally as new models appear.
1123
+ * 5) Return root models in first-seen root scope order.
934
1124
  */
935
- const clumpIntoGroups = (processed) =&gt; {
936
- const root = processed[0][0];
937
- const rootBo = root.constructor;
938
- const clumps = processed.reduce((accum, item) =&gt; {
939
- const id = getEntityByModel(root)
940
- .primaryKeys.map((key) =&gt; { var _a; return (_a = item.find((x) =&gt; x.constructor === rootBo)) === null || _a === void 0 ? <span class="branch-0 cbranch-no" title="branch not covered" >void 0 </span>: _a[key]; })
941
- .join('@');
942
- if (accum.has(id)) {
943
- accum.set(id, [...accum.get(id), item]);
1125
+ const createFromDatabase = (rows) =&gt; {
1126
+ var _a;
1127
+ const result = Array.isArray(rows) ? rows : [rows];
1128
+ const len = result.length;
1129
+ const entityRowPlans = buildEntityRowPlans(result[0]);
1130
+ const selectedEntities = new Set();
1131
+ for (let i = 0; i &lt; entityRowPlans.length; i++) {
1132
+ selectedEntities.add(entityRowPlans[i].entity);
1133
+ }
1134
+ const applicableRefPlans = new Map();
1135
+ for (let i = 0; i &lt; entityRowPlans.length; i++) {
1136
+ const entity = entityRowPlans[i].entity;
1137
+ const refs = entityReferencePlans.get(entity) || <span class="branch-1 cbranch-no" title="branch not covered" >[];</span>
1138
+ const filteredRefs = refs.filter((ref) =&gt; selectedEntities.has(ref.targetEntity));
1139
+ applicableRefPlans.set(entity, filteredRefs);
1140
+ }
1141
+ const rootEntity = entityRowPlans[0].entity;
1142
+ const rootPrimaryKeys = rootEntity.primaryKeys;
1143
+ const rootScopeOrder = [];
1144
+ const rootModelsByScopeKey = new Map();
1145
+ const rootScopeStateByKey = new Map();
1146
+ let currentRootScopeKey = void 0;
1147
+ let currentRootScopeState = void 0;
1148
+ const rowModels = new Array(entityRowPlans.length);
1149
+ const rowModelPkIds = new Array(entityRowPlans.length);
1150
+ const rowCreatedWithPkIndexes = [];
1151
+ // Phase 1: materialize and index model instances by root scope + entity.
1152
+ for (let i = 0; i &lt; len; i++) {
1153
+ const row = result[i];
1154
+ const rootScopeKey = getRootScopeKey(row, rootEntity, rootPrimaryKeys);
1155
+ let rootScopeState = currentRootScopeState;
1156
+ if (!rootScopeState || rootScopeKey !== currentRootScopeKey) {
1157
+ rootScopeState = ensureRootScopeState(rootScopeKey, rootScopeStateByKey);
1158
+ currentRootScopeKey = rootScopeKey;
1159
+ currentRootScopeState = rootScopeState;
944
1160
  }
945
- else {
946
- accum.set(id, [item]);
1161
+ const rootModel = materializeModelsFromRow(row, entityRowPlans, rootScopeState.modelsByEntity, rowModels, rowModelPkIds, rowCreatedWithPkIndexes);
1162
+ if (!rootModelsByScopeKey.has(rootScopeKey)) {
1163
+ rootScopeOrder.push(rootScopeKey);
1164
+ rootModelsByScopeKey.set(rootScopeKey, rootModel);
947
1165
  }
948
- return accum;
949
- }, new Map());
950
- return [...clumps.values()];
951
- };
952
- const mapToBos = (objectified) =&gt; {
953
- return Object.keys(objectified).map((tableName) =&gt; {
954
- const entity = getEntityByTableName(tableName);
955
- const propified = Object.keys(objectified[tableName]).reduce((obj, column) =&gt; {
956
- let propertyName = entity.propertyNames[entity.columnNames.indexOf(column)];
957
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!propertyName) {
958
- <span class="cstat-no" title="statement not covered" > if (column.startsWith('meta_')) {</span>
959
- <span class="cstat-no" title="statement not covered" > propertyName = (0, camelcase_1.default)(column);</span>
1166
+ for (let c = 0; c &lt; rowCreatedWithPkIndexes.length; c++) {
1167
+ const j = rowCreatedWithPkIndexes[c];
1168
+ const sourceModel = rowModels[j];
1169
+ const sourceModelPkId = rowModelPkIds[j];
1170
+ const sourceEntity = entityRowPlans[j].entity;
1171
+ const refs = applicableRefPlans.get(sourceEntity);
1172
+ if (!refs || refs.length === 0) {
1173
+ continue;
1174
+ }
1175
+ for (let r = 0; r &lt; refs.length; r++) {
1176
+ const ref = refs[r];
1177
+ const refId = sourceModel[ref.property];
1178
+ if (refId == null) {
1179
+ continue;
960
1180
  }
961
- else {
962
- <span class="cstat-no" title="statement not covered" > throw Error(`No property name for "${column}" in business object "${entity.displayName}". Non-spec'd columns must begin with "meta_".`);</span>
1181
+ const targetPkId = String(refId);
1182
+ const target = (_a = rootScopeState.modelsByEntity
1183
+ .get(ref.targetEntity)) === null || _a === void 0 ? void 0 : _a.get(targetPkId);
1184
+ if (target) {
1185
+ linkSourceToTarget({
1186
+ sourceEntity,
1187
+ sourceModel,
1188
+ sourceModelPkId,
1189
+ targetEntity: ref.targetEntity,
1190
+ targetModel: target,
1191
+ collectionMembership: ensureCollectionMembership(rootScopeState)
1192
+ });
963
1193
  }
964
1194
  }
965
- obj[propertyName] = objectified[tableName][column];
966
- return obj;
967
- }, {});
968
- return new entity.Model(propified);
969
- });
970
- };
971
- /*
972
- * Make objects (based on special table#column names) from flat database
973
- * return value.
974
- */
975
- const objectifyDatabaseResult = (result) =&gt; {
976
- return Object.keys(result).reduce((obj, text) =&gt; {
977
- const tableName = text.split('#')[0];
978
- const column = text.split('#')[1];
979
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!tableName || !column) {
980
- <span class="cstat-no" title="statement not covered" > throw new Error('Column names must be namespaced to table');</span>
981
1195
  }
982
- obj[tableName] = obj[tableName] || {};
983
- obj[tableName][column] = result[text];
984
- return obj;
985
- }, {});
986
- };
987
- const createFromDatabase = (rows) =&gt; {
988
- const result = Array.isArray(rows) ? rows : <span class="branch-1 cbranch-no" title="branch not covered" >[rows];</span>
989
- const objectified = result.map(objectifyDatabaseResult);
990
- const boified = objectified.map(mapToBos);
991
- const clumps = clumpIntoGroups(boified);
992
- const nested = clumps.map(nestClump);
993
- const models = nested.map((n) =&gt; Object.values(n)[0]);
1196
+ }
1197
+ const models = new Array(rootScopeOrder.length);
1198
+ for (let i = 0; i &lt; rootScopeOrder.length; i++) {
1199
+ models[i] = rootModelsByScopeKey.get(rootScopeOrder[i]);
1200
+ }
994
1201
  const Collection = getEntityByModel(models[0]).Collection;
995
1202
  return new Collection({ models });
996
1203
  };
@@ -1051,7 +1258,7 @@ exports.createCore = createCore;
1051
1258
  </div><!-- /wrapper -->
1052
1259
  <div class='footer quiet pad2 space-top1 center small'>
1053
1260
  Code coverage
1054
- generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Sat Dec 23 2023 12:48:55 GMT-0500 (Eastern Standard Time)
1261
+ generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Sun Mar 01 2026 17:10:47 GMT-0500 (Eastern Standard Time)
1055
1262
  </div>
1056
1263
  </div>
1057
1264
  <script src="../../prettify.js"></script>