@budibase/server 0.9.140-alpha.1 → 0.9.140-alpha.5

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 (203) hide show
  1. package/builder/assets/{index.e8745f5e.js → index.80d850d1.js} +35 -35
  2. package/builder/assets/{vendor.d39b3c1e.js → vendor.820de34b.js} +10 -2
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +798 -530
  5. package/coverage/coverage-final.json +19 -16
  6. package/coverage/lcov-report/api/controllers/analytics.js.html +4 -4
  7. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/application.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/datasource.js.html +3 -3
  14. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/index.html +5 -5
  17. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/index.html +34 -19
  26. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/internal.js.html +242 -47
  28. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1244 -0
  29. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  33. package/coverage/lcov-report/api/controllers/table/index.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/table/utils.js.html +31 -19
  35. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.html +32 -17
  39. package/coverage/lcov-report/api/controllers/view/index.js.html +84 -186
  40. package/coverage/lcov-report/api/controllers/view/utils.js.html +407 -0
  41. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  43. package/coverage/lcov-report/api/index.html +1 -1
  44. package/coverage/lcov-report/api/index.js.html +1 -1
  45. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  46. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/index.html +1 -1
  57. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  74. package/coverage/lcov-report/automations/actions.js.html +1 -1
  75. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  76. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  77. package/coverage/lcov-report/automations/index.html +1 -1
  78. package/coverage/lcov-report/automations/index.js.html +1 -1
  79. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  80. package/coverage/lcov-report/automations/steps/createRow.js.html +10 -19
  81. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/deleteRow.js.html +14 -20
  83. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/index.html +31 -31
  88. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/queryRows.js.html +18 -27
  91. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/updateRow.js.html +12 -21
  95. package/coverage/lcov-report/automations/steps/utils.js.html +23 -23
  96. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  97. package/coverage/lcov-report/automations/thread.js.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  107. package/coverage/lcov-report/automations/utils.js.html +1 -1
  108. package/coverage/lcov-report/constants/index.html +1 -1
  109. package/coverage/lcov-report/constants/index.js.html +1 -1
  110. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  111. package/coverage/lcov-report/constants/screens.js.html +1 -1
  112. package/coverage/lcov-report/db/client.js.html +1 -1
  113. package/coverage/lcov-report/db/inMemoryView.js.html +224 -0
  114. package/coverage/lcov-report/db/index.html +34 -19
  115. package/coverage/lcov-report/db/index.js.html +1 -1
  116. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +4 -4
  117. package/coverage/lcov-report/db/linkedRows/index.html +14 -14
  118. package/coverage/lcov-report/db/linkedRows/index.js.html +18 -9
  119. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  120. package/coverage/lcov-report/db/newid.js.html +1 -1
  121. package/coverage/lcov-report/db/utils.js.html +37 -10
  122. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  123. package/coverage/lcov-report/events/index.html +1 -1
  124. package/coverage/lcov-report/events/index.js.html +1 -1
  125. package/coverage/lcov-report/events/utils.js.html +1 -1
  126. package/coverage/lcov-report/index.html +68 -68
  127. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  128. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  129. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  130. package/coverage/lcov-report/middleware/authorized.js.html +1 -1
  131. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  132. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  133. package/coverage/lcov-report/middleware/index.html +1 -1
  134. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  135. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  136. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  137. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  138. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  139. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  140. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  141. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  142. package/coverage/lcov-report/utilities/global.js.html +1 -1
  143. package/coverage/lcov-report/utilities/index.html +1 -1
  144. package/coverage/lcov-report/utilities/index.js.html +1 -1
  145. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  146. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  147. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  148. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/index.html +15 -15
  150. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +58 -13
  151. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  152. package/coverage/lcov-report/utilities/security.js.html +2 -2
  153. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  154. package/coverage/lcov-report/utilities/users.js.html +1 -1
  155. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  156. package/coverage/lcov.info +1405 -886
  157. package/dist/api/controllers/analytics.js +1 -1
  158. package/dist/api/controllers/datasource.js +2 -2
  159. package/dist/api/controllers/row/ExternalRequest.js +4 -0
  160. package/dist/api/controllers/row/internal.js +97 -23
  161. package/dist/api/controllers/table/index.js +1 -1
  162. package/dist/api/controllers/table/utils.js +13 -11
  163. package/dist/api/controllers/view/index.js +74 -96
  164. package/dist/api/controllers/view/utils.js +102 -0
  165. package/dist/automations/steps/createRow.js +5 -8
  166. package/dist/automations/steps/deleteRow.js +7 -10
  167. package/dist/automations/steps/queryRows.js +11 -14
  168. package/dist/automations/steps/updateRow.js +4 -7
  169. package/dist/db/inMemoryView.js +51 -0
  170. package/dist/db/linkedRows/index.js +5 -2
  171. package/dist/db/utils.js +7 -0
  172. package/dist/environment.js +7 -1
  173. package/dist/integrations/mysql.js +2 -13
  174. package/dist/integrations/postgres.js +8 -14
  175. package/dist/integrations/utils.js +19 -1
  176. package/dist/package.json +10 -12
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/dist/utilities/rowProcessor/index.js +10 -5
  179. package/package.json +11 -13
  180. package/scripts/integrations/service-vehicles/docker-compose.yml +28 -0
  181. package/scripts/integrations/service-vehicles/init.sql +52 -0
  182. package/scripts/integrations/service-vehicles/reset.sh +3 -0
  183. package/src/api/controllers/analytics.js +1 -1
  184. package/src/api/controllers/datasource.js +2 -2
  185. package/src/api/controllers/row/ExternalRequest.ts +5 -1
  186. package/src/api/controllers/row/internal.js +88 -23
  187. package/src/api/controllers/table/index.js +1 -1
  188. package/src/api/controllers/table/utils.js +16 -12
  189. package/src/api/controllers/view/index.js +82 -116
  190. package/src/api/controllers/view/utils.js +109 -0
  191. package/src/api/routes/tests/view.spec.js +1 -1
  192. package/src/automations/steps/createRow.js +5 -8
  193. package/src/automations/steps/deleteRow.js +8 -10
  194. package/src/automations/steps/queryRows.js +11 -14
  195. package/src/automations/steps/updateRow.js +7 -10
  196. package/src/db/inMemoryView.js +48 -0
  197. package/src/db/linkedRows/index.js +5 -2
  198. package/src/db/utils.js +9 -0
  199. package/src/environment.js +8 -1
  200. package/src/integrations/mysql.ts +2 -13
  201. package/src/integrations/postgres.ts +9 -16
  202. package/src/integrations/utils.ts +18 -0
  203. package/src/utilities/rowProcessor/index.js +20 -5
@@ -96,10 +96,11 @@ const TYPE_TRANSFORM_MAP = {
96
96
  * @param {Object} user The user to be used for an appId as well as the createdBy and createdAt fields.
97
97
  * @param {Object} table The table which is to be used for the schema, as well as handling auto IDs incrementing.
98
98
  * @param {Object} row The row which is to be updated with information for the auto columns.
99
+ * @param {Object} opts specific options for function to carry out optional features.
99
100
  * @returns {{row: Object, table: Object}} The updated row and table, the table may need to be updated
100
101
  * for automatic ID purposes.
101
102
  */
102
- function processAutoColumn(user, table, row) {
103
+ function processAutoColumn(user, table, row, opts = { reprocessing: false, noAutoRelationships: false }) {
103
104
  let now = new Date().toISOString();
104
105
  // if a row doesn't have a revision then it doesn't exist yet
105
106
  const creating = !row._rev;
@@ -109,7 +110,7 @@ function processAutoColumn(user, table, row) {
109
110
  }
110
111
  switch (schema.subtype) {
111
112
  case AutoFieldSubTypes.CREATED_BY:
112
- if (creating) {
113
+ if (creating && !opts.reprocessing && !opts.noAutoRelationships) {
113
114
  row[key] = [user.userId];
114
115
  }
115
116
  break;
@@ -119,7 +120,9 @@ function processAutoColumn(user, table, row) {
119
120
  }
120
121
  break;
121
122
  case AutoFieldSubTypes.UPDATED_BY:
122
- row[key] = [user.userId];
123
+ if (!opts.reprocessing && !opts.noAutoRelationships) {
124
+ row[key] = [user.userId];
125
+ }
123
126
  break;
124
127
  case AutoFieldSubTypes.UPDATED_AT:
125
128
  row[key] = now;
@@ -134,6 +137,7 @@ function processAutoColumn(user, table, row) {
134
137
  }
135
138
  return { table, row };
136
139
  }
140
+ exports.processAutoColumn = processAutoColumn;
137
141
  /**
138
142
  * This will coerce a value to the correct types based on the type transform map
139
143
  * @param {object} row The value to coerce
@@ -156,9 +160,10 @@ exports.coerce = (row, type) => {
156
160
  * @param {object} user the user which is performing the input.
157
161
  * @param {object} row the row which is being created/updated.
158
162
  * @param {object} table the table which the row is being saved to.
163
+ * @param {object} opts some input processing options (like disabling auto-column relationships).
159
164
  * @returns {object} the row which has been prepared to be written to the DB.
160
165
  */
161
- exports.inputProcessing = (user = {}, table, row) => {
166
+ exports.inputProcessing = (user = {}, table, row, opts = { noAutoRelationships: false }) => {
162
167
  let clonedRow = cloneDeep(row);
163
168
  // need to copy the table so it can be differenced on way out
164
169
  const copiedTable = cloneDeep(table);
@@ -182,7 +187,7 @@ exports.inputProcessing = (user = {}, table, row) => {
182
187
  }
183
188
  }
184
189
  // handle auto columns - this returns an object like {table, row}
185
- return processAutoColumn(user, copiedTable, clonedRow);
190
+ return processAutoColumn(user, copiedTable, clonedRow, opts);
186
191
  };
187
192
  /**
188
193
  * This function enriches the input rows with anything they are supposed to contain, for example
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "0.9.140-alpha.1",
4
+ "version": "0.9.140-alpha.5",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -13,7 +13,7 @@
13
13
  "postbuild": "copyfiles -u 1 src/**/*.svelte dist/ && copyfiles -u 1 src/**/*.hbs dist/ && copyfiles -u 1 src/**/*.json dist/",
14
14
  "test": "jest --coverage --maxWorkers=2",
15
15
  "test:watch": "jest --watch",
16
- "predocker": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client",
16
+ "predocker": "copyfiles -f ../client/dist/budibase-client.js ../standard-components/manifest.json client",
17
17
  "build:docker": "yarn run predocker && docker build . -t app-service",
18
18
  "run:docker": "node dist/index.js",
19
19
  "dev:stack:up": "node scripts/dev/manage.js up",
@@ -23,10 +23,9 @@
23
23
  "format": "prettier --config ../../.prettierrc.json 'src/**/*.ts' --write",
24
24
  "lint": "eslint --fix src/",
25
25
  "lint:fix": "yarn run format && yarn run lint",
26
+ "initialise": "node scripts/initialise.js",
26
27
  "multi:enable": "node scripts/multiTenancy.js enable",
27
- "multi:disable": "node scripts/multiTenancy.js disable",
28
- "selfhost:enable": "node scripts/selfhost.js enable",
29
- "selfhost:disable": "node scripts/selfhost.js disable"
28
+ "multi:disable": "node scripts/multiTenancy.js disable"
30
29
  },
31
30
  "jest": {
32
31
  "preset": "ts-jest",
@@ -49,8 +48,7 @@
49
48
  "!src/automations/tests/**/*",
50
49
  "!src/utilities/fileProcessor.js",
51
50
  "!src/utilities/fileSystem/**/*",
52
- "!src/utilities/redis.js",
53
- "!src/api/controllers/row/internalSearch.js"
51
+ "!src/utilities/redis.js"
54
52
  ],
55
53
  "coverageReporters": [
56
54
  "lcov",
@@ -64,9 +62,9 @@
64
62
  "author": "Budibase",
65
63
  "license": "AGPL-3.0-or-later",
66
64
  "dependencies": {
67
- "@budibase/auth": "^0.9.140-alpha.1",
68
- "@budibase/client": "^0.9.140-alpha.1",
69
- "@budibase/string-templates": "^0.9.140-alpha.1",
65
+ "@budibase/auth": "^0.9.140-alpha.5",
66
+ "@budibase/client": "^0.9.140-alpha.5",
67
+ "@budibase/string-templates": "^0.9.140-alpha.5",
70
68
  "@elastic/elasticsearch": "7.10.0",
71
69
  "@koa/router": "8.0.0",
72
70
  "@sendgrid/mail": "7.1.1",
@@ -98,12 +96,13 @@
98
96
  "lodash": "4.17.21",
99
97
  "mongodb": "3.6.3",
100
98
  "mssql": "6.2.3",
101
- "mysql": "^2.18.1",
99
+ "mysql": "2.18.1",
102
100
  "node-fetch": "2.6.0",
103
101
  "open": "7.3.0",
104
102
  "pg": "8.5.1",
105
103
  "pino-pretty": "4.0.0",
106
104
  "pouchdb": "7.2.1",
105
+ "pouchdb-adapter-memory": "^7.2.1",
107
106
  "pouchdb-all-dbs": "1.0.2",
108
107
  "pouchdb-find": "^7.2.2",
109
108
  "pouchdb-replication-stream": "1.2.9",
@@ -133,7 +132,6 @@
133
132
  "express": "^4.17.1",
134
133
  "jest": "^27.0.5",
135
134
  "nodemon": "^2.0.4",
136
- "pouchdb-adapter-memory": "^7.2.1",
137
135
  "prettier": "^2.3.1",
138
136
  "rimraf": "^3.0.2",
139
137
  "supertest": "^4.0.2",
@@ -142,5 +140,5 @@
142
140
  "typescript": "^4.3.5",
143
141
  "update-dotenv": "^1.1.1"
144
142
  },
145
- "gitHead": "792316e501277a278b8a096bb1f6cdaed1bc5b89"
143
+ "gitHead": "15cd5e45144b43db3af75d58bbe695dc497b7cbd"
146
144
  }
@@ -0,0 +1,28 @@
1
+ version: "3.8"
2
+ services:
3
+ db:
4
+ container_name: postgres-vehicle
5
+ image: postgres
6
+ restart: always
7
+ environment:
8
+ POSTGRES_USER: root
9
+ POSTGRES_PASSWORD: root
10
+ POSTGRES_DB: main
11
+ ports:
12
+ - "5432:5432"
13
+ volumes:
14
+ #- pg_data:/var/lib/postgresql/data/
15
+ - ./init.sql:/docker-entrypoint-initdb.d/init.sql
16
+
17
+ pgadmin:
18
+ container_name: pgadmin
19
+ image: dpage/pgadmin4
20
+ restart: always
21
+ environment:
22
+ PGADMIN_DEFAULT_EMAIL: root@root.com
23
+ PGADMIN_DEFAULT_PASSWORD: root
24
+ ports:
25
+ - "5050:80"
26
+
27
+ #volumes:
28
+ # pg_data:
@@ -0,0 +1,52 @@
1
+ SELECT 'CREATE DATABASE main'
2
+ WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'main')\gexec
3
+ CREATE TABLE Vehicles (
4
+ id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
5
+ Registration text COLLATE pg_catalog."default",
6
+ Make text COLLATE pg_catalog."default",
7
+ Model text COLLATE pg_catalog."default",
8
+ Colour text COLLATE pg_catalog."default",
9
+ Year smallint,
10
+ CONSTRAINT Vehicles_pkey PRIMARY KEY (id)
11
+ );
12
+
13
+ CREATE TABLE ServiceLog (
14
+ id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
15
+ Description text COLLATE pg_catalog."default",
16
+ VehicleId bigint,
17
+ ServiceDate timestamp without time zone,
18
+ Category text COLLATE pg_catalog."default",
19
+ Mileage bigint,
20
+ CONSTRAINT ServiceLog_pkey PRIMARY KEY (id),
21
+ CONSTRAINT vehicle_foreign_key FOREIGN KEY (VehicleId)
22
+ REFERENCES Vehicles (id) MATCH SIMPLE
23
+ ON UPDATE NO ACTION
24
+ ON DELETE NO ACTION
25
+ );
26
+
27
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
28
+ VALUES ('FAZ 9837','Volkswagen','Polo','White',2002);
29
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
30
+ VALUES ('JHI 8827','BMW','M3','Black',2013);
31
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
32
+ VALUES ('D903PI','Volvo','XC40','Grey',2014);
33
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
34
+ VALUES ('YFI002','Volkswagen','Golf','Dark Blue',2018);
35
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
36
+ VALUES ('HGT5677','Skoda','Octavia','Graphite',2009);
37
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
38
+ VALUES ('PPF9276','Skoda','Octavia','Graphite',2021);
39
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
40
+ VALUES ('J893FT','Toyota','Corolla','Red',2015);
41
+ INSERT INTO Vehicles (Registration, Make, Model, Colour, Year)
42
+ VALUES ('MJK776','Honda','HR-V','Silver',2015);
43
+
44
+
45
+ INSERT INTO ServiceLog (Description, VehicleId, ServiceDate, Category, Mileage)
46
+ VALUES ('Change front brakes', 1, '2021-05-04', 'Brakes', 20667);
47
+ INSERT INTO ServiceLog (Description, VehicleId, ServiceDate, Category, Mileage)
48
+ VALUES ('Tyres - full set', 1, '2021-05-04', 'Brakes', 20667);
49
+ INSERT INTO ServiceLog (Description, VehicleId, ServiceDate, Category, Mileage)
50
+ VALUES ('Engine tune up', 2, '2021-07-14', 'Brakes', 50889);
51
+ INSERT INTO ServiceLog (Description, VehicleId, ServiceDate, Category, Mileage)
52
+ VALUES ('Replace transmission', 3, '2021-09-26', 'Transmission', 98002);
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ docker-compose down
3
+ docker volume prune -f
@@ -2,6 +2,6 @@ const env = require("../../environment")
2
2
 
3
3
  exports.isEnabled = async function (ctx) {
4
4
  ctx.body = {
5
- enabled: env.ENABLE_ANALYTICS === "true",
5
+ enabled: !env.SELF_HOSTED && env.ENABLE_ANALYTICS === "true",
6
6
  }
7
7
  }
@@ -51,7 +51,7 @@ exports.buildSchemaFromDb = async function (ctx) {
51
51
  await connector.buildSchema(datasource._id, datasource.entities)
52
52
  datasource.entities = connector.tables
53
53
 
54
- const response = await db.post(datasource)
54
+ const response = await db.put(datasource)
55
55
  datasource._rev = response.rev
56
56
 
57
57
  ctx.body = datasource
@@ -89,7 +89,7 @@ exports.save = async function (ctx) {
89
89
  ...ctx.request.body,
90
90
  }
91
91
 
92
- const response = await db.post(datasource)
92
+ const response = await db.put(datasource)
93
93
  datasource._rev = response.rev
94
94
 
95
95
  // Drain connection pools when configuration is changed
@@ -437,7 +437,11 @@ module External {
437
437
  for (let [colName, { isMany, rows, tableId }] of Object.entries(
438
438
  related
439
439
  )) {
440
- const table = this.getTable(tableId)
440
+ const table: Table = this.getTable(tableId)
441
+ // if its not the foreign key skip it, nothing to do
442
+ if (table.primary && table.primary.indexOf(colName) !== -1) {
443
+ continue
444
+ }
441
445
  for (let row of rows) {
442
446
  const filters = buildFilters(generateIdForRow(row, table), {}, table)
443
447
  // safety check, if there are no filters on deletion bad things happen
@@ -5,17 +5,22 @@ const {
5
5
  generateRowID,
6
6
  DocumentTypes,
7
7
  InternalTables,
8
+ generateMemoryViewID,
8
9
  } = require("../../../db/utils")
9
10
  const userController = require("../user")
10
11
  const {
11
12
  inputProcessing,
12
13
  outputProcessing,
14
+ processAutoColumn,
13
15
  } = require("../../../utilities/rowProcessor")
14
16
  const { FieldTypes } = require("../../../constants")
15
17
  const { isEqual } = require("lodash")
16
18
  const { validate, findRow } = require("./utils")
17
19
  const { fullSearch, paginatedSearch } = require("./internalSearch")
18
20
  const { getGlobalUsersFromMetadata } = require("../../../utilities/global")
21
+ const inMemoryViews = require("../../../db/inMemoryView")
22
+ const env = require("../../../environment")
23
+ const { migrateToInMemoryView } = require("../view/utils")
19
24
 
20
25
  const CALCULATION_TYPES = {
21
26
  SUM: "sum",
@@ -25,17 +30,84 @@ const CALCULATION_TYPES = {
25
30
 
26
31
  async function storeResponse(ctx, db, row, oldTable, table) {
27
32
  row.type = "row"
28
- const response = await db.put(row)
29
33
  // don't worry about rev, tables handle rev/lastID updates
34
+ // if another row has been written since processing this will
35
+ // handle the auto ID clash
30
36
  if (!isEqual(oldTable, table)) {
31
- await db.put(table)
37
+ try {
38
+ await db.put(table)
39
+ } catch (err) {
40
+ if (err.status === 409) {
41
+ const updatedTable = await db.get(table._id)
42
+ let response = processAutoColumn(null, updatedTable, row, {
43
+ reprocessing: true,
44
+ })
45
+ await db.put(response.table)
46
+ row = response.row
47
+ } else {
48
+ throw err
49
+ }
50
+ }
32
51
  }
52
+ const response = await db.put(row)
33
53
  row._rev = response.rev
34
54
  // process the row before return, to include relationships
35
55
  row = await outputProcessing(ctx, table, row, { squash: false })
36
56
  return { row, table }
37
57
  }
38
58
 
59
+ // doesn't do the outputProcessing
60
+ async function getRawTableData(ctx, db, tableId) {
61
+ let rows
62
+ if (tableId === InternalTables.USER_METADATA) {
63
+ await userController.fetchMetadata(ctx)
64
+ rows = ctx.body
65
+ } else {
66
+ const response = await db.allDocs(
67
+ getRowParams(tableId, null, {
68
+ include_docs: true,
69
+ })
70
+ )
71
+ rows = response.rows.map(row => row.doc)
72
+ }
73
+ return rows
74
+ }
75
+
76
+ async function getView(db, viewName) {
77
+ let viewInfo
78
+ async function getFromDesignDoc() {
79
+ const designDoc = await db.get("_design/database")
80
+ viewInfo = designDoc.views[viewName]
81
+ return viewInfo
82
+ }
83
+ let migrate = false
84
+ if (env.SELF_HOSTED) {
85
+ viewInfo = await getFromDesignDoc()
86
+ } else {
87
+ try {
88
+ viewInfo = await db.get(generateMemoryViewID(viewName))
89
+ if (viewInfo) {
90
+ viewInfo = viewInfo.view
91
+ }
92
+ } catch (err) {
93
+ // check if it can be retrieved from design doc (needs migrated)
94
+ if (err.status !== 404) {
95
+ viewInfo = null
96
+ } else {
97
+ viewInfo = await getFromDesignDoc()
98
+ migrate = !!viewInfo
99
+ }
100
+ }
101
+ }
102
+ if (migrate) {
103
+ await migrateToInMemoryView(db, viewName)
104
+ }
105
+ if (!viewInfo) {
106
+ throw "View does not exist."
107
+ }
108
+ return viewInfo
109
+ }
110
+
39
111
  exports.patch = async ctx => {
40
112
  const appId = ctx.appId
41
113
  const db = new CouchDB(appId)
@@ -139,15 +211,18 @@ exports.fetchView = async ctx => {
139
211
 
140
212
  const db = new CouchDB(appId)
141
213
  const { calculation, group, field } = ctx.query
142
- const designDoc = await db.get("_design/database")
143
- const viewInfo = designDoc.views[viewName]
144
- if (!viewInfo) {
145
- throw "View does not exist."
214
+ const viewInfo = await getView(db, viewName)
215
+ let response
216
+ if (env.SELF_HOSTED) {
217
+ response = await db.query(`database/${viewName}`, {
218
+ include_docs: !calculation,
219
+ group: !!group,
220
+ })
221
+ } else {
222
+ const tableId = viewInfo.meta.tableId
223
+ const data = await getRawTableData(ctx, db, tableId)
224
+ response = await inMemoryViews.runView(viewInfo, calculation, group, data)
146
225
  }
147
- const response = await db.query(`database/${viewName}`, {
148
- include_docs: !calculation,
149
- group: !!group,
150
- })
151
226
 
152
227
  let rows
153
228
  if (!calculation) {
@@ -191,19 +266,9 @@ exports.fetch = async ctx => {
191
266
  const appId = ctx.appId
192
267
  const db = new CouchDB(appId)
193
268
 
194
- let rows,
195
- table = await db.get(ctx.params.tableId)
196
- if (ctx.params.tableId === InternalTables.USER_METADATA) {
197
- await userController.fetchMetadata(ctx)
198
- rows = ctx.body
199
- } else {
200
- const response = await db.allDocs(
201
- getRowParams(ctx.params.tableId, null, {
202
- include_docs: true,
203
- })
204
- )
205
- rows = response.rows.map(row => row.doc)
206
- }
269
+ const tableId = ctx.params.tableId
270
+ let table = await db.get(tableId)
271
+ let rows = await getRawTableData(ctx, db, tableId)
207
272
  return outputProcessing(ctx, table, rows)
208
273
  }
209
274
 
@@ -145,7 +145,7 @@ exports.save = async function (ctx) {
145
145
  if (updatedRows && updatedRows.length !== 0) {
146
146
  await db.bulkDocs(updatedRows)
147
147
  }
148
- const result = await db.post(tableToSave)
148
+ const result = await db.put(tableToSave)
149
149
  tableToSave._rev = result.rev
150
150
 
151
151
  tableToSave = await tableSaveFunctions.after(tableToSave)
@@ -68,23 +68,17 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
68
68
  // Populate the table with rows imported from CSV in a bulk update
69
69
  const data = await csvParser.transform(dataImport)
70
70
 
71
+ let finalData = []
71
72
  for (let i = 0; i < data.length; i++) {
72
73
  let row = data[i]
73
74
  row._id = generateRowID(table._id)
74
75
  row.tableId = table._id
75
- const processed = inputProcessing(user, table, row)
76
+ const processed = inputProcessing(user, table, row, {
77
+ noAutoRelationships: true,
78
+ })
76
79
  table = processed.table
77
80
  row = processed.row
78
81
 
79
- // make sure link rows are up to date
80
- row = await linkRows.updateLinks({
81
- appId,
82
- eventType: linkRows.EventType.ROW_SAVE,
83
- row,
84
- tableId: row.tableId,
85
- table,
86
- })
87
-
88
82
  for (let [fieldName, schema] of Object.entries(table.schema)) {
89
83
  // check whether the options need to be updated for inclusion as part of the data import
90
84
  if (
@@ -98,10 +92,20 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
98
92
  ]
99
93
  }
100
94
  }
101
- data[i] = row
95
+
96
+ // make sure link rows are up to date
97
+ finalData.push(
98
+ linkRows.updateLinks({
99
+ appId,
100
+ eventType: linkRows.EventType.ROW_SAVE,
101
+ row,
102
+ tableId: row.tableId,
103
+ table,
104
+ })
105
+ )
102
106
  }
103
107
 
104
- await db.bulkDocs(data)
108
+ await db.bulkDocs(await Promise.all(finalData))
105
109
  let response = await db.put(table)
106
110
  table._rev = response._rev
107
111
  }