@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,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const knex_1 = require("knex");
4
+ const datasource_1 = require("../../definitions/datasource");
5
+ const utils_1 = require("../utils");
6
+ const { FieldTypes, RelationshipTypes } = require("../../constants");
7
+ function generateSchema(schema, table, tables, oldTable = null) {
8
+ let primaryKey = table && table.primary ? table.primary[0] : null;
9
+ const columns = Object.values(table.schema);
10
+ // all columns in a junction table will be meta
11
+ let metaCols = columns.filter(col => col.meta);
12
+ let isJunction = metaCols.length === columns.length;
13
+ // can't change primary once its set for now
14
+ if (primaryKey && !oldTable && !isJunction) {
15
+ schema.increments(primaryKey).primary();
16
+ }
17
+ else if (!oldTable && isJunction) {
18
+ schema.primary(metaCols.map(col => col.name));
19
+ }
20
+ // check if any columns need added
21
+ const foreignKeys = Object.values(table.schema).map(col => col.foreignKey);
22
+ for (let [key, column] of Object.entries(table.schema)) {
23
+ // skip things that are already correct
24
+ const oldColumn = oldTable ? oldTable.schema[key] : null;
25
+ if ((oldColumn && oldColumn.type) || (primaryKey === key && !isJunction)) {
26
+ continue;
27
+ }
28
+ switch (column.type) {
29
+ case FieldTypes.STRING:
30
+ case FieldTypes.OPTIONS:
31
+ case FieldTypes.LONGFORM:
32
+ schema.string(key);
33
+ break;
34
+ case FieldTypes.NUMBER:
35
+ // if meta is specified then this is a junction table entry
36
+ if (column.meta && column.meta.toKey && column.meta.toTable) {
37
+ const { toKey, toTable } = column.meta;
38
+ schema.integer(key).unsigned();
39
+ schema.foreign(key).references(`${toTable}.${toKey}`);
40
+ }
41
+ else if (foreignKeys.indexOf(key) === -1) {
42
+ schema.float(key);
43
+ }
44
+ break;
45
+ case FieldTypes.BOOLEAN:
46
+ schema.boolean(key);
47
+ break;
48
+ case FieldTypes.DATETIME:
49
+ schema.datetime(key);
50
+ break;
51
+ case FieldTypes.ARRAY:
52
+ schema.json(key);
53
+ break;
54
+ case FieldTypes.LINK:
55
+ // this side of the relationship doesn't need any SQL work
56
+ if (column.relationshipType !== RelationshipTypes.MANY_TO_ONE &&
57
+ column.relationshipType !== RelationshipTypes.MANY_TO_MANY) {
58
+ if (!column.foreignKey || !column.tableId) {
59
+ throw "Invalid relationship schema";
60
+ }
61
+ const { tableName } = utils_1.breakExternalTableId(column.tableId);
62
+ // @ts-ignore
63
+ const relatedTable = tables[tableName];
64
+ if (!relatedTable) {
65
+ throw "Referenced table doesn't exist";
66
+ }
67
+ schema.integer(column.foreignKey).unsigned();
68
+ schema
69
+ .foreign(column.foreignKey)
70
+ .references(`${tableName}.${relatedTable.primary[0]}`);
71
+ }
72
+ break;
73
+ }
74
+ }
75
+ // need to check if any columns have been deleted
76
+ if (oldTable) {
77
+ const deletedColumns = Object.entries(oldTable.schema)
78
+ .filter(([key, schema]) => schema.type !== FieldTypes.LINK && table.schema[key] == null)
79
+ .map(([key]) => key);
80
+ deletedColumns.forEach(key => {
81
+ if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {
82
+ schema.dropForeign(key);
83
+ }
84
+ schema.dropColumn(key);
85
+ });
86
+ }
87
+ return schema;
88
+ }
89
+ function buildCreateTable(knex, table, tables) {
90
+ return knex.schema.createTable(table.name, schema => {
91
+ generateSchema(schema, table, tables);
92
+ });
93
+ }
94
+ function buildUpdateTable(knex, table, tables, oldTable) {
95
+ return knex.schema.alterTable(table.name, schema => {
96
+ generateSchema(schema, table, tables, oldTable);
97
+ });
98
+ }
99
+ function buildDeleteTable(knex, table) {
100
+ return knex.schema.dropTable(table.name);
101
+ }
102
+ class SqlTableQueryBuilder {
103
+ // pass through client to get flavour of SQL
104
+ constructor(client) {
105
+ this.sqlClient = client;
106
+ }
107
+ getSqlClient() {
108
+ return this.sqlClient;
109
+ }
110
+ /**
111
+ * @param json the input JSON structure from which an SQL query will be built.
112
+ * @return {string} the operation that was found in the JSON.
113
+ */
114
+ _operation(json) {
115
+ return json.endpoint.operation;
116
+ }
117
+ _tableQuery(json) {
118
+ const client = knex_1.knex({ client: this.sqlClient });
119
+ let query;
120
+ if (!json.table || !json.meta || !json.meta.tables) {
121
+ throw "Cannot execute without table being specified";
122
+ }
123
+ switch (this._operation(json)) {
124
+ case datasource_1.Operation.CREATE_TABLE:
125
+ query = buildCreateTable(client, json.table, json.meta.tables);
126
+ break;
127
+ case datasource_1.Operation.UPDATE_TABLE:
128
+ if (!json.meta || !json.meta.table) {
129
+ throw "Must specify old table for update";
130
+ }
131
+ query = buildUpdateTable(client, json.table, json.meta.tables, json.meta.table);
132
+ break;
133
+ case datasource_1.Operation.DELETE_TABLE:
134
+ query = buildDeleteTable(client, json.table);
135
+ break;
136
+ default:
137
+ throw "Table operation is of unknown type";
138
+ }
139
+ return query.toSQL();
140
+ }
141
+ }
142
+ exports.default = SqlTableQueryBuilder;
143
+ module.exports = SqlTableQueryBuilder;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ var DatasourceUtils;
13
+ (function (DatasourceUtils) {
14
+ const { integrations } = require("../index");
15
+ function makeExternalQuery(datasource, json) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const Integration = integrations[datasource.source];
18
+ // query is the opinionated function
19
+ if (Integration.prototype.query) {
20
+ const integration = new Integration(datasource.config);
21
+ return integration.query(json);
22
+ }
23
+ else {
24
+ throw "Datasource does not support query.";
25
+ }
26
+ });
27
+ }
28
+ DatasourceUtils.makeExternalQuery = makeExternalQuery;
29
+ module.exports.makeExternalQuery = makeExternalQuery;
30
+ })(DatasourceUtils || (DatasourceUtils = {}));
@@ -17,6 +17,7 @@ var MSSQLModule;
17
17
  const Sql = require("./base/sql");
18
18
  const SCHEMA = {
19
19
  docs: "https://github.com/tediousjs/node-mssql",
20
+ plus: true,
20
21
  description: "Microsoft SQL Server is a relational database management system developed by Microsoft. ",
21
22
  friendlyName: "MS SQL Server",
22
23
  datasource: {
@@ -62,10 +63,22 @@ var MSSQLModule;
62
63
  },
63
64
  },
64
65
  };
65
- function internalQuery(client, query) {
66
+ function internalQuery(client, query, operation = undefined) {
66
67
  return __awaiter(this, void 0, void 0, function* () {
68
+ const request = client.request();
67
69
  try {
68
- return yield client.query(query.sql, query.bindings || {});
70
+ if (Array.isArray(query.bindings)) {
71
+ let count = 0;
72
+ for (let binding of query.bindings) {
73
+ request.input(`p${count++}`, binding);
74
+ }
75
+ }
76
+ // this is a hack to get the inserted ID back,
77
+ // no way to do this with Knex nicely
78
+ const sql = operation === datasource_1.Operation.CREATE
79
+ ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`
80
+ : query.sql;
81
+ return yield request.query(sql);
69
82
  }
70
83
  catch (err) {
71
84
  // @ts-ignore
@@ -75,21 +88,56 @@ var MSSQLModule;
75
88
  }
76
89
  class SqlServerIntegration extends Sql {
77
90
  constructor(config) {
78
- super("mssql");
91
+ super(utils_1.SqlClients.MS_SQL);
92
+ this.tables = {};
93
+ this.schemaErrors = {};
94
+ this.MASTER_TABLES = [
95
+ "spt_fallback_db",
96
+ "spt_fallback_dev",
97
+ "spt_fallback_usg",
98
+ "spt_monitor",
99
+ "MSreplication_options",
100
+ ];
101
+ this.TABLES_SQL = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'";
79
102
  this.config = config;
80
103
  const clientCfg = Object.assign(Object.assign({}, this.config), { options: {
81
104
  encrypt: this.config.encrypt,
105
+ enableArithAbort: true,
82
106
  } });
83
107
  delete clientCfg.encrypt;
84
108
  if (!this.pool) {
85
109
  this.pool = new sqlServer.ConnectionPool(clientCfg);
86
110
  }
87
111
  }
112
+ getDefinitionSQL(tableName) {
113
+ return `select *
114
+ from INFORMATION_SCHEMA.COLUMNS
115
+ where TABLE_NAME='${tableName}'`;
116
+ }
117
+ getConstraintsSQL(tableName) {
118
+ return `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
119
+ INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
120
+ ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
121
+ AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
122
+ AND KU.table_name='${tableName}'
123
+ ORDER BY
124
+ KU.TABLE_NAME,
125
+ KU.ORDINAL_POSITION;`;
126
+ }
127
+ getAutoColumnsSQL(tableName) {
128
+ return `SELECT
129
+ COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed')
130
+ AS IS_COMPUTED,
131
+ COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity')
132
+ AS IS_IDENTITY,
133
+ *
134
+ FROM INFORMATION_SCHEMA.COLUMNS
135
+ WHERE TABLE_NAME='${tableName}'`;
136
+ }
88
137
  connect() {
89
138
  return __awaiter(this, void 0, void 0, function* () {
90
139
  try {
91
- const client = yield this.pool.connect();
92
- this.client = client.request();
140
+ this.client = yield this.pool.connect();
93
141
  }
94
142
  catch (err) {
95
143
  // @ts-ignore
@@ -97,6 +145,65 @@ var MSSQLModule;
97
145
  }
98
146
  });
99
147
  }
148
+ runSQL(sql) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ return (yield internalQuery(this.client, utils_1.getSqlQuery(sql))).recordset;
151
+ });
152
+ }
153
+ /**
154
+ * Fetches the tables from the sql server database and assigns them to the datasource.
155
+ * @param {*} datasourceId - datasourceId to fetch
156
+ * @param entities - the tables that are to be built
157
+ */
158
+ buildSchema(datasourceId, entities) {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ yield this.connect();
161
+ let tableNames = yield this.runSQL(this.TABLES_SQL);
162
+ if (tableNames == null || !Array.isArray(tableNames)) {
163
+ throw "Unable to get list of tables in database";
164
+ }
165
+ tableNames = tableNames
166
+ .map((record) => record.TABLE_NAME)
167
+ .filter((name) => this.MASTER_TABLES.indexOf(name) === -1);
168
+ const tables = {};
169
+ for (let tableName of tableNames) {
170
+ // get the column definition (type)
171
+ const definition = yield this.runSQL(this.getDefinitionSQL(tableName));
172
+ // find primary key constraints
173
+ const constraints = yield this.runSQL(this.getConstraintsSQL(tableName));
174
+ // find the computed and identity columns (auto columns)
175
+ const columns = yield this.runSQL(this.getAutoColumnsSQL(tableName));
176
+ const primaryKeys = constraints
177
+ .filter((constraint) => constraint.CONSTRAINT_TYPE === "PRIMARY KEY")
178
+ .map((constraint) => constraint.COLUMN_NAME);
179
+ const autoColumns = columns
180
+ .filter((col) => col.IS_COMPUTED || col.IS_IDENTITY)
181
+ .map((col) => col.COLUMN_NAME);
182
+ let schema = {};
183
+ for (let def of definition) {
184
+ const name = def.COLUMN_NAME;
185
+ if (typeof name !== "string") {
186
+ continue;
187
+ }
188
+ const type = utils_1.convertSqlType(def.DATA_TYPE);
189
+ schema[name] = {
190
+ autocolumn: !!autoColumns.find((col) => col === name),
191
+ name: name,
192
+ type,
193
+ };
194
+ }
195
+ tables[tableName] = {
196
+ _id: utils_1.buildExternalTableId(datasourceId, tableName),
197
+ primary: primaryKeys,
198
+ name: tableName,
199
+ schema,
200
+ };
201
+ }
202
+ const final = utils_1.finaliseExternalTables(tables, entities);
203
+ this.tables = final.tables;
204
+ this.schemaErrors = final.errors;
205
+ });
206
+ }
100
207
  read(query) {
101
208
  return __awaiter(this, void 0, void 0, function* () {
102
209
  yield this.connect();
@@ -127,10 +234,11 @@ var MSSQLModule;
127
234
  }
128
235
  query(json) {
129
236
  return __awaiter(this, void 0, void 0, function* () {
130
- const operation = this._operation(json).toLowerCase();
131
- const input = this._query(json);
132
- const response = yield internalQuery(this.client, input);
133
- return response.recordset ? response.recordset : [{ [operation]: true }];
237
+ yield this.connect();
238
+ const operation = this._operation(json);
239
+ const queryFn = (query, op) => internalQuery(this.client, query, op);
240
+ const processFn = (result) => result.recordset ? result.recordset : [{ [operation]: true }];
241
+ return this.queryWithReturning(json, queryFn, processFn);
134
242
  });
135
243
  }
136
244
  }
@@ -15,31 +15,6 @@ var MySQLModule;
15
15
  (function (MySQLModule) {
16
16
  const mysql = require("mysql2");
17
17
  const Sql = require("./base/sql");
18
- const { buildExternalTableId, convertType, copyExistingPropsOver, } = require("./utils");
19
- const { FieldTypes } = require("../constants");
20
- const TYPE_MAP = {
21
- text: FieldTypes.LONGFORM,
22
- blob: FieldTypes.LONGFORM,
23
- enum: FieldTypes.STRING,
24
- varchar: FieldTypes.STRING,
25
- float: FieldTypes.NUMBER,
26
- int: FieldTypes.NUMBER,
27
- numeric: FieldTypes.NUMBER,
28
- bigint: FieldTypes.NUMBER,
29
- mediumint: FieldTypes.NUMBER,
30
- decimal: FieldTypes.NUMBER,
31
- dec: FieldTypes.NUMBER,
32
- double: FieldTypes.NUMBER,
33
- real: FieldTypes.NUMBER,
34
- fixed: FieldTypes.NUMBER,
35
- smallint: FieldTypes.NUMBER,
36
- timestamp: FieldTypes.DATETIME,
37
- date: FieldTypes.DATETIME,
38
- datetime: FieldTypes.DATETIME,
39
- time: FieldTypes.DATETIME,
40
- tinyint: FieldTypes.BOOLEAN,
41
- json: datasource_1.DatasourceFieldTypes.JSON,
42
- };
43
18
  const SCHEMA = {
44
19
  docs: "https://github.com/mysqljs/mysql",
45
20
  plus: true,
@@ -111,7 +86,9 @@ var MySQLModule;
111
86
  }
112
87
  class MySQLIntegration extends Sql {
113
88
  constructor(config) {
114
- super("mysql");
89
+ super(utils_1.SqlClients.MY_SQL);
90
+ this.tables = {};
91
+ this.schemaErrors = {};
115
92
  this.config = config;
116
93
  if (config.ssl && Object.keys(config.ssl).length === 0) {
117
94
  delete config.ssl;
@@ -144,26 +121,23 @@ var MySQLModule;
144
121
  schema[columnName] = {
145
122
  name: columnName,
146
123
  autocolumn: isAuto,
147
- type: convertType(column.Type, TYPE_MAP),
124
+ type: utils_1.convertSqlType(column.Type),
148
125
  constraints,
149
126
  };
150
127
  }
151
- // for now just default to first column
152
- if (primaryKeys.length === 0) {
153
- primaryKeys.push(descResp[0].Field);
154
- }
155
128
  if (!tables[tableName]) {
156
129
  tables[tableName] = {
157
- _id: buildExternalTableId(datasourceId, tableName),
130
+ _id: utils_1.buildExternalTableId(datasourceId, tableName),
158
131
  primary: primaryKeys,
159
132
  name: tableName,
160
133
  schema,
161
134
  };
162
135
  }
163
- copyExistingPropsOver(tableName, tables, entities);
164
136
  }
165
137
  this.client.end();
166
- this.tables = tables;
138
+ const final = utils_1.finaliseExternalTables(tables, entities);
139
+ this.tables = final.tables;
140
+ this.schemaErrors = final.errors;
167
141
  });
168
142
  }
169
143
  create(query) {
@@ -173,7 +147,9 @@ var MySQLModule;
173
147
  });
174
148
  }
175
149
  read(query) {
176
- return internalQuery(this.client, utils_1.getSqlQuery(query));
150
+ return __awaiter(this, void 0, void 0, function* () {
151
+ return internalQuery(this.client, utils_1.getSqlQuery(query));
152
+ });
177
153
  }
178
154
  update(query) {
179
155
  return __awaiter(this, void 0, void 0, function* () {
@@ -187,59 +163,13 @@ var MySQLModule;
187
163
  return results.length ? results : [{ deleted: true }];
188
164
  });
189
165
  }
190
- getReturningRow(json) {
191
- return __awaiter(this, void 0, void 0, function* () {
192
- if (!json.extra || !json.extra.idFilter) {
193
- return {};
194
- }
195
- const input = this._query({
196
- endpoint: Object.assign(Object.assign({}, json.endpoint), { operation: datasource_1.Operation.READ }),
197
- fields: [],
198
- filters: json.extra.idFilter,
199
- paginate: {
200
- limit: 1,
201
- },
202
- });
203
- return internalQuery(this.client, input, false);
204
- });
205
- }
206
- // when creating if an ID has been inserted need to make sure
207
- // the id filter is enriched with it before trying to retrieve the row
208
- checkLookupKeys(results, json) {
209
- var _a, _b;
210
- if (!(results === null || results === void 0 ? void 0 : results.insertId) || !((_a = json.meta) === null || _a === void 0 ? void 0 : _a.table) || !json.meta.table.primary) {
211
- return json;
212
- }
213
- const primaryKey = (_b = json.meta.table.primary) === null || _b === void 0 ? void 0 : _b[0];
214
- json.extra = {
215
- idFilter: {
216
- equal: {
217
- [primaryKey]: results.insertId,
218
- },
219
- },
220
- };
221
- return json;
222
- }
223
166
  query(json) {
224
167
  return __awaiter(this, void 0, void 0, function* () {
225
- const operation = this._operation(json);
226
168
  this.client.connect();
227
- const input = this._query(json, { disableReturning: true });
228
- let row;
229
- // need to manage returning, a feature mySQL can't do
230
- if (operation === operation.DELETE) {
231
- row = this.getReturningRow(json);
232
- }
233
- const results = yield internalQuery(this.client, input, false);
234
- // same as delete, manage returning
235
- if (operation === datasource_1.Operation.CREATE || operation === datasource_1.Operation.UPDATE) {
236
- row = this.getReturningRow(this.checkLookupKeys(results, json));
237
- }
169
+ const queryFn = (query) => internalQuery(this.client, query, false);
170
+ const output = yield this.queryWithReturning(json, queryFn);
238
171
  this.client.end();
239
- if (operation !== datasource_1.Operation.READ) {
240
- return row;
241
- }
242
- return results.length ? results : [{ [operation.toLowerCase()]: true }];
172
+ return output;
243
173
  });
244
174
  }
245
175
  }
@@ -15,8 +15,6 @@ var PostgresModule;
15
15
  (function (PostgresModule) {
16
16
  const { Pool } = require("pg");
17
17
  const Sql = require("./base/sql");
18
- const { FieldTypes } = require("../constants");
19
- const { buildExternalTableId, convertType, copyExistingPropsOver, } = require("./utils");
20
18
  const { escapeDangerousCharacters } = require("../utilities");
21
19
  const JSON_REGEX = /'{.*}'::json/s;
22
20
  const SCHEMA = {
@@ -50,6 +48,11 @@ var PostgresModule;
50
48
  default: "root",
51
49
  required: true,
52
50
  },
51
+ schema: {
52
+ type: datasource_1.DatasourceFieldTypes.STRING,
53
+ default: "public",
54
+ required: true,
55
+ },
53
56
  ssl: {
54
57
  type: datasource_1.DatasourceFieldTypes.BOOLEAN,
55
58
  default: false,
@@ -81,21 +84,6 @@ var PostgresModule;
81
84
  },
82
85
  },
83
86
  };
84
- const TYPE_MAP = {
85
- text: FieldTypes.LONGFORM,
86
- varchar: FieldTypes.STRING,
87
- integer: FieldTypes.NUMBER,
88
- bigint: FieldTypes.NUMBER,
89
- decimal: FieldTypes.NUMBER,
90
- smallint: FieldTypes.NUMBER,
91
- real: FieldTypes.NUMBER,
92
- "double precision": FieldTypes.NUMBER,
93
- timestamp: FieldTypes.DATETIME,
94
- time: FieldTypes.DATETIME,
95
- boolean: FieldTypes.BOOLEAN,
96
- json: FieldTypes.JSON,
97
- date: FieldTypes.DATETIME,
98
- };
99
87
  function internalQuery(client, query) {
100
88
  return __awaiter(this, void 0, void 0, function* () {
101
89
  // need to handle a specific issue with json data types in postgres,
@@ -120,8 +108,9 @@ var PostgresModule;
120
108
  }
121
109
  class PostgresIntegration extends Sql {
122
110
  constructor(config) {
123
- super("pg");
124
- this.COLUMNS_SQL = "select * from information_schema.columns where not table_schema = 'information_schema' and not table_schema = 'pg_catalog'";
111
+ super(utils_1.SqlClients.POSTGRES);
112
+ this.tables = {};
113
+ this.schemaErrors = {};
125
114
  this.PRIMARY_KEYS_SQL = `
126
115
  select tc.table_schema, tc.table_name, kc.column_name as primary_key
127
116
  from information_schema.table_constraints tc
@@ -142,6 +131,16 @@ var PostgresModule;
142
131
  this.pool = new Pool(newConfig);
143
132
  }
144
133
  this.client = this.pool;
134
+ this.setSchema();
135
+ }
136
+ setSchema() {
137
+ if (!this.config.schema) {
138
+ this.config.schema = "public";
139
+ }
140
+ this.client.on("connect", (client) => {
141
+ client.query(`SET search_path TO ${this.config.schema}`);
142
+ });
143
+ this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`;
145
144
  }
146
145
  /**
147
146
  * Fetches the tables from the postgres table and assigns them to the datasource.
@@ -176,13 +175,13 @@ var PostgresModule;
176
175
  // table key doesn't exist yet
177
176
  if (!tables[tableName] || !tables[tableName].schema) {
178
177
  tables[tableName] = {
179
- _id: buildExternalTableId(datasourceId, tableName),
180
- primary: tableKeys[tableName] || ["id"],
178
+ _id: utils_1.buildExternalTableId(datasourceId, tableName),
179
+ primary: tableKeys[tableName] || [],
181
180
  name: tableName,
182
181
  schema: {},
183
182
  };
184
183
  }
185
- const type = convertType(column.data_type, TYPE_MAP);
184
+ const type = utils_1.convertSqlType(column.data_type);
186
185
  const identity = !!(column.identity_generation ||
187
186
  column.identity_start ||
188
187
  column.identity_increment);
@@ -196,10 +195,9 @@ var PostgresModule;
196
195
  type,
197
196
  };
198
197
  }
199
- for (let tableName of Object.keys(tables)) {
200
- copyExistingPropsOver(tableName, tables, entities);
201
- }
202
- this.tables = tables;
198
+ const final = utils_1.finaliseExternalTables(tables, entities);
199
+ this.tables = final.tables;
200
+ this.schemaErrors = final.errors;
203
201
  });
204
202
  }
205
203
  create(query) {
@@ -230,8 +228,17 @@ var PostgresModule;
230
228
  return __awaiter(this, void 0, void 0, function* () {
231
229
  const operation = this._operation(json).toLowerCase();
232
230
  const input = this._query(json);
233
- const response = yield internalQuery(this.client, input);
234
- return response.rows.length ? response.rows : [{ [operation]: true }];
231
+ if (Array.isArray(input)) {
232
+ const responses = [];
233
+ for (let query of input) {
234
+ responses.push(yield internalQuery(this.client, query));
235
+ }
236
+ return responses;
237
+ }
238
+ else {
239
+ const response = yield internalQuery(this.client, input);
240
+ return response.rows.length ? response.rows : [{ [operation]: true }];
241
+ }
235
242
  });
236
243
  }
237
244
  }