@budibase/server 1.0.49-alpha.7 → 1.0.50-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/builder/assets/{index.83c0944f.css → index.c0cc369d.css} +6 -1
  2. package/builder/assets/{index.b7cd931c.js → index.ff2bad21.js} +190 -190
  3. package/builder/assets/{vendor.d526bfe8.js → vendor.5ad9695a.js} +202 -106
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +195 -207
  6. package/coverage/coverage-final.json +4 -4
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/application.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/index.html +14 -14
  18. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/query/index.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/external.js.html +29 -116
  29. package/coverage/lcov-report/api/controllers/row/index.html +11 -11
  30. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  40. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/user.js.html +41 -35
  45. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  48. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  49. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  50. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  51. package/coverage/lcov-report/api/index.html +1 -1
  52. package/coverage/lcov-report/api/index.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/index.html +1 -1
  65. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  82. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  83. package/coverage/lcov-report/automations/actions.js.html +1 -1
  84. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  85. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  86. package/coverage/lcov-report/automations/index.html +1 -1
  87. package/coverage/lcov-report/automations/index.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/index.html +1 -1
  97. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  111. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  112. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  113. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  114. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  115. package/coverage/lcov-report/automations/utils.js.html +1 -1
  116. package/coverage/lcov-report/constants/index.html +1 -1
  117. package/coverage/lcov-report/constants/index.js.html +1 -1
  118. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  119. package/coverage/lcov-report/constants/screens.js.html +1 -1
  120. package/coverage/lcov-report/db/client.js.html +1 -1
  121. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  122. package/coverage/lcov-report/db/index.html +1 -1
  123. package/coverage/lcov-report/db/index.js.html +1 -1
  124. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  126. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  127. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  128. package/coverage/lcov-report/db/newid.js.html +1 -1
  129. package/coverage/lcov-report/db/utils.js.html +1 -1
  130. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  131. package/coverage/lcov-report/events/index.html +1 -1
  132. package/coverage/lcov-report/events/index.js.html +1 -1
  133. package/coverage/lcov-report/events/utils.js.html +1 -1
  134. package/coverage/lcov-report/index.html +28 -28
  135. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  136. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  137. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  138. package/coverage/lcov-report/middleware/authorized.js.html +1 -1
  139. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  140. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  141. package/coverage/lcov-report/middleware/index.html +1 -1
  142. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  143. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  144. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  145. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  146. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  147. package/coverage/lcov-report/threads/automation.js.html +1 -1
  148. package/coverage/lcov-report/threads/index.html +14 -14
  149. package/coverage/lcov-report/threads/index.js.html +1 -1
  150. package/coverage/lcov-report/threads/query.js.html +10 -31
  151. package/coverage/lcov-report/threads/utils.js.html +1 -1
  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 +1 -1
  156. package/coverage/lcov-report/utilities/global.js.html +1 -1
  157. package/coverage/lcov-report/utilities/index.html +1 -1
  158. package/coverage/lcov-report/utilities/index.js.html +1 -1
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  160. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  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 +1 -1
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  167. package/coverage/lcov-report/utilities/security.js.html +1 -1
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  170. package/coverage/lcov-report/utilities/usageQuota/index.js.html +1 -1
  171. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
  172. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  173. package/coverage/lcov-report/utilities/users.js.html +1 -1
  174. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  175. package/coverage/lcov.info +314 -328
  176. package/dist/api/controllers/row/ExternalRequest.js +14 -4
  177. package/dist/api/controllers/row/external.js +10 -18
  178. package/dist/api/controllers/static/index.js +4 -7
  179. package/dist/api/controllers/user.js +27 -25
  180. package/dist/integrations/base/sql.js +49 -15
  181. package/dist/package.json +4 -4
  182. package/dist/threads/query.js +2 -8
  183. package/dist/tsconfig.tsbuildinfo +1 -1
  184. package/package.json +5 -5
  185. package/scripts/integrations/mssql/data/Dockerfile +1 -1
  186. package/scripts/integrations/mssql/data/setup.sql +17 -4
  187. package/scripts/integrations/postgres/init.sql +11 -6
  188. package/src/api/controllers/row/ExternalRequest.ts +14 -1
  189. package/src/api/controllers/row/external.js +23 -52
  190. package/src/api/controllers/static/index.js +4 -6
  191. package/src/api/controllers/user.js +29 -27
  192. package/src/integrations/base/sql.ts +61 -22
  193. package/src/threads/query.js +2 -9
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.0.49-alpha.7",
4
+ "version": "1.0.50-alpha.0",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -70,9 +70,9 @@
70
70
  "license": "GPL-3.0",
71
71
  "dependencies": {
72
72
  "@apidevtools/swagger-parser": "^10.0.3",
73
- "@budibase/backend-core": "^1.0.49-alpha.7",
74
- "@budibase/client": "^1.0.49-alpha.7",
75
- "@budibase/string-templates": "^1.0.49-alpha.7",
73
+ "@budibase/backend-core": "^1.0.50-alpha.0",
74
+ "@budibase/client": "^1.0.50-alpha.0",
75
+ "@budibase/string-templates": "^1.0.50-alpha.0",
76
76
  "@bull-board/api": "^3.7.0",
77
77
  "@bull-board/koa": "^3.7.0",
78
78
  "@elastic/elasticsearch": "7.10.0",
@@ -168,5 +168,5 @@
168
168
  "optionalDependencies": {
169
169
  "oracledb": "^5.3.0"
170
170
  },
171
- "gitHead": "c7d23bbf7e30545a20c9452d720b7078dafb9947"
171
+ "gitHead": "a076d7ccf1deab0d300ae229a1aa3f4ce92aa1ba"
172
172
  }
@@ -1,4 +1,4 @@
1
- FROM mcr.microsoft.com/mssql/server
1
+ FROM mcr.microsoft.com/mssql/server:2017-latest
2
2
 
3
3
  ENV ACCEPT_EULA=Y
4
4
  ENV SA_PASSWORD=Passw0rd
@@ -48,7 +48,20 @@ INSERT tasks
48
48
  VALUES
49
49
  ('Processing', 1);
50
50
 
51
- INSERT people
52
- (name, age)
53
- VALUES
54
- ('Bob', '30');
51
+ INSERT INTO people (name, age)
52
+ VALUES ('Bob', '30'),
53
+ ('Bert', '10'),
54
+ ('Jack', '12'),
55
+ ('Mike', '31'),
56
+ ('Dave', '44'),
57
+ ('Jim', '43'),
58
+ ('Kerry', '32'),
59
+ ('Julie', '12'),
60
+ ('Kim', '55'),
61
+ ('Andy', '33'),
62
+ ('John', '22'),
63
+ ('Ruth', '66'),
64
+ ('Robert', '88'),
65
+ ('Bobert', '99'),
66
+ ('Jan', '22'),
67
+ ('Megan', '11');
@@ -9,12 +9,16 @@ CREATE TABLE Persons (
9
9
  );
10
10
  CREATE TABLE Tasks (
11
11
  TaskID SERIAL PRIMARY KEY,
12
- PersonID INT,
12
+ ExecutorID INT,
13
+ QaID INT,
13
14
  Completed BOOLEAN,
14
15
  TaskName varchar(255),
15
- CONSTRAINT fkPersons
16
- FOREIGN KEY(PersonID)
17
- REFERENCES Persons(PersonID)
16
+ CONSTRAINT fkexecutor
17
+ FOREIGN KEY(ExecutorID)
18
+ REFERENCES Persons(PersonID),
19
+ CONSTRAINT fkqa
20
+ FOREIGN KEY(QaID)
21
+ REFERENCES Persons(PersonID)
18
22
  );
19
23
  CREATE TABLE Products (
20
24
  ProductID SERIAL PRIMARY KEY,
@@ -32,8 +36,9 @@ CREATE TABLE Products_Tasks (
32
36
  PRIMARY KEY (ProductID, TaskID)
33
37
  );
34
38
  INSERT INTO Persons (FirstName, LastName, Address, City) VALUES ('Mike', 'Hughes', '123 Fake Street', 'Belfast');
35
- INSERT INTO Tasks (PersonID, TaskName, Completed) VALUES (1, 'assembling', TRUE);
36
- INSERT INTO Tasks (PersonID, TaskName, Completed) VALUES (1, 'processing', FALSE);
39
+ INSERT INTO Persons (FirstName, LastName, Address, City) Values ('John', 'Smith', '64 Updown Road', 'Dublin');
40
+ INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (1, 2, 'assembling', TRUE);
41
+ INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (2, 1, 'processing', FALSE);
37
42
  INSERT INTO Products (ProductName) VALUES ('Computers');
38
43
  INSERT INTO Products (ProductName) VALUES ('Laptops');
39
44
  INSERT INTO Products (ProductName) VALUES ('Chairs');
@@ -184,7 +184,7 @@ module External {
184
184
  thisRow._id = generateIdForRow(row, table)
185
185
  thisRow.tableId = table._id
186
186
  thisRow._rev = "rev"
187
- return thisRow
187
+ return processFormulas(table, thisRow)
188
188
  }
189
189
 
190
190
  function fixArrayTypes(row: Row, table: Table) {
@@ -327,8 +327,12 @@ module External {
327
327
  * This iterates through the returned rows and works out what elements of the rows
328
328
  * actually match up to another row (based on primary keys) - this is pretty specific
329
329
  * to SQL and the way that SQL relationships are returned based on joins.
330
+ * This is complicated, but the idea is that when a SQL query returns all the relations
331
+ * will be separate rows, with all of the data in each row. We have to decipher what comes
332
+ * from where (which tables) and how to convert that into budibase columns.
330
333
  */
331
334
  updateRelationshipColumns(
335
+ table: Table,
332
336
  row: Row,
333
337
  rows: { [key: string]: Row },
334
338
  relationships: RelationshipsJson[]
@@ -339,6 +343,13 @@ module External {
339
343
  if (!linkedTable) {
340
344
  continue
341
345
  }
346
+ const fromColumn = `${table.name}.${relationship.from}`
347
+ const toColumn = `${linkedTable.name}.${relationship.to}`
348
+ // this is important when working with multiple relationships
349
+ // between the same tables, don't want to overlap/multiply the relations
350
+ if (!relationship.through && row[fromColumn] !== row[toColumn]) {
351
+ continue
352
+ }
342
353
  let linked = basicProcessing(row, linkedTable)
343
354
  if (!linked._id) {
344
355
  continue
@@ -386,6 +397,7 @@ module External {
386
397
  // this is a relationship of some sort
387
398
  if (finalRows[rowId]) {
388
399
  finalRows = this.updateRelationshipColumns(
400
+ table,
389
401
  row,
390
402
  finalRows,
391
403
  relationships
@@ -399,6 +411,7 @@ module External {
399
411
  finalRows[thisRow._id] = thisRow
400
412
  // do this at end once its been added to the final rows
401
413
  finalRows = this.updateRelationshipColumns(
414
+ table,
402
415
  row,
403
416
  finalRows,
404
417
  relationships
@@ -31,23 +31,21 @@ async function handleRequest(operation, tableId, opts = {}) {
31
31
  exports.handleRequest = handleRequest
32
32
 
33
33
  exports.patch = async ctx => {
34
- const appId = ctx.appId
35
34
  const inputs = ctx.request.body
36
35
  const tableId = ctx.params.tableId
37
36
  const id = breakRowIdField(inputs._id)
38
37
  // don't save the ID to db
39
38
  delete inputs._id
40
- return handleRequest(appId, DataSourceOperation.UPDATE, tableId, {
39
+ return handleRequest(DataSourceOperation.UPDATE, tableId, {
41
40
  id,
42
41
  row: inputs,
43
42
  })
44
43
  }
45
44
 
46
45
  exports.save = async ctx => {
47
- const appId = ctx.appId
48
46
  const inputs = ctx.request.body
49
47
  const tableId = ctx.params.tableId
50
- return handleRequest(appId, DataSourceOperation.CREATE, tableId, {
48
+ return handleRequest(DataSourceOperation.CREATE, tableId, {
51
49
  row: inputs,
52
50
  })
53
51
  }
@@ -61,49 +59,35 @@ exports.fetchView = async ctx => {
61
59
  }
62
60
 
63
61
  exports.fetch = async ctx => {
64
- const appId = ctx.appId
65
62
  const tableId = ctx.params.tableId
66
- return handleRequest(appId, DataSourceOperation.READ, tableId)
63
+ return handleRequest(DataSourceOperation.READ, tableId)
67
64
  }
68
65
 
69
66
  exports.find = async ctx => {
70
- const appId = ctx.appId
71
67
  const id = ctx.params.rowId
72
68
  const tableId = ctx.params.tableId
73
- const response = await handleRequest(
74
- appId,
75
- DataSourceOperation.READ,
76
- tableId,
77
- {
78
- id,
79
- }
80
- )
69
+ const response = await handleRequest(DataSourceOperation.READ, tableId, {
70
+ id,
71
+ })
81
72
  return response ? response[0] : response
82
73
  }
83
74
 
84
75
  exports.destroy = async ctx => {
85
- const appId = ctx.appId
86
76
  const tableId = ctx.params.tableId
87
77
  const id = ctx.request.body._id
88
- const { row } = await handleRequest(
89
- appId,
90
- DataSourceOperation.DELETE,
91
- tableId,
92
- {
93
- id,
94
- }
95
- )
78
+ const { row } = await handleRequest(DataSourceOperation.DELETE, tableId, {
79
+ id,
80
+ })
96
81
  return { response: { ok: true }, row }
97
82
  }
98
83
 
99
84
  exports.bulkDestroy = async ctx => {
100
- const appId = ctx.appId
101
85
  const { rows } = ctx.request.body
102
86
  const tableId = ctx.params.tableId
103
87
  let promises = []
104
88
  for (let row of rows) {
105
89
  promises.push(
106
- handleRequest(appId, DataSourceOperation.DELETE, tableId, {
90
+ handleRequest(DataSourceOperation.DELETE, tableId, {
107
91
  id: breakRowIdField(row._id),
108
92
  })
109
93
  )
@@ -113,7 +97,6 @@ exports.bulkDestroy = async ctx => {
113
97
  }
114
98
 
115
99
  exports.search = async ctx => {
116
- const appId = ctx.appId
117
100
  const tableId = ctx.params.tableId
118
101
  const { paginate, query, ...params } = ctx.request.body
119
102
  let { bookmark, limit } = params
@@ -143,26 +126,21 @@ exports.search = async ctx => {
143
126
  [params.sort]: direction,
144
127
  }
145
128
  }
146
- const rows = await handleRequest(appId, DataSourceOperation.READ, tableId, {
129
+ const rows = await handleRequest(DataSourceOperation.READ, tableId, {
147
130
  filters: query,
148
131
  sort,
149
132
  paginate: paginateObj,
150
133
  })
151
134
  let hasNextPage = false
152
135
  if (paginate && rows.length === limit) {
153
- const nextRows = await handleRequest(
154
- appId,
155
- DataSourceOperation.READ,
156
- tableId,
157
- {
158
- filters: query,
159
- sort,
160
- paginate: {
161
- limit: 1,
162
- page: bookmark * limit + 1,
163
- },
164
- }
165
- )
136
+ const nextRows = await handleRequest(DataSourceOperation.READ, tableId, {
137
+ filters: query,
138
+ sort,
139
+ paginate: {
140
+ limit: 1,
141
+ page: bookmark * limit + 1,
142
+ },
143
+ })
166
144
  hasNextPage = nextRows.length > 0
167
145
  }
168
146
  // need wrapper object for bookmarks etc when paginating
@@ -175,7 +153,6 @@ exports.validate = async () => {
175
153
  }
176
154
 
177
155
  exports.fetchEnrichedRow = async ctx => {
178
- const appId = ctx.appId
179
156
  const id = ctx.params.rowId
180
157
  const tableId = ctx.params.tableId
181
158
  const { datasourceId, tableName } = breakExternalTableId(tableId)
@@ -185,15 +162,10 @@ exports.fetchEnrichedRow = async ctx => {
185
162
  ctx.throw(400, "Datasource has not been configured for plus API.")
186
163
  }
187
164
  const tables = datasource.entities
188
- const response = await handleRequest(
189
- appId,
190
- DataSourceOperation.READ,
191
- tableId,
192
- {
193
- id,
194
- datasource,
195
- }
196
- )
165
+ const response = await handleRequest(DataSourceOperation.READ, tableId, {
166
+ id,
167
+ datasource,
168
+ })
197
169
  const table = tables[tableName]
198
170
  const row = response[0]
199
171
  // this seems like a lot of work, but basically we need to dig deeper for the enrich
@@ -212,7 +184,6 @@ exports.fetchEnrichedRow = async ctx => {
212
184
  // don't support composite keys right now
213
185
  const linkedIds = links.map(link => breakRowIdField(link._id)[0])
214
186
  row[fieldName] = await handleRequest(
215
- appId,
216
187
  DataSourceOperation.READ,
217
188
  linkedTableId,
218
189
  {
@@ -16,7 +16,7 @@ const { clientLibraryPath } = require("../../../utilities")
16
16
  const { upload } = require("../../../utilities/fileSystem")
17
17
  const { attachmentsRelativeURL } = require("../../../utilities")
18
18
  const { DocumentTypes } = require("../../../db/utils")
19
- const { getAppDB } = require("@budibase/backend-core/context")
19
+ const { getAppDB, updateAppId } = require("@budibase/backend-core/context")
20
20
  const AWS = require("aws-sdk")
21
21
  const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1"
22
22
 
@@ -49,11 +49,9 @@ async function getAppIdFromUrl(ctx) {
49
49
  a => a.url && a.url.toLowerCase() === possibleAppUrl
50
50
  )[0]
51
51
 
52
- if (app && app.appId) {
53
- return app.appId
54
- } else {
55
- return ctx.params.appId
56
- }
52
+ const appId = app && app.appId ? app.appId : ctx.params.appId
53
+ updateAppId(appId)
54
+ return appId
57
55
  }
58
56
 
59
57
  exports.serveBuilder = async function (ctx) {
@@ -14,7 +14,7 @@ const {
14
14
  dbExists,
15
15
  } = require("@budibase/backend-core/db")
16
16
  const { UserStatus } = require("@budibase/backend-core/constants")
17
- const { getAppDB } = require("@budibase/backend-core/context")
17
+ const { getAppDB, doInAppContext } = require("@budibase/backend-core/context")
18
18
 
19
19
  async function rawMetadata() {
20
20
  const db = getAppDB()
@@ -105,34 +105,36 @@ exports.syncUser = async function (ctx) {
105
105
  if (!(await dbExists(appId))) {
106
106
  continue
107
107
  }
108
- const db = getAppDB()
109
- const metadataId = generateUserMetadataID(userId)
110
- let metadata
111
- try {
112
- metadata = await db.get(metadataId)
113
- } catch (err) {
114
- if (deleting) {
115
- continue
108
+ await doInAppContext(appId, async () => {
109
+ const db = getAppDB()
110
+ const metadataId = generateUserMetadataID(userId)
111
+ let metadata
112
+ try {
113
+ metadata = await db.get(metadataId)
114
+ } catch (err) {
115
+ if (deleting) {
116
+ return
117
+ }
118
+ metadata = {
119
+ tableId: InternalTables.USER_METADATA,
120
+ }
116
121
  }
117
- metadata = {
118
- tableId: InternalTables.USER_METADATA,
122
+ // assign the roleId for the metadata doc
123
+ if (roleId) {
124
+ metadata.roleId = roleId
119
125
  }
120
- }
121
- // assign the roleId for the metadata doc
122
- if (roleId) {
123
- metadata.roleId = roleId
124
- }
125
- let combined = !deleting
126
- ? combineMetadataAndUser(user, metadata)
127
- : {
128
- ...metadata,
129
- status: UserStatus.INACTIVE,
130
- metadata: BUILTIN_ROLE_IDS.PUBLIC,
131
- }
132
- // if its null then there was no updates required
133
- if (combined) {
134
- await db.put(combined)
135
- }
126
+ let combined = !deleting
127
+ ? combineMetadataAndUser(user, metadata)
128
+ : {
129
+ ...metadata,
130
+ status: UserStatus.INACTIVE,
131
+ metadata: BUILTIN_ROLE_IDS.PUBLIC,
132
+ }
133
+ // if its null then there was no updates required
134
+ if (combined) {
135
+ await db.put(combined)
136
+ }
137
+ })
136
138
  }
137
139
  }
138
140
  ctx.body = {
@@ -166,15 +166,13 @@ class InternalBuilder {
166
166
 
167
167
  addSorting(query: KnexQuery, json: QueryJson): KnexQuery {
168
168
  let { sort, paginate } = json
169
- if (!sort) {
170
- return query
171
- }
172
169
  const table = json.meta?.table
173
- for (let [key, value] of Object.entries(sort)) {
174
- const direction = value === SortDirection.ASCENDING ? "asc" : "desc"
175
- query = query.orderBy(`${table?.name}.${key}`, direction)
176
- }
177
- if (this.client === SqlClients.MS_SQL && !sort && paginate?.limit) {
170
+ if (sort) {
171
+ for (let [key, value] of Object.entries(sort)) {
172
+ const direction = value === SortDirection.ASCENDING ? "asc" : "desc"
173
+ query = query.orderBy(`${table?.name}.${key}`, direction)
174
+ }
175
+ } else if (this.client === SqlClients.MS_SQL && paginate?.limit) {
178
176
  // @ts-ignore
179
177
  query = query.orderBy(`${table?.name}.${table?.primary[0]}`)
180
178
  }
@@ -191,29 +189,70 @@ class InternalBuilder {
191
189
  if (!relationships) {
192
190
  return query
193
191
  }
192
+ const tableSets: Record<string, [any]> = {}
193
+ // aggregate into table sets (all the same to tables)
194
194
  for (let relationship of relationships) {
195
- const from = relationship.from,
196
- to = relationship.to,
197
- toTable = relationship.tableName
198
- if (!relationship.through) {
195
+ const keyObj: { toTable: string; throughTable: string | undefined } = {
196
+ toTable: relationship.tableName,
197
+ throughTable: undefined,
198
+ }
199
+ if (relationship.through) {
200
+ keyObj.throughTable = relationship.through
201
+ }
202
+ const key = JSON.stringify(keyObj)
203
+ if (tableSets[key]) {
204
+ tableSets[key].push(relationship)
205
+ } else {
206
+ tableSets[key] = [relationship]
207
+ }
208
+ }
209
+ for (let [key, relationships] of Object.entries(tableSets)) {
210
+ const { toTable, throughTable } = JSON.parse(key)
211
+ if (!throughTable) {
199
212
  // @ts-ignore
200
- query = query.leftJoin(
213
+ query = query.join(
201
214
  toTable,
202
- `${fromTable}.${from}`,
203
- `${toTable}.${to}`
215
+ function () {
216
+ for (let relationship of relationships) {
217
+ const from = relationship.from,
218
+ to = relationship.to
219
+ // @ts-ignore
220
+ this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`)
221
+ }
222
+ },
223
+ "left"
204
224
  )
205
225
  } else {
206
- const throughTable = relationship.through
207
- const fromPrimary = relationship.fromPrimary
208
- const toPrimary = relationship.toPrimary
209
226
  query = query
210
227
  // @ts-ignore
211
- .leftJoin(
228
+ .join(
212
229
  throughTable,
213
- `${fromTable}.${fromPrimary}`,
214
- `${throughTable}.${from}`
230
+ function () {
231
+ for (let relationship of relationships) {
232
+ const fromPrimary = relationship.fromPrimary
233
+ const from = relationship.from
234
+ // @ts-ignore
235
+ this.orOn(
236
+ `${fromTable}.${fromPrimary}`,
237
+ "=",
238
+ `${throughTable}.${from}`
239
+ )
240
+ }
241
+ },
242
+ "left"
243
+ )
244
+ .join(
245
+ toTable,
246
+ function () {
247
+ for (let relationship of relationships) {
248
+ const toPrimary = relationship.toPrimary
249
+ const to = relationship.to
250
+ // @ts-ignore
251
+ this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`)
252
+ }
253
+ },
254
+ "left"
215
255
  )
216
- .leftJoin(toTable, `${toTable}.${toPrimary}`, `${throughTable}.${to}`)
217
256
  }
218
257
  }
219
258
  return query.limit(BASE_LIMIT)
@@ -5,9 +5,6 @@ const { integrations } = require("../integrations")
5
5
  const { processStringSync } = require("@budibase/string-templates")
6
6
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
7
7
 
8
- const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/)
9
- const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/)
10
-
11
8
  class QueryRunner {
12
9
  constructor(input, flags = { noRecursiveQuery: false }) {
13
10
  this.datasource = input.datasource
@@ -188,12 +185,8 @@ class QueryRunner {
188
185
  enrichedQuery[key] = this.enrichQueryFields(fields[key], parameters)
189
186
  } else if (typeof fields[key] === "string") {
190
187
  // enrich string value as normal
191
- let value = fields[key]
192
- // add triple brace to avoid escaping e.g. '=' in cookie header
193
- if (IS_HANDLEBARS.test(value) && !IS_TRIPLE_BRACE.test(value)) {
194
- value = `{${value}}`
195
- }
196
- enrichedQuery[key] = processStringSync(value, parameters, {
188
+ enrichedQuery[key] = processStringSync(fields[key], parameters, {
189
+ noEscaping: true,
197
190
  noHelpers: true,
198
191
  })
199
192
  } else {