@budibase/server 0.9.184 → 0.9.185-alpha.11

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 (290) hide show
  1. package/Dockerfile +1 -1
  2. package/__mocks__/mssql.ts +1 -1
  3. package/__mocks__/pg.ts +3 -0
  4. package/builder/assets/bb-space-man.5be51a45.svg +290 -0
  5. package/builder/assets/index.053c6f7a.js +1321 -0
  6. package/builder/assets/index.4a7c5636.css +1 -0
  7. package/builder/assets/vendor.470042a4.js +152 -0
  8. package/builder/assets/vendor.5e1fe644.css +1 -0
  9. package/builder/index.html +4 -4
  10. package/coverage/clover.xml +1357 -959
  11. package/coverage/coverage-final.json +91 -87
  12. package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
  13. package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
  14. package/coverage/lcov-report/api/controllers/application.js.html +65 -14
  15. package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
  16. package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
  17. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  20. package/coverage/lcov-report/api/controllers/datasource.js.html +147 -27
  21. package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
  22. package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
  23. package/coverage/lcov-report/api/controllers/index.html +90 -90
  24. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
  26. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
  27. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  28. package/coverage/lcov-report/api/controllers/query.js.html +53 -209
  29. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  30. package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
  31. package/coverage/lcov-report/api/controllers/row/external.js.html +12 -6
  32. package/coverage/lcov-report/api/controllers/row/index.html +26 -26
  33. package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
  35. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  36. package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
  37. package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
  38. package/coverage/lcov-report/api/controllers/script.js.html +3 -3
  39. package/coverage/lcov-report/api/controllers/table/external.js.html +980 -0
  40. package/coverage/lcov-report/api/controllers/table/index.html +56 -26
  41. package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
  42. package/coverage/lcov-report/api/controllers/table/internal.js.html +545 -0
  43. package/coverage/lcov-report/api/controllers/table/utils.js.html +172 -49
  44. package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
  45. package/coverage/lcov-report/api/controllers/user.js.html +390 -33
  46. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.html +9 -9
  48. package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
  49. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  50. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
  51. package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
  52. package/coverage/lcov-report/api/index.html +1 -1
  53. package/coverage/lcov-report/api/index.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  65. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/index.html +4 -4
  67. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/query.js.html +5 -2
  73. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  79. package/coverage/lcov-report/api/routes/table.js.html +35 -2
  80. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/user.js.html +17 -2
  82. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  83. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  84. package/coverage/lcov-report/automations/actions.js.html +2 -2
  85. package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
  86. package/coverage/lcov-report/automations/bullboard.js.html +71 -20
  87. package/coverage/lcov-report/automations/index.html +33 -48
  88. package/coverage/lcov-report/automations/index.js.html +2 -2
  89. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
  94. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
  96. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/index.html +14 -14
  98. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
  100. package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
  101. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
  106. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  108. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  109. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  111. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  113. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  114. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggers.js.html +22 -10
  116. package/coverage/lcov-report/automations/utils.js.html +42 -12
  117. package/coverage/lcov-report/constants/index.html +5 -5
  118. package/coverage/lcov-report/constants/index.js.html +49 -4
  119. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  120. package/coverage/lcov-report/constants/screens.js.html +1 -1
  121. package/coverage/lcov-report/db/client.js.html +2 -2
  122. package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
  123. package/coverage/lcov-report/db/index.html +2 -2
  124. package/coverage/lcov-report/db/index.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
  126. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  127. package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
  128. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
  129. package/coverage/lcov-report/db/newid.js.html +1 -1
  130. package/coverage/lcov-report/db/utils.js.html +1 -1
  131. package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
  132. package/coverage/lcov-report/events/index.html +6 -6
  133. package/coverage/lcov-report/events/index.js.html +1 -1
  134. package/coverage/lcov-report/events/utils.js.html +5 -5
  135. package/coverage/lcov-report/index.html +98 -83
  136. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  137. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  138. package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
  139. package/coverage/lcov-report/middleware/authorized.js.html +11 -8
  140. package/coverage/lcov-report/middleware/builder.js.html +16 -7
  141. package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
  142. package/coverage/lcov-report/middleware/index.html +23 -23
  143. package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
  144. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  145. package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
  146. package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
  147. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  148. package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +83 -32
  149. package/coverage/lcov-report/threads/index.html +141 -0
  150. package/coverage/lcov-report/threads/index.js.html +260 -0
  151. package/coverage/lcov-report/threads/query.js.html +269 -0
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  154. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  155. package/coverage/lcov-report/utilities/csvParser.js.html +144 -15
  156. package/coverage/lcov-report/utilities/global.js.html +26 -11
  157. package/coverage/lcov-report/utilities/index.html +49 -49
  158. package/coverage/lcov-report/utilities/index.js.html +65 -17
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
  160. package/coverage/lcov-report/utilities/queue/index.html +14 -14
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
  167. package/coverage/lcov-report/utilities/security.js.html +3 -3
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/users.js.html +1 -1
  170. package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
  171. package/coverage/lcov.info +2301 -1599
  172. package/dist/api/controllers/application.js +16 -2
  173. package/dist/api/controllers/auth.js +3 -3
  174. package/dist/api/controllers/datasource.js +47 -16
  175. package/dist/api/controllers/deploy/index.js +2 -0
  176. package/dist/api/controllers/dev.js +4 -1
  177. package/dist/api/controllers/query.js +30 -58
  178. package/dist/api/controllers/row/ExternalRequest.js +37 -14
  179. package/dist/api/controllers/row/external.js +1 -0
  180. package/dist/api/controllers/row/utils.js +6 -12
  181. package/dist/api/controllers/static/index.js +1 -1
  182. package/dist/api/controllers/table/external.js +242 -0
  183. package/dist/api/controllers/table/index.js +49 -123
  184. package/dist/api/controllers/table/internal.js +150 -0
  185. package/dist/api/controllers/table/utils.js +62 -28
  186. package/dist/api/controllers/user.js +123 -11
  187. package/dist/api/routes/query.js +1 -1
  188. package/dist/api/routes/table.js +7 -1
  189. package/dist/api/routes/user.js +2 -1
  190. package/dist/app.js +2 -11
  191. package/dist/automations/bullboard.js +37 -10
  192. package/dist/automations/triggers.js +7 -3
  193. package/dist/automations/utils.js +11 -2
  194. package/dist/constants/index.js +13 -0
  195. package/dist/definitions/datasource.js +4 -0
  196. package/dist/integrations/base/IntegrationBase.js +2 -0
  197. package/dist/integrations/base/datasourcePlus.js +2 -0
  198. package/dist/integrations/base/sql.js +334 -180
  199. package/dist/integrations/base/sqlTable.js +143 -0
  200. package/dist/integrations/base/utils.js +30 -0
  201. package/dist/integrations/microsoftSqlServer.js +117 -9
  202. package/dist/integrations/mysql.js +14 -84
  203. package/dist/integrations/postgres.js +35 -28
  204. package/dist/integrations/utils.js +56 -9
  205. package/dist/middleware/authorized.js +2 -1
  206. package/dist/middleware/builder.js +4 -1
  207. package/dist/package.json +7 -6
  208. package/dist/tests/utilities/TestConfiguration.js +2 -1
  209. package/dist/{automations/thread.js → threads/automation.js} +23 -7
  210. package/dist/threads/index.js +58 -0
  211. package/dist/threads/query.js +61 -0
  212. package/dist/tsconfig.tsbuildinfo +1 -1
  213. package/dist/utilities/csvParser.js +46 -5
  214. package/dist/utilities/global.js +6 -2
  215. package/dist/utilities/index.js +18 -2
  216. package/dist/utilities/queue/inMemoryQueue.js +8 -0
  217. package/dist/utilities/scriptRunner.js +4 -1
  218. package/package.json +8 -7
  219. package/scripts/integrations/mssql/data/Dockerfile +9 -0
  220. package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
  221. package/scripts/integrations/mssql/data/setup.sql +54 -0
  222. package/scripts/integrations/mssql/docker-compose.yaml +12 -0
  223. package/scripts/integrations/mssql/reset.sh +3 -0
  224. package/scripts/likeCypress.ts +33 -0
  225. package/src/api/controllers/application.js +19 -2
  226. package/src/api/controllers/auth.js +3 -0
  227. package/src/api/controllers/datasource.js +56 -16
  228. package/src/api/controllers/deploy/index.js +2 -0
  229. package/src/api/controllers/dev.js +4 -1
  230. package/src/api/controllers/query.js +29 -81
  231. package/src/api/controllers/row/ExternalRequest.ts +47 -16
  232. package/src/api/controllers/row/external.js +2 -0
  233. package/src/api/controllers/row/utils.js +8 -11
  234. package/src/api/controllers/static/index.js +1 -1
  235. package/src/api/controllers/table/external.js +300 -0
  236. package/src/api/controllers/table/index.js +47 -137
  237. package/src/api/controllers/table/internal.js +155 -0
  238. package/src/api/controllers/table/utils.js +74 -33
  239. package/src/api/controllers/user.js +132 -13
  240. package/src/api/routes/query.js +1 -0
  241. package/src/api/routes/table.js +11 -0
  242. package/src/api/routes/tests/datasource.spec.js +2 -2
  243. package/src/api/routes/tests/misc.spec.js +5 -1
  244. package/src/api/routes/tests/query.spec.js +0 -1
  245. package/src/api/routes/user.js +5 -0
  246. package/src/app.ts +2 -10
  247. package/src/automations/bullboard.js +28 -11
  248. package/src/automations/tests/automation.spec.js +3 -4
  249. package/src/automations/triggers.js +7 -3
  250. package/src/automations/utils.js +12 -2
  251. package/src/constants/index.js +15 -0
  252. package/src/definitions/common.ts +7 -1
  253. package/src/definitions/datasource.ts +9 -3
  254. package/src/integrations/airtable.ts +2 -1
  255. package/src/integrations/arangodb.ts +2 -1
  256. package/src/integrations/base/IntegrationBase.ts +6 -0
  257. package/src/integrations/base/datasourcePlus.ts +9 -0
  258. package/src/integrations/base/sql.ts +359 -222
  259. package/src/integrations/base/sqlTable.ts +180 -0
  260. package/src/integrations/base/utils.ts +22 -0
  261. package/src/integrations/couchdb.ts +2 -1
  262. package/src/integrations/dynamodb.ts +2 -1
  263. package/src/integrations/elasticsearch.ts +2 -1
  264. package/src/integrations/microsoftSqlServer.ts +145 -13
  265. package/src/integrations/mongodb.ts +2 -1
  266. package/src/integrations/mysql.ts +20 -94
  267. package/src/integrations/postgres.ts +45 -35
  268. package/src/integrations/rest.ts +2 -1
  269. package/src/integrations/s3.ts +2 -1
  270. package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
  271. package/src/integrations/tests/postgres.spec.js +4 -0
  272. package/src/integrations/utils.ts +60 -8
  273. package/src/middleware/authorized.js +2 -1
  274. package/src/middleware/builder.js +4 -1
  275. package/src/tests/utilities/TestConfiguration.js +2 -1
  276. package/src/{automations/thread.js → threads/automation.js} +24 -7
  277. package/src/threads/index.js +60 -0
  278. package/src/threads/query.js +63 -0
  279. package/src/utilities/csvParser.js +48 -5
  280. package/src/utilities/global.js +7 -2
  281. package/src/utilities/index.js +18 -2
  282. package/src/utilities/queue/inMemoryQueue.js +7 -0
  283. package/src/utilities/scriptRunner.js +4 -1
  284. package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
  285. package/src/utilities/tests/csvParser.spec.js +3 -0
  286. package/tsconfig.json +1 -1
  287. package/builder/assets/index.34964222.js +0 -201
  288. package/builder/assets/index.7469e1e4.css +0 -29
  289. package/builder/assets/vendor.278a305c.js +0 -9
  290. package/builder/assets/vendor.d75d5eb7.css +0 -1
@@ -0,0 +1,980 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for api/controllers/table/external.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../../prettify.css" />
9
+ <link rel="stylesheet" href="../../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../../index.html">All files</a> / <a href="index.html">api/controllers/table</a> external.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">8.27% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>11/133</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/70</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/14</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">8.27% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>11/133</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ </div>
58
+ <div class='status-line low'></div>
59
+ <pre><table class="coverage">
60
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
61
+ <a name='L2'></a><a href='#L2'>2</a>
62
+ <a name='L3'></a><a href='#L3'>3</a>
63
+ <a name='L4'></a><a href='#L4'>4</a>
64
+ <a name='L5'></a><a href='#L5'>5</a>
65
+ <a name='L6'></a><a href='#L6'>6</a>
66
+ <a name='L7'></a><a href='#L7'>7</a>
67
+ <a name='L8'></a><a href='#L8'>8</a>
68
+ <a name='L9'></a><a href='#L9'>9</a>
69
+ <a name='L10'></a><a href='#L10'>10</a>
70
+ <a name='L11'></a><a href='#L11'>11</a>
71
+ <a name='L12'></a><a href='#L12'>12</a>
72
+ <a name='L13'></a><a href='#L13'>13</a>
73
+ <a name='L14'></a><a href='#L14'>14</a>
74
+ <a name='L15'></a><a href='#L15'>15</a>
75
+ <a name='L16'></a><a href='#L16'>16</a>
76
+ <a name='L17'></a><a href='#L17'>17</a>
77
+ <a name='L18'></a><a href='#L18'>18</a>
78
+ <a name='L19'></a><a href='#L19'>19</a>
79
+ <a name='L20'></a><a href='#L20'>20</a>
80
+ <a name='L21'></a><a href='#L21'>21</a>
81
+ <a name='L22'></a><a href='#L22'>22</a>
82
+ <a name='L23'></a><a href='#L23'>23</a>
83
+ <a name='L24'></a><a href='#L24'>24</a>
84
+ <a name='L25'></a><a href='#L25'>25</a>
85
+ <a name='L26'></a><a href='#L26'>26</a>
86
+ <a name='L27'></a><a href='#L27'>27</a>
87
+ <a name='L28'></a><a href='#L28'>28</a>
88
+ <a name='L29'></a><a href='#L29'>29</a>
89
+ <a name='L30'></a><a href='#L30'>30</a>
90
+ <a name='L31'></a><a href='#L31'>31</a>
91
+ <a name='L32'></a><a href='#L32'>32</a>
92
+ <a name='L33'></a><a href='#L33'>33</a>
93
+ <a name='L34'></a><a href='#L34'>34</a>
94
+ <a name='L35'></a><a href='#L35'>35</a>
95
+ <a name='L36'></a><a href='#L36'>36</a>
96
+ <a name='L37'></a><a href='#L37'>37</a>
97
+ <a name='L38'></a><a href='#L38'>38</a>
98
+ <a name='L39'></a><a href='#L39'>39</a>
99
+ <a name='L40'></a><a href='#L40'>40</a>
100
+ <a name='L41'></a><a href='#L41'>41</a>
101
+ <a name='L42'></a><a href='#L42'>42</a>
102
+ <a name='L43'></a><a href='#L43'>43</a>
103
+ <a name='L44'></a><a href='#L44'>44</a>
104
+ <a name='L45'></a><a href='#L45'>45</a>
105
+ <a name='L46'></a><a href='#L46'>46</a>
106
+ <a name='L47'></a><a href='#L47'>47</a>
107
+ <a name='L48'></a><a href='#L48'>48</a>
108
+ <a name='L49'></a><a href='#L49'>49</a>
109
+ <a name='L50'></a><a href='#L50'>50</a>
110
+ <a name='L51'></a><a href='#L51'>51</a>
111
+ <a name='L52'></a><a href='#L52'>52</a>
112
+ <a name='L53'></a><a href='#L53'>53</a>
113
+ <a name='L54'></a><a href='#L54'>54</a>
114
+ <a name='L55'></a><a href='#L55'>55</a>
115
+ <a name='L56'></a><a href='#L56'>56</a>
116
+ <a name='L57'></a><a href='#L57'>57</a>
117
+ <a name='L58'></a><a href='#L58'>58</a>
118
+ <a name='L59'></a><a href='#L59'>59</a>
119
+ <a name='L60'></a><a href='#L60'>60</a>
120
+ <a name='L61'></a><a href='#L61'>61</a>
121
+ <a name='L62'></a><a href='#L62'>62</a>
122
+ <a name='L63'></a><a href='#L63'>63</a>
123
+ <a name='L64'></a><a href='#L64'>64</a>
124
+ <a name='L65'></a><a href='#L65'>65</a>
125
+ <a name='L66'></a><a href='#L66'>66</a>
126
+ <a name='L67'></a><a href='#L67'>67</a>
127
+ <a name='L68'></a><a href='#L68'>68</a>
128
+ <a name='L69'></a><a href='#L69'>69</a>
129
+ <a name='L70'></a><a href='#L70'>70</a>
130
+ <a name='L71'></a><a href='#L71'>71</a>
131
+ <a name='L72'></a><a href='#L72'>72</a>
132
+ <a name='L73'></a><a href='#L73'>73</a>
133
+ <a name='L74'></a><a href='#L74'>74</a>
134
+ <a name='L75'></a><a href='#L75'>75</a>
135
+ <a name='L76'></a><a href='#L76'>76</a>
136
+ <a name='L77'></a><a href='#L77'>77</a>
137
+ <a name='L78'></a><a href='#L78'>78</a>
138
+ <a name='L79'></a><a href='#L79'>79</a>
139
+ <a name='L80'></a><a href='#L80'>80</a>
140
+ <a name='L81'></a><a href='#L81'>81</a>
141
+ <a name='L82'></a><a href='#L82'>82</a>
142
+ <a name='L83'></a><a href='#L83'>83</a>
143
+ <a name='L84'></a><a href='#L84'>84</a>
144
+ <a name='L85'></a><a href='#L85'>85</a>
145
+ <a name='L86'></a><a href='#L86'>86</a>
146
+ <a name='L87'></a><a href='#L87'>87</a>
147
+ <a name='L88'></a><a href='#L88'>88</a>
148
+ <a name='L89'></a><a href='#L89'>89</a>
149
+ <a name='L90'></a><a href='#L90'>90</a>
150
+ <a name='L91'></a><a href='#L91'>91</a>
151
+ <a name='L92'></a><a href='#L92'>92</a>
152
+ <a name='L93'></a><a href='#L93'>93</a>
153
+ <a name='L94'></a><a href='#L94'>94</a>
154
+ <a name='L95'></a><a href='#L95'>95</a>
155
+ <a name='L96'></a><a href='#L96'>96</a>
156
+ <a name='L97'></a><a href='#L97'>97</a>
157
+ <a name='L98'></a><a href='#L98'>98</a>
158
+ <a name='L99'></a><a href='#L99'>99</a>
159
+ <a name='L100'></a><a href='#L100'>100</a>
160
+ <a name='L101'></a><a href='#L101'>101</a>
161
+ <a name='L102'></a><a href='#L102'>102</a>
162
+ <a name='L103'></a><a href='#L103'>103</a>
163
+ <a name='L104'></a><a href='#L104'>104</a>
164
+ <a name='L105'></a><a href='#L105'>105</a>
165
+ <a name='L106'></a><a href='#L106'>106</a>
166
+ <a name='L107'></a><a href='#L107'>107</a>
167
+ <a name='L108'></a><a href='#L108'>108</a>
168
+ <a name='L109'></a><a href='#L109'>109</a>
169
+ <a name='L110'></a><a href='#L110'>110</a>
170
+ <a name='L111'></a><a href='#L111'>111</a>
171
+ <a name='L112'></a><a href='#L112'>112</a>
172
+ <a name='L113'></a><a href='#L113'>113</a>
173
+ <a name='L114'></a><a href='#L114'>114</a>
174
+ <a name='L115'></a><a href='#L115'>115</a>
175
+ <a name='L116'></a><a href='#L116'>116</a>
176
+ <a name='L117'></a><a href='#L117'>117</a>
177
+ <a name='L118'></a><a href='#L118'>118</a>
178
+ <a name='L119'></a><a href='#L119'>119</a>
179
+ <a name='L120'></a><a href='#L120'>120</a>
180
+ <a name='L121'></a><a href='#L121'>121</a>
181
+ <a name='L122'></a><a href='#L122'>122</a>
182
+ <a name='L123'></a><a href='#L123'>123</a>
183
+ <a name='L124'></a><a href='#L124'>124</a>
184
+ <a name='L125'></a><a href='#L125'>125</a>
185
+ <a name='L126'></a><a href='#L126'>126</a>
186
+ <a name='L127'></a><a href='#L127'>127</a>
187
+ <a name='L128'></a><a href='#L128'>128</a>
188
+ <a name='L129'></a><a href='#L129'>129</a>
189
+ <a name='L130'></a><a href='#L130'>130</a>
190
+ <a name='L131'></a><a href='#L131'>131</a>
191
+ <a name='L132'></a><a href='#L132'>132</a>
192
+ <a name='L133'></a><a href='#L133'>133</a>
193
+ <a name='L134'></a><a href='#L134'>134</a>
194
+ <a name='L135'></a><a href='#L135'>135</a>
195
+ <a name='L136'></a><a href='#L136'>136</a>
196
+ <a name='L137'></a><a href='#L137'>137</a>
197
+ <a name='L138'></a><a href='#L138'>138</a>
198
+ <a name='L139'></a><a href='#L139'>139</a>
199
+ <a name='L140'></a><a href='#L140'>140</a>
200
+ <a name='L141'></a><a href='#L141'>141</a>
201
+ <a name='L142'></a><a href='#L142'>142</a>
202
+ <a name='L143'></a><a href='#L143'>143</a>
203
+ <a name='L144'></a><a href='#L144'>144</a>
204
+ <a name='L145'></a><a href='#L145'>145</a>
205
+ <a name='L146'></a><a href='#L146'>146</a>
206
+ <a name='L147'></a><a href='#L147'>147</a>
207
+ <a name='L148'></a><a href='#L148'>148</a>
208
+ <a name='L149'></a><a href='#L149'>149</a>
209
+ <a name='L150'></a><a href='#L150'>150</a>
210
+ <a name='L151'></a><a href='#L151'>151</a>
211
+ <a name='L152'></a><a href='#L152'>152</a>
212
+ <a name='L153'></a><a href='#L153'>153</a>
213
+ <a name='L154'></a><a href='#L154'>154</a>
214
+ <a name='L155'></a><a href='#L155'>155</a>
215
+ <a name='L156'></a><a href='#L156'>156</a>
216
+ <a name='L157'></a><a href='#L157'>157</a>
217
+ <a name='L158'></a><a href='#L158'>158</a>
218
+ <a name='L159'></a><a href='#L159'>159</a>
219
+ <a name='L160'></a><a href='#L160'>160</a>
220
+ <a name='L161'></a><a href='#L161'>161</a>
221
+ <a name='L162'></a><a href='#L162'>162</a>
222
+ <a name='L163'></a><a href='#L163'>163</a>
223
+ <a name='L164'></a><a href='#L164'>164</a>
224
+ <a name='L165'></a><a href='#L165'>165</a>
225
+ <a name='L166'></a><a href='#L166'>166</a>
226
+ <a name='L167'></a><a href='#L167'>167</a>
227
+ <a name='L168'></a><a href='#L168'>168</a>
228
+ <a name='L169'></a><a href='#L169'>169</a>
229
+ <a name='L170'></a><a href='#L170'>170</a>
230
+ <a name='L171'></a><a href='#L171'>171</a>
231
+ <a name='L172'></a><a href='#L172'>172</a>
232
+ <a name='L173'></a><a href='#L173'>173</a>
233
+ <a name='L174'></a><a href='#L174'>174</a>
234
+ <a name='L175'></a><a href='#L175'>175</a>
235
+ <a name='L176'></a><a href='#L176'>176</a>
236
+ <a name='L177'></a><a href='#L177'>177</a>
237
+ <a name='L178'></a><a href='#L178'>178</a>
238
+ <a name='L179'></a><a href='#L179'>179</a>
239
+ <a name='L180'></a><a href='#L180'>180</a>
240
+ <a name='L181'></a><a href='#L181'>181</a>
241
+ <a name='L182'></a><a href='#L182'>182</a>
242
+ <a name='L183'></a><a href='#L183'>183</a>
243
+ <a name='L184'></a><a href='#L184'>184</a>
244
+ <a name='L185'></a><a href='#L185'>185</a>
245
+ <a name='L186'></a><a href='#L186'>186</a>
246
+ <a name='L187'></a><a href='#L187'>187</a>
247
+ <a name='L188'></a><a href='#L188'>188</a>
248
+ <a name='L189'></a><a href='#L189'>189</a>
249
+ <a name='L190'></a><a href='#L190'>190</a>
250
+ <a name='L191'></a><a href='#L191'>191</a>
251
+ <a name='L192'></a><a href='#L192'>192</a>
252
+ <a name='L193'></a><a href='#L193'>193</a>
253
+ <a name='L194'></a><a href='#L194'>194</a>
254
+ <a name='L195'></a><a href='#L195'>195</a>
255
+ <a name='L196'></a><a href='#L196'>196</a>
256
+ <a name='L197'></a><a href='#L197'>197</a>
257
+ <a name='L198'></a><a href='#L198'>198</a>
258
+ <a name='L199'></a><a href='#L199'>199</a>
259
+ <a name='L200'></a><a href='#L200'>200</a>
260
+ <a name='L201'></a><a href='#L201'>201</a>
261
+ <a name='L202'></a><a href='#L202'>202</a>
262
+ <a name='L203'></a><a href='#L203'>203</a>
263
+ <a name='L204'></a><a href='#L204'>204</a>
264
+ <a name='L205'></a><a href='#L205'>205</a>
265
+ <a name='L206'></a><a href='#L206'>206</a>
266
+ <a name='L207'></a><a href='#L207'>207</a>
267
+ <a name='L208'></a><a href='#L208'>208</a>
268
+ <a name='L209'></a><a href='#L209'>209</a>
269
+ <a name='L210'></a><a href='#L210'>210</a>
270
+ <a name='L211'></a><a href='#L211'>211</a>
271
+ <a name='L212'></a><a href='#L212'>212</a>
272
+ <a name='L213'></a><a href='#L213'>213</a>
273
+ <a name='L214'></a><a href='#L214'>214</a>
274
+ <a name='L215'></a><a href='#L215'>215</a>
275
+ <a name='L216'></a><a href='#L216'>216</a>
276
+ <a name='L217'></a><a href='#L217'>217</a>
277
+ <a name='L218'></a><a href='#L218'>218</a>
278
+ <a name='L219'></a><a href='#L219'>219</a>
279
+ <a name='L220'></a><a href='#L220'>220</a>
280
+ <a name='L221'></a><a href='#L221'>221</a>
281
+ <a name='L222'></a><a href='#L222'>222</a>
282
+ <a name='L223'></a><a href='#L223'>223</a>
283
+ <a name='L224'></a><a href='#L224'>224</a>
284
+ <a name='L225'></a><a href='#L225'>225</a>
285
+ <a name='L226'></a><a href='#L226'>226</a>
286
+ <a name='L227'></a><a href='#L227'>227</a>
287
+ <a name='L228'></a><a href='#L228'>228</a>
288
+ <a name='L229'></a><a href='#L229'>229</a>
289
+ <a name='L230'></a><a href='#L230'>230</a>
290
+ <a name='L231'></a><a href='#L231'>231</a>
291
+ <a name='L232'></a><a href='#L232'>232</a>
292
+ <a name='L233'></a><a href='#L233'>233</a>
293
+ <a name='L234'></a><a href='#L234'>234</a>
294
+ <a name='L235'></a><a href='#L235'>235</a>
295
+ <a name='L236'></a><a href='#L236'>236</a>
296
+ <a name='L237'></a><a href='#L237'>237</a>
297
+ <a name='L238'></a><a href='#L238'>238</a>
298
+ <a name='L239'></a><a href='#L239'>239</a>
299
+ <a name='L240'></a><a href='#L240'>240</a>
300
+ <a name='L241'></a><a href='#L241'>241</a>
301
+ <a name='L242'></a><a href='#L242'>242</a>
302
+ <a name='L243'></a><a href='#L243'>243</a>
303
+ <a name='L244'></a><a href='#L244'>244</a>
304
+ <a name='L245'></a><a href='#L245'>245</a>
305
+ <a name='L246'></a><a href='#L246'>246</a>
306
+ <a name='L247'></a><a href='#L247'>247</a>
307
+ <a name='L248'></a><a href='#L248'>248</a>
308
+ <a name='L249'></a><a href='#L249'>249</a>
309
+ <a name='L250'></a><a href='#L250'>250</a>
310
+ <a name='L251'></a><a href='#L251'>251</a>
311
+ <a name='L252'></a><a href='#L252'>252</a>
312
+ <a name='L253'></a><a href='#L253'>253</a>
313
+ <a name='L254'></a><a href='#L254'>254</a>
314
+ <a name='L255'></a><a href='#L255'>255</a>
315
+ <a name='L256'></a><a href='#L256'>256</a>
316
+ <a name='L257'></a><a href='#L257'>257</a>
317
+ <a name='L258'></a><a href='#L258'>258</a>
318
+ <a name='L259'></a><a href='#L259'>259</a>
319
+ <a name='L260'></a><a href='#L260'>260</a>
320
+ <a name='L261'></a><a href='#L261'>261</a>
321
+ <a name='L262'></a><a href='#L262'>262</a>
322
+ <a name='L263'></a><a href='#L263'>263</a>
323
+ <a name='L264'></a><a href='#L264'>264</a>
324
+ <a name='L265'></a><a href='#L265'>265</a>
325
+ <a name='L266'></a><a href='#L266'>266</a>
326
+ <a name='L267'></a><a href='#L267'>267</a>
327
+ <a name='L268'></a><a href='#L268'>268</a>
328
+ <a name='L269'></a><a href='#L269'>269</a>
329
+ <a name='L270'></a><a href='#L270'>270</a>
330
+ <a name='L271'></a><a href='#L271'>271</a>
331
+ <a name='L272'></a><a href='#L272'>272</a>
332
+ <a name='L273'></a><a href='#L273'>273</a>
333
+ <a name='L274'></a><a href='#L274'>274</a>
334
+ <a name='L275'></a><a href='#L275'>275</a>
335
+ <a name='L276'></a><a href='#L276'>276</a>
336
+ <a name='L277'></a><a href='#L277'>277</a>
337
+ <a name='L278'></a><a href='#L278'>278</a>
338
+ <a name='L279'></a><a href='#L279'>279</a>
339
+ <a name='L280'></a><a href='#L280'>280</a>
340
+ <a name='L281'></a><a href='#L281'>281</a>
341
+ <a name='L282'></a><a href='#L282'>282</a>
342
+ <a name='L283'></a><a href='#L283'>283</a>
343
+ <a name='L284'></a><a href='#L284'>284</a>
344
+ <a name='L285'></a><a href='#L285'>285</a>
345
+ <a name='L286'></a><a href='#L286'>286</a>
346
+ <a name='L287'></a><a href='#L287'>287</a>
347
+ <a name='L288'></a><a href='#L288'>288</a>
348
+ <a name='L289'></a><a href='#L289'>289</a>
349
+ <a name='L290'></a><a href='#L290'>290</a>
350
+ <a name='L291'></a><a href='#L291'>291</a>
351
+ <a name='L292'></a><a href='#L292'>292</a>
352
+ <a name='L293'></a><a href='#L293'>293</a>
353
+ <a name='L294'></a><a href='#L294'>294</a>
354
+ <a name='L295'></a><a href='#L295'>295</a>
355
+ <a name='L296'></a><a href='#L296'>296</a>
356
+ <a name='L297'></a><a href='#L297'>297</a>
357
+ <a name='L298'></a><a href='#L298'>298</a>
358
+ <a name='L299'></a><a href='#L299'>299</a>
359
+ <a name='L300'></a><a href='#L300'>300</a>
360
+ <a name='L301'></a><a href='#L301'>301</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">34x</span>
361
+ <span class="cline-any cline-neutral">&nbsp;</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-neutral">&nbsp;</span>
364
+ <span class="cline-any cline-yes">34x</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-neutral">&nbsp;</span>
367
+ <span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-yes">34x</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-neutral">&nbsp;</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
376
+ <span class="cline-any cline-yes">34x</span>
377
+ <span class="cline-any cline-yes">34x</span>
378
+ <span class="cline-any cline-yes">34x</span>
379
+ <span class="cline-any cline-yes">34x</span>
380
+ <span class="cline-any cline-yes">34x</span>
381
+ <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <span class="cline-any cline-neutral">&nbsp;</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-neutral">&nbsp;</span>
385
+ <span class="cline-any cline-neutral">&nbsp;</span>
386
+ <span class="cline-any cline-neutral">&nbsp;</span>
387
+ <span class="cline-any cline-neutral">&nbsp;</span>
388
+ <span class="cline-any cline-neutral">&nbsp;</span>
389
+ <span class="cline-any cline-no">&nbsp;</span>
390
+ <span class="cline-any cline-neutral">&nbsp;</span>
391
+ <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-neutral">&nbsp;</span>
393
+ <span class="cline-any cline-neutral">&nbsp;</span>
394
+ <span class="cline-any cline-neutral">&nbsp;</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</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>
400
+ <span class="cline-any cline-no">&nbsp;</span>
401
+ <span class="cline-any cline-no">&nbsp;</span>
402
+ <span class="cline-any cline-neutral">&nbsp;</span>
403
+ <span class="cline-any cline-no">&nbsp;</span>
404
+ <span class="cline-any cline-neutral">&nbsp;</span>
405
+ <span class="cline-any cline-neutral">&nbsp;</span>
406
+ <span class="cline-any cline-neutral">&nbsp;</span>
407
+ <span class="cline-any cline-no">&nbsp;</span>
408
+ <span class="cline-any cline-neutral">&nbsp;</span>
409
+ <span class="cline-any cline-no">&nbsp;</span>
410
+ <span class="cline-any cline-no">&nbsp;</span>
411
+ <span class="cline-any cline-neutral">&nbsp;</span>
412
+ <span class="cline-any cline-neutral">&nbsp;</span>
413
+ <span class="cline-any cline-neutral">&nbsp;</span>
414
+ <span class="cline-any cline-no">&nbsp;</span>
415
+ <span class="cline-any cline-no">&nbsp;</span>
416
+ <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-no">&nbsp;</span>
418
+ <span class="cline-any cline-no">&nbsp;</span>
419
+ <span class="cline-any cline-no">&nbsp;</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-no">&nbsp;</span>
422
+ <span class="cline-any cline-neutral">&nbsp;</span>
423
+ <span class="cline-any cline-neutral">&nbsp;</span>
424
+ <span class="cline-any cline-no">&nbsp;</span>
425
+ <span class="cline-any cline-neutral">&nbsp;</span>
426
+ <span class="cline-any cline-neutral">&nbsp;</span>
427
+ <span class="cline-any cline-neutral">&nbsp;</span>
428
+ <span class="cline-any cline-no">&nbsp;</span>
429
+ <span class="cline-any cline-neutral">&nbsp;</span>
430
+ <span class="cline-any cline-neutral">&nbsp;</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-neutral">&nbsp;</span>
433
+ <span class="cline-any cline-neutral">&nbsp;</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-no">&nbsp;</span>
437
+ <span class="cline-any cline-no">&nbsp;</span>
438
+ <span class="cline-any cline-neutral">&nbsp;</span>
439
+ <span class="cline-any cline-no">&nbsp;</span>
440
+ <span class="cline-any cline-no">&nbsp;</span>
441
+ <span class="cline-any cline-neutral">&nbsp;</span>
442
+ <span class="cline-any cline-no">&nbsp;</span>
443
+ <span class="cline-any cline-neutral">&nbsp;</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-no">&nbsp;</span>
447
+ <span class="cline-any cline-no">&nbsp;</span>
448
+ <span class="cline-any cline-neutral">&nbsp;</span>
449
+ <span class="cline-any cline-no">&nbsp;</span>
450
+ <span class="cline-any cline-neutral">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-neutral">&nbsp;</span>
454
+ <span class="cline-any cline-neutral">&nbsp;</span>
455
+ <span class="cline-any cline-no">&nbsp;</span>
456
+ <span class="cline-any cline-no">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-no">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-neutral">&nbsp;</span>
465
+ <span class="cline-any cline-neutral">&nbsp;</span>
466
+ <span class="cline-any cline-neutral">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-neutral">&nbsp;</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-neutral">&nbsp;</span>
471
+ <span class="cline-any cline-neutral">&nbsp;</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-neutral">&nbsp;</span>
474
+ <span class="cline-any cline-neutral">&nbsp;</span>
475
+ <span class="cline-any cline-no">&nbsp;</span>
476
+ <span class="cline-any cline-no">&nbsp;</span>
477
+ <span class="cline-any cline-no">&nbsp;</span>
478
+ <span class="cline-any cline-no">&nbsp;</span>
479
+ <span class="cline-any cline-no">&nbsp;</span>
480
+ <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-neutral">&nbsp;</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
483
+ <span class="cline-any cline-no">&nbsp;</span>
484
+ <span class="cline-any cline-no">&nbsp;</span>
485
+ <span class="cline-any cline-neutral">&nbsp;</span>
486
+ <span class="cline-any cline-no">&nbsp;</span>
487
+ <span class="cline-any cline-no">&nbsp;</span>
488
+ <span class="cline-any cline-no">&nbsp;</span>
489
+ <span class="cline-any cline-no">&nbsp;</span>
490
+ <span class="cline-any cline-no">&nbsp;</span>
491
+ <span class="cline-any cline-neutral">&nbsp;</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-neutral">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-no">&nbsp;</span>
496
+ <span class="cline-any cline-neutral">&nbsp;</span>
497
+ <span class="cline-any cline-no">&nbsp;</span>
498
+ <span class="cline-any cline-no">&nbsp;</span>
499
+ <span class="cline-any cline-no">&nbsp;</span>
500
+ <span class="cline-any cline-neutral">&nbsp;</span>
501
+ <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-no">&nbsp;</span>
505
+ <span class="cline-any cline-no">&nbsp;</span>
506
+ <span class="cline-any cline-no">&nbsp;</span>
507
+ <span class="cline-any cline-neutral">&nbsp;</span>
508
+ <span class="cline-any cline-no">&nbsp;</span>
509
+ <span class="cline-any cline-neutral">&nbsp;</span>
510
+ <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-no">&nbsp;</span>
512
+ <span class="cline-any cline-no">&nbsp;</span>
513
+ <span class="cline-any cline-no">&nbsp;</span>
514
+ <span class="cline-any cline-neutral">&nbsp;</span>
515
+ <span class="cline-any cline-neutral">&nbsp;</span>
516
+ <span class="cline-any cline-neutral">&nbsp;</span>
517
+ <span class="cline-any cline-no">&nbsp;</span>
518
+ <span class="cline-any cline-neutral">&nbsp;</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-yes">34x</span>
521
+ <span class="cline-any cline-no">&nbsp;</span>
522
+ <span class="cline-any cline-no">&nbsp;</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-no">&nbsp;</span>
525
+ <span class="cline-any cline-no">&nbsp;</span>
526
+ <span class="cline-any cline-no">&nbsp;</span>
527
+ <span class="cline-any cline-neutral">&nbsp;</span>
528
+ <span class="cline-any cline-neutral">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-neutral">&nbsp;</span>
532
+ <span class="cline-any cline-neutral">&nbsp;</span>
533
+ <span class="cline-any cline-no">&nbsp;</span>
534
+ <span class="cline-any cline-no">&nbsp;</span>
535
+ <span class="cline-any cline-neutral">&nbsp;</span>
536
+ <span class="cline-any cline-neutral">&nbsp;</span>
537
+ <span class="cline-any cline-no">&nbsp;</span>
538
+ <span class="cline-any cline-no">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-no">&nbsp;</span>
542
+ <span class="cline-any cline-no">&nbsp;</span>
543
+ <span class="cline-any cline-no">&nbsp;</span>
544
+ <span class="cline-any cline-no">&nbsp;</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-no">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-no">&nbsp;</span>
550
+ <span class="cline-any cline-no">&nbsp;</span>
551
+ <span class="cline-any cline-no">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-no">&nbsp;</span>
554
+ <span class="cline-any cline-no">&nbsp;</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-no">&nbsp;</span>
557
+ <span class="cline-any cline-no">&nbsp;</span>
558
+ <span class="cline-any cline-no">&nbsp;</span>
559
+ <span class="cline-any cline-no">&nbsp;</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-neutral">&nbsp;</span>
562
+ <span class="cline-any cline-neutral">&nbsp;</span>
563
+ <span class="cline-any cline-neutral">&nbsp;</span>
564
+ <span class="cline-any cline-neutral">&nbsp;</span>
565
+ <span class="cline-any cline-no">&nbsp;</span>
566
+ <span class="cline-any cline-no">&nbsp;</span>
567
+ <span class="cline-any cline-neutral">&nbsp;</span>
568
+ <span class="cline-any cline-no">&nbsp;</span>
569
+ <span class="cline-any cline-no">&nbsp;</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-neutral">&nbsp;</span>
572
+ <span class="cline-any cline-no">&nbsp;</span>
573
+ <span class="cline-any cline-no">&nbsp;</span>
574
+ <span class="cline-any cline-neutral">&nbsp;</span>
575
+ <span class="cline-any cline-neutral">&nbsp;</span>
576
+ <span class="cline-any cline-neutral">&nbsp;</span>
577
+ <span class="cline-any cline-neutral">&nbsp;</span>
578
+ <span class="cline-any cline-neutral">&nbsp;</span>
579
+ <span class="cline-any cline-no">&nbsp;</span>
580
+ <span class="cline-any cline-no">&nbsp;</span>
581
+ <span class="cline-any cline-no">&nbsp;</span>
582
+ <span class="cline-any cline-neutral">&nbsp;</span>
583
+ <span class="cline-any cline-no">&nbsp;</span>
584
+ <span class="cline-any cline-no">&nbsp;</span>
585
+ <span class="cline-any cline-neutral">&nbsp;</span>
586
+ <span class="cline-any cline-neutral">&nbsp;</span>
587
+ <span class="cline-any cline-no">&nbsp;</span>
588
+ <span class="cline-any cline-no">&nbsp;</span>
589
+ <span class="cline-any cline-neutral">&nbsp;</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span>
591
+ <span class="cline-any cline-no">&nbsp;</span>
592
+ <span class="cline-any cline-no">&nbsp;</span>
593
+ <span class="cline-any cline-neutral">&nbsp;</span>
594
+ <span class="cline-any cline-neutral">&nbsp;</span>
595
+ <span class="cline-any cline-no">&nbsp;</span>
596
+ <span class="cline-any cline-neutral">&nbsp;</span>
597
+ <span class="cline-any cline-no">&nbsp;</span>
598
+ <span class="cline-any cline-neutral">&nbsp;</span>
599
+ <span class="cline-any cline-neutral">&nbsp;</span>
600
+ <span class="cline-any cline-no">&nbsp;</span>
601
+ <span class="cline-any cline-neutral">&nbsp;</span>
602
+ <span class="cline-any cline-no">&nbsp;</span>
603
+ <span class="cline-any cline-no">&nbsp;</span>
604
+ <span class="cline-any cline-no">&nbsp;</span>
605
+ <span class="cline-any cline-neutral">&nbsp;</span>
606
+ <span class="cline-any cline-neutral">&nbsp;</span>
607
+ <span class="cline-any cline-no">&nbsp;</span>
608
+ <span class="cline-any cline-neutral">&nbsp;</span>
609
+ <span class="cline-any cline-neutral">&nbsp;</span>
610
+ <span class="cline-any cline-neutral">&nbsp;</span>
611
+ <span class="cline-any cline-no">&nbsp;</span>
612
+ <span class="cline-any cline-no">&nbsp;</span>
613
+ <span class="cline-any cline-no">&nbsp;</span>
614
+ <span class="cline-any cline-neutral">&nbsp;</span>
615
+ <span class="cline-any cline-neutral">&nbsp;</span>
616
+ <span class="cline-any cline-neutral">&nbsp;</span>
617
+ <span class="cline-any cline-neutral">&nbsp;</span>
618
+ <span class="cline-any cline-no">&nbsp;</span>
619
+ <span class="cline-any cline-no">&nbsp;</span>
620
+ <span class="cline-any cline-neutral">&nbsp;</span>
621
+ <span class="cline-any cline-no">&nbsp;</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-neutral">&nbsp;</span>
624
+ <span class="cline-any cline-yes">34x</span>
625
+ <span class="cline-any cline-no">&nbsp;</span>
626
+ <span class="cline-any cline-no">&nbsp;</span>
627
+ <span class="cline-any cline-no">&nbsp;</span>
628
+ <span class="cline-any cline-neutral">&nbsp;</span>
629
+ <span class="cline-any cline-no">&nbsp;</span>
630
+ <span class="cline-any cline-no">&nbsp;</span>
631
+ <span class="cline-any cline-no">&nbsp;</span>
632
+ <span class="cline-any cline-neutral">&nbsp;</span>
633
+ <span class="cline-any cline-no">&nbsp;</span>
634
+ <span class="cline-any cline-no">&nbsp;</span>
635
+ <span class="cline-any cline-neutral">&nbsp;</span>
636
+ <span class="cline-any cline-no">&nbsp;</span>
637
+ <span class="cline-any cline-neutral">&nbsp;</span>
638
+ <span class="cline-any cline-no">&nbsp;</span>
639
+ <span class="cline-any cline-no">&nbsp;</span>
640
+ <span class="cline-any cline-neutral">&nbsp;</span>
641
+ <span class="cline-any cline-no">&nbsp;</span>
642
+ <span class="cline-any cline-neutral">&nbsp;</span>
643
+ <span class="cline-any cline-neutral">&nbsp;</span>
644
+ <span class="cline-any cline-yes">34x</span>
645
+ <span class="cline-any cline-no">&nbsp;</span>
646
+ <span class="cline-any cline-no">&nbsp;</span>
647
+ <span class="cline-any cline-no">&nbsp;</span>
648
+ <span class="cline-any cline-no">&nbsp;</span>
649
+ <span class="cline-any cline-no">&nbsp;</span>
650
+ <span class="cline-any cline-neutral">&nbsp;</span>
651
+ <span class="cline-any cline-no">&nbsp;</span>
652
+ <span class="cline-any cline-neutral">&nbsp;</span>
653
+ <span class="cline-any cline-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-neutral">&nbsp;</span>
655
+ <span class="cline-any cline-no">&nbsp;</span>
656
+ <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-neutral">&nbsp;</span>
658
+ <span class="cline-any cline-no">&nbsp;</span>
659
+ <span class="cline-any cline-neutral">&nbsp;</span>
660
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const CouchDB = require("../../../db")
661
+ const {
662
+ buildExternalTableId,
663
+ breakExternalTableId,
664
+ } = require("../../../integrations/utils")
665
+ const {
666
+ getTable,
667
+ generateForeignKey,
668
+ generateJunctionTableName,
669
+ foreignKeyStructure,
670
+ hasTypeChanged,
671
+ } = require("./utils")
672
+ const {
673
+ DataSourceOperation,
674
+ FieldTypes,
675
+ RelationshipTypes,
676
+ } = require("../../../constants")
677
+ const { makeExternalQuery } = require("../../../integrations/base/utils")
678
+ const { cloneDeep } = require("lodash/fp")
679
+ const csvParser = require("../../../utilities/csvParser")
680
+ const { handleRequest } = require("../row/external")
681
+ &nbsp;
682
+ async function <span class="fstat-no" title="function not covered" >makeTableRequest(</span>
683
+ datasource,
684
+ operation,
685
+ table,
686
+ tables,
687
+ oldTable = <span class="branch-0 cbranch-no" title="branch not covered" >null</span>
688
+ ) {
689
+ const json = <span class="cstat-no" title="statement not covered" >{</span>
690
+ endpoint: {
691
+ datasourceId: datasource._id,
692
+ entityId: table._id,
693
+ operation,
694
+ },
695
+ meta: {
696
+ tables,
697
+ },
698
+ table,
699
+ }
700
+ <span class="cstat-no" title="statement not covered" > if (oldTable) {</span>
701
+ <span class="cstat-no" title="statement not covered" > json.meta.table = oldTable</span>
702
+ }
703
+ <span class="cstat-no" title="statement not covered" > return makeExternalQuery(datasource, json)</span>
704
+ }
705
+ &nbsp;
706
+ function <span class="fstat-no" title="function not covered" >cleanupRelationships(</span>table, tables, oldTable = <span class="branch-0 cbranch-no" title="branch not covered" >null)</span> {
707
+ const tableToIterate = <span class="cstat-no" title="statement not covered" >oldTable ? oldTable : table</span>
708
+ // clean up relationships in couch table schemas
709
+ <span class="cstat-no" title="statement not covered" > for (let [key, schema] of Object.entries(tableToIterate.schema)) {</span>
710
+ <span class="cstat-no" title="statement not covered" > if (</span>
711
+ schema.type === FieldTypes.LINK &amp;&amp;
712
+ (!oldTable || table.schema[key] == null)
713
+ ) {
714
+ const relatedTable = <span class="cstat-no" title="statement not covered" >Object.values(tables).find(</span>
715
+ <span class="fstat-no" title="function not covered" > ta</span>ble =&gt; <span class="cstat-no" title="statement not covered" >table._id === schema.tableId</span>
716
+ )
717
+ const foreignKey = <span class="cstat-no" title="statement not covered" >schema.foreignKey</span>
718
+ <span class="cstat-no" title="statement not covered" > if (!relatedTable || !foreignKey) {</span>
719
+ <span class="cstat-no" title="statement not covered" > continue</span>
720
+ }
721
+ <span class="cstat-no" title="statement not covered" > for (let [relatedKey, relatedSchema] of Object.entries(</span>
722
+ relatedTable.schema
723
+ )) {
724
+ <span class="cstat-no" title="statement not covered" > if (</span>
725
+ relatedSchema.type === FieldTypes.LINK &amp;&amp;
726
+ relatedSchema.fieldName === foreignKey
727
+ ) {
728
+ <span class="cstat-no" title="statement not covered" > delete relatedTable.schema[relatedKey]</span>
729
+ }
730
+ }
731
+ }
732
+ }
733
+ }
734
+ &nbsp;
735
+ function <span class="fstat-no" title="function not covered" >getDatasourceId(</span>table) {
736
+ <span class="cstat-no" title="statement not covered" > if (!table) {</span>
737
+ <span class="cstat-no" title="statement not covered" > throw "No table supplied"</span>
738
+ }
739
+ <span class="cstat-no" title="statement not covered" > if (table.sourceId) {</span>
740
+ <span class="cstat-no" title="statement not covered" > return table.sourceId</span>
741
+ }
742
+ <span class="cstat-no" title="statement not covered" > return breakExternalTableId(table._id).datasourceId</span>
743
+ }
744
+ &nbsp;
745
+ function <span class="fstat-no" title="function not covered" >otherRelationshipType(</span>type) {
746
+ <span class="cstat-no" title="statement not covered" > if (type === RelationshipTypes.MANY_TO_MANY) {</span>
747
+ <span class="cstat-no" title="statement not covered" > return RelationshipTypes.MANY_TO_MANY</span>
748
+ }
749
+ <span class="cstat-no" title="statement not covered" > return type === RelationshipTypes.ONE_TO_MANY</span>
750
+ ? RelationshipTypes.MANY_TO_ONE
751
+ : RelationshipTypes.ONE_TO_MANY
752
+ }
753
+ &nbsp;
754
+ function <span class="fstat-no" title="function not covered" >generateManyLinkSchema(</span>datasource, column, table, relatedTable) {
755
+ const primary = <span class="cstat-no" title="statement not covered" >table.name + table.primary[0]</span>
756
+ const relatedPrimary = <span class="cstat-no" title="statement not covered" >relatedTable.name + relatedTable.primary[0]</span>
757
+ const jcTblName = <span class="cstat-no" title="statement not covered" >generateJunctionTableName(column, table, relatedTable)</span>
758
+ // first create the new table
759
+ const junctionTable = <span class="cstat-no" title="statement not covered" >{</span>
760
+ _id: buildExternalTableId(datasource._id, jcTblName),
761
+ name: jcTblName,
762
+ primary: [primary, relatedPrimary],
763
+ constrained: [primary, relatedPrimary],
764
+ schema: {
765
+ [primary]: foreignKeyStructure(primary, {
766
+ toTable: table.name,
767
+ toKey: table.primary[0],
768
+ }),
769
+ [relatedPrimary]: foreignKeyStructure(relatedPrimary, {
770
+ toTable: relatedTable.name,
771
+ toKey: relatedTable.primary[0],
772
+ }),
773
+ },
774
+ }
775
+ <span class="cstat-no" title="statement not covered" > column.through = junctionTable._id</span>
776
+ <span class="cstat-no" title="statement not covered" > column.throughFrom = primary</span>
777
+ <span class="cstat-no" title="statement not covered" > column.throughTo = relatedPrimary</span>
778
+ <span class="cstat-no" title="statement not covered" > column.fieldName = relatedPrimary</span>
779
+ <span class="cstat-no" title="statement not covered" > return junctionTable</span>
780
+ }
781
+ &nbsp;
782
+ function <span class="fstat-no" title="function not covered" >generateLinkSchema(</span>column, table, relatedTable, type) {
783
+ const isOneSide = <span class="cstat-no" title="statement not covered" >type === RelationshipTypes.ONE_TO_MANY</span>
784
+ const primary = <span class="cstat-no" title="statement not covered" >isOneSide ? relatedTable.primary[0] : table.primary[0]</span>
785
+ // generate a foreign key
786
+ const foreignKey = <span class="cstat-no" title="statement not covered" >generateForeignKey(column, relatedTable)</span>
787
+ <span class="cstat-no" title="statement not covered" > column.relationshipType = type</span>
788
+ <span class="cstat-no" title="statement not covered" > column.foreignKey = isOneSide ? foreignKey : primary</span>
789
+ <span class="cstat-no" title="statement not covered" > column.fieldName = isOneSide ? primary : foreignKey</span>
790
+ <span class="cstat-no" title="statement not covered" > return foreignKey</span>
791
+ }
792
+ &nbsp;
793
+ function <span class="fstat-no" title="function not covered" >generateRelatedSchema(</span>linkColumn, table, relatedTable, columnName) {
794
+ // generate column for other table
795
+ const relatedSchema = <span class="cstat-no" title="statement not covered" >cloneDeep(linkColumn)</span>
796
+ // swap them from the main link
797
+ <span class="cstat-no" title="statement not covered" > if (linkColumn.foreignKey) {</span>
798
+ <span class="cstat-no" title="statement not covered" > relatedSchema.fieldName = linkColumn.foreignKey</span>
799
+ <span class="cstat-no" title="statement not covered" > relatedSchema.foreignKey = linkColumn.fieldName</span>
800
+ }
801
+ // is many to many
802
+ else {
803
+ // don't need to copy through, already got it
804
+ <span class="cstat-no" title="statement not covered" > relatedSchema.fieldName = linkColumn.throughFrom</span>
805
+ <span class="cstat-no" title="statement not covered" > relatedSchema.throughTo = linkColumn.throughFrom</span>
806
+ <span class="cstat-no" title="statement not covered" > relatedSchema.throughFrom = linkColumn.throughTo</span>
807
+ }
808
+ <span class="cstat-no" title="statement not covered" > relatedSchema.relationshipType = otherRelationshipType(</span>
809
+ linkColumn.relationshipType
810
+ )
811
+ <span class="cstat-no" title="statement not covered" > relatedSchema.tableId = relatedTable._id</span>
812
+ <span class="cstat-no" title="statement not covered" > relatedSchema.name = columnName</span>
813
+ <span class="cstat-no" title="statement not covered" > table.schema[columnName] = relatedSchema</span>
814
+ }
815
+ &nbsp;
816
+ function <span class="fstat-no" title="function not covered" >isRelationshipSetup(</span>column) {
817
+ <span class="cstat-no" title="statement not covered" > return column.foreignKey || column.through</span>
818
+ }
819
+ &nbsp;
820
+ exports.save = <span class="fstat-no" title="function not covered" >as</span>ync function (ctx) {
821
+ const appId = <span class="cstat-no" title="statement not covered" >ctx.appId</span>
822
+ const table = <span class="cstat-no" title="statement not covered" >ctx.request.body</span>
823
+ // can't do this
824
+ <span class="cstat-no" title="statement not covered" > delete table.dataImport</span>
825
+ const datasourceId = <span class="cstat-no" title="statement not covered" >getDatasourceId(ctx.request.body)</span>
826
+ let tableToSave = <span class="cstat-no" title="statement not covered" >{</span>
827
+ type: "table",
828
+ _id: buildExternalTableId(datasourceId, table.name),
829
+ ...table,
830
+ }
831
+ &nbsp;
832
+ let oldTable
833
+ <span class="cstat-no" title="statement not covered" > if (ctx.request.body &amp;&amp; ctx.request.body._id) {</span>
834
+ <span class="cstat-no" title="statement not covered" > oldTable = await getTable(appId, ctx.request.body._id)</span>
835
+ }
836
+ &nbsp;
837
+ <span class="cstat-no" title="statement not covered" > if (hasTypeChanged(tableToSave, oldTable)) {</span>
838
+ <span class="cstat-no" title="statement not covered" > ctx.throw(400, "A column type has changed.")</span>
839
+ }
840
+ &nbsp;
841
+ const db = <span class="cstat-no" title="statement not covered" >new CouchDB(appId)</span>
842
+ const datasource = <span class="cstat-no" title="statement not covered" >await db.get(datasourceId)</span>
843
+ const oldTables = <span class="cstat-no" title="statement not covered" >cloneDeep(datasource.entities)</span>
844
+ const tables = <span class="cstat-no" title="statement not covered" >datasource.entities</span>
845
+ &nbsp;
846
+ const extraTablesToUpdate = <span class="cstat-no" title="statement not covered" >[]</span>
847
+ &nbsp;
848
+ // check if relations need setup
849
+ <span class="cstat-no" title="statement not covered" > for (let schema of Object.values(tableToSave.schema)) {</span>
850
+ <span class="cstat-no" title="statement not covered" > if (schema.type !== FieldTypes.LINK || isRelationshipSetup(schema)) {</span>
851
+ <span class="cstat-no" title="statement not covered" > continue</span>
852
+ }
853
+ const relatedTable = <span class="cstat-no" title="statement not covered" >Object.values(tables).find(</span>
854
+ <span class="fstat-no" title="function not covered" > ta</span>ble =&gt; <span class="cstat-no" title="statement not covered" >table._id === schema.tableId</span>
855
+ )
856
+ const relatedColumnName = <span class="cstat-no" title="statement not covered" >schema.fieldName</span>
857
+ const relationType = <span class="cstat-no" title="statement not covered" >schema.relationshipType</span>
858
+ <span class="cstat-no" title="statement not covered" > if (relationType === RelationshipTypes.MANY_TO_MANY) {</span>
859
+ const junctionTable = <span class="cstat-no" title="statement not covered" >generateManyLinkSchema(</span>
860
+ datasource,
861
+ schema,
862
+ table,
863
+ relatedTable
864
+ )
865
+ <span class="cstat-no" title="statement not covered" > if (tables[junctionTable.name]) {</span>
866
+ <span class="cstat-no" title="statement not covered" > throw "Junction table already exists, cannot create another relationship."</span>
867
+ }
868
+ <span class="cstat-no" title="statement not covered" > tables[junctionTable.name] = junctionTable</span>
869
+ <span class="cstat-no" title="statement not covered" > extraTablesToUpdate.push(junctionTable)</span>
870
+ } else {
871
+ const fkTable =
872
+ <span class="cstat-no" title="statement not covered" > relationType === RelationshipTypes.ONE_TO_MANY ? table : relatedTable</span>
873
+ const foreignKey = <span class="cstat-no" title="statement not covered" >generateLinkSchema(</span>
874
+ schema,
875
+ table,
876
+ relatedTable,
877
+ relationType
878
+ )
879
+ <span class="cstat-no" title="statement not covered" > fkTable.schema[foreignKey] = foreignKeyStructure(foreignKey)</span>
880
+ <span class="cstat-no" title="statement not covered" > if (fkTable.constrained == null) {</span>
881
+ <span class="cstat-no" title="statement not covered" > fkTable.constrained = []</span>
882
+ }
883
+ <span class="cstat-no" title="statement not covered" > if (fkTable.constrained.indexOf(foreignKey) === -1) {</span>
884
+ <span class="cstat-no" title="statement not covered" > fkTable.constrained.push(foreignKey)</span>
885
+ }
886
+ // foreign key is in other table, need to save it to external
887
+ <span class="cstat-no" title="statement not covered" > if (fkTable._id !== table._id) {</span>
888
+ <span class="cstat-no" title="statement not covered" > extraTablesToUpdate.push(fkTable)</span>
889
+ }
890
+ }
891
+ <span class="cstat-no" title="statement not covered" > generateRelatedSchema(schema, relatedTable, table, relatedColumnName)</span>
892
+ <span class="cstat-no" title="statement not covered" > schema.main = true</span>
893
+ }
894
+ &nbsp;
895
+ <span class="cstat-no" title="statement not covered" > cleanupRelationships(tableToSave, tables, oldTable)</span>
896
+ &nbsp;
897
+ const operation = <span class="cstat-no" title="statement not covered" >oldTable</span>
898
+ ? DataSourceOperation.UPDATE_TABLE
899
+ : DataSourceOperation.CREATE_TABLE
900
+ <span class="cstat-no" title="statement not covered" > await makeTableRequest(datasource, operation, tableToSave, tables, oldTable)</span>
901
+ // update any extra tables (like foreign keys in other tables)
902
+ <span class="cstat-no" title="statement not covered" > for (let extraTable of extraTablesToUpdate) {</span>
903
+ const oldExtraTable = <span class="cstat-no" title="statement not covered" >oldTables[extraTable.name]</span>
904
+ let op = <span class="cstat-no" title="statement not covered" >oldExtraTable</span>
905
+ ? DataSourceOperation.UPDATE_TABLE
906
+ : DataSourceOperation.CREATE_TABLE
907
+ <span class="cstat-no" title="statement not covered" > await makeTableRequest(datasource, op, extraTable, tables, oldExtraTable)</span>
908
+ }
909
+ &nbsp;
910
+ // make sure the constrained list, all still exist
911
+ <span class="cstat-no" title="statement not covered" > if (Array.isArray(tableToSave.constrained)) {</span>
912
+ <span class="cstat-no" title="statement not covered" > tableToSave.constrained = tableToSave.constrained.filter(<span class="fstat-no" title="function not covered" >co</span>nstraint =&gt;</span>
913
+ <span class="cstat-no" title="statement not covered" > Object.keys(tableToSave.schema).includes(constraint)</span>
914
+ )
915
+ }
916
+ &nbsp;
917
+ // store it into couch now for budibase reference
918
+ <span class="cstat-no" title="statement not covered" > datasource.entities[tableToSave.name] = tableToSave</span>
919
+ <span class="cstat-no" title="statement not covered" > await db.put(datasource)</span>
920
+ &nbsp;
921
+ <span class="cstat-no" title="statement not covered" > return tableToSave</span>
922
+ }
923
+ &nbsp;
924
+ exports.destroy = <span class="fstat-no" title="function not covered" >as</span>ync function (ctx) {
925
+ const appId = <span class="cstat-no" title="statement not covered" >ctx.appId</span>
926
+ const tableToDelete = <span class="cstat-no" title="statement not covered" >await getTable(appId, ctx.params.tableId)</span>
927
+ const datasourceId = <span class="cstat-no" title="statement not covered" >getDatasourceId(tableToDelete)</span>
928
+ &nbsp;
929
+ const db = <span class="cstat-no" title="statement not covered" >new CouchDB(appId)</span>
930
+ const datasource = <span class="cstat-no" title="statement not covered" >await db.get(datasourceId)</span>
931
+ const tables = <span class="cstat-no" title="statement not covered" >datasource.entities</span>
932
+ &nbsp;
933
+ const operation = <span class="cstat-no" title="statement not covered" >DataSourceOperation.DELETE_TABLE</span>
934
+ <span class="cstat-no" title="statement not covered" > await makeTableRequest(datasource, operation, tableToDelete, tables)</span>
935
+ &nbsp;
936
+ <span class="cstat-no" title="statement not covered" > cleanupRelationships(tableToDelete, tables)</span>
937
+ &nbsp;
938
+ <span class="cstat-no" title="statement not covered" > delete datasource.entities[tableToDelete.name]</span>
939
+ <span class="cstat-no" title="statement not covered" > await db.put(datasource)</span>
940
+ &nbsp;
941
+ <span class="cstat-no" title="statement not covered" > return tableToDelete</span>
942
+ }
943
+ &nbsp;
944
+ exports.bulkImport = <span class="fstat-no" title="function not covered" >as</span>ync function (ctx) {
945
+ const appId = <span class="cstat-no" title="statement not covered" >ctx.appId</span>
946
+ const table = <span class="cstat-no" title="statement not covered" >await getTable(appId, ctx.params.tableId)</span>
947
+ const { dataImport } = <span class="cstat-no" title="statement not covered" >ctx.request.body</span>
948
+ <span class="cstat-no" title="statement not covered" > if (!dataImport || !dataImport.schema || !dataImport.csvString) {</span>
949
+ <span class="cstat-no" title="statement not covered" > ctx.throw(400, "Provided data import information is invalid.")</span>
950
+ }
951
+ const rows = <span class="cstat-no" title="statement not covered" >await csvParser.transform({</span>
952
+ ...dataImport,
953
+ existingTable: table,
954
+ })
955
+ <span class="cstat-no" title="statement not covered" > await handleRequest(appId, DataSourceOperation.BULK_CREATE, table._id, {</span>
956
+ rows,
957
+ })
958
+ <span class="cstat-no" title="statement not covered" > return table</span>
959
+ }
960
+ &nbsp;</pre></td></tr></table></pre>
961
+
962
+ <div class='push'></div><!-- for sticky footer -->
963
+ </div><!-- /wrapper -->
964
+ <div class='footer quiet pad2 space-top1 center small'>
965
+ Code coverage generated by
966
+ <a href="https://istanbul.js.org/" target="_blank">istanbul</a>
967
+ at Mon Nov 22 2021 10:23:31 GMT+0000 (Coordinated Universal Time)
968
+ </div>
969
+ </div>
970
+ <script src="../../../prettify.js"></script>
971
+ <script>
972
+ window.onload = function () {
973
+ prettyPrint();
974
+ };
975
+ </script>
976
+ <script src="../../../sorter.js"></script>
977
+ <script src="../../../block-navigation.js"></script>
978
+ </body>
979
+ </html>
980
+