@budibase/server 1.0.49 → 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.
- package/__mocks__/arangojs.ts +1 -1
- package/__mocks__/aws-sdk.ts +4 -4
- package/__mocks__/mongodb.ts +4 -5
- package/__mocks__/mssql.ts +3 -3
- package/__mocks__/node-fetch.ts +2 -1
- package/__mocks__/pg.ts +3 -5
- package/builder/assets/index.c0cc369d.css +6 -0
- package/builder/assets/{index.2c37968e.js → index.ff2bad21.js} +252 -249
- package/builder/assets/{vendor.f9faf6ab.js → vendor.5ad9695a.js} +202 -106
- package/builder/index.html +3 -3
- package/coverage/clover.xml +3105 -2814
- package/coverage/coverage-final.json +106 -101
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +257 -152
- package/coverage/lcov-report/api/controllers/auth.js.html +22 -13
- package/coverage/lcov-report/api/controllers/automation.js.html +39 -69
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +8 -11
- package/coverage/lcov-report/api/controllers/component.js.html +13 -16
- package/coverage/lcov-report/api/controllers/datasource.js.html +81 -51
- package/coverage/lcov-report/api/controllers/dev.js.html +6 -6
- package/coverage/lcov-report/api/controllers/index.html +78 -78
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
- package/coverage/lcov-report/api/controllers/metadata.js.html +6 -21
- package/coverage/lcov-report/api/controllers/migrations.js.html +119 -0
- package/coverage/lcov-report/api/controllers/permission.js.html +19 -19
- package/coverage/lcov-report/api/controllers/query/index.html +10 -10
- package/coverage/lcov-report/api/controllers/query/index.js.html +38 -35
- package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
- package/coverage/lcov-report/api/controllers/role.js.html +16 -16
- package/coverage/lcov-report/api/controllers/routing.js.html +7 -10
- package/coverage/lcov-report/api/controllers/row/external.js.html +48 -141
- package/coverage/lcov-report/api/controllers/row/index.html +55 -40
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +118 -226
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +52 -34
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +548 -0
- package/coverage/lcov-report/api/controllers/row/utils.js.html +47 -62
- package/coverage/lcov-report/api/controllers/screen.js.html +15 -21
- package/coverage/lcov-report/api/controllers/script.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +599 -0
- package/coverage/lcov-report/api/controllers/table/external.js.html +25 -34
- package/coverage/lcov-report/api/controllers/table/index.html +58 -43
- package/coverage/lcov-report/api/controllers/table/index.js.html +58 -82
- package/coverage/lcov-report/api/controllers/table/internal.js.html +81 -66
- package/coverage/lcov-report/api/controllers/table/utils.js.html +218 -110
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +79 -76
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
- package/coverage/lcov-report/api/controllers/view/index.html +16 -16
- package/coverage/lcov-report/api/controllers/view/index.js.html +27 -33
- package/coverage/lcov-report/api/controllers/view/utils.js.html +35 -20
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
- package/coverage/lcov-report/api/controllers/webhook.js.html +34 -28
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +8 -8
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +18 -18
- package/coverage/lcov-report/api/routes/index.js.html +3 -3
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/{hosting.js.html → migrations.js.html} +17 -14
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +17 -2
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +24 -24
- package/coverage/lcov-report/automations/automationUtils.js.html +7 -10
- package/coverage/lcov-report/automations/bullboard.js.html +16 -16
- package/coverage/lcov-report/automations/index.html +18 -18
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
- package/coverage/lcov-report/automations/steps/createRow.js.html +13 -22
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
- package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
- package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
- package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
- package/coverage/lcov-report/automations/steps/index.html +13 -13
- package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
- package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
- package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
- package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
- package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +61 -55
- package/coverage/lcov-report/automations/utils.js.html +54 -42
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +53 -26
- package/coverage/lcov-report/constants/layouts.js.html +5 -5
- package/coverage/lcov-report/constants/screens.js.html +4 -4
- package/coverage/lcov-report/db/client.js.html +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +25 -37
- package/coverage/lcov-report/db/linkedRows/index.html +27 -27
- package/coverage/lcov-report/db/linkedRows/index.js.html +51 -96
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +42 -42
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +87 -87
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +5 -5
- package/coverage/lcov-report/events/utils.js.html +3 -3
- package/coverage/lcov-report/index.html +135 -120
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +173 -65
- package/coverage/lcov-report/middleware/builder.js.html +10 -10
- package/coverage/lcov-report/middleware/currentapp.js.html +95 -83
- package/coverage/lcov-report/middleware/index.html +38 -38
- package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +281 -53
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +30 -24
- package/coverage/lcov-report/threads/index.html +26 -26
- package/coverage/lcov-report/threads/index.js.html +10 -10
- package/coverage/lcov-report/threads/query.js.html +39 -24
- package/coverage/lcov-report/threads/utils.js.html +14 -14
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
- package/coverage/lcov-report/utilities/global.js.html +58 -49
- package/coverage/lcov-report/utilities/index.html +37 -37
- package/coverage/lcov-report/utilities/index.js.html +43 -73
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +7 -7
- package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +97 -103
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +75 -27
- package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
- package/coverage/lcov-report/utilities/security.js.html +8 -8
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +141 -0
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +359 -0
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +305 -0
- package/coverage/lcov-report/{api/controllers/hosting.js.html → utilities/usageQuota/usageQuoteReset.js.html} +36 -48
- package/coverage/lcov-report/utilities/users.js.html +9 -9
- package/coverage/lcov-report/utilities/workerRequests.js.html +43 -112
- package/coverage/lcov.info +5010 -4425
- package/dist/api/controllers/application.js +90 -60
- package/dist/api/controllers/auth.js +8 -5
- package/dist/api/controllers/automation.js +14 -19
- package/dist/api/controllers/cloud.js +2 -3
- package/dist/api/controllers/component.js +3 -4
- package/dist/api/controllers/datasource.js +20 -10
- package/dist/api/controllers/deploy/Deployment.js +3 -6
- package/dist/api/controllers/deploy/index.js +12 -13
- package/dist/api/controllers/dev.js +5 -5
- package/dist/api/controllers/layout.js +3 -3
- package/dist/api/controllers/metadata.js +4 -4
- package/dist/api/controllers/migrations.js +21 -0
- package/dist/api/controllers/permission.js +4 -4
- package/dist/api/controllers/query/import/index.js +4 -6
- package/dist/api/controllers/query/index.js +11 -10
- package/dist/api/controllers/role.js +5 -5
- package/dist/api/controllers/routing.js +5 -6
- package/dist/api/controllers/row/ExternalRequest.js +90 -67
- package/dist/api/controllers/row/external.js +14 -22
- package/dist/api/controllers/row/internal.js +55 -93
- package/dist/api/controllers/row/internalSearch.js +23 -17
- package/dist/api/controllers/row/staticFormula.js +147 -0
- package/dist/api/controllers/row/utils.js +13 -14
- package/dist/api/controllers/screen.js +5 -7
- package/dist/api/controllers/static/index.js +62 -16
- package/dist/api/controllers/table/bulkFormula.js +159 -0
- package/dist/api/controllers/table/external.js +7 -10
- package/dist/api/controllers/table/index.js +16 -13
- package/dist/api/controllers/table/internal.js +22 -16
- package/dist/api/controllers/table/utils.js +62 -35
- package/dist/api/controllers/user.js +43 -43
- package/dist/api/controllers/view/index.js +8 -10
- package/dist/api/controllers/view/utils.js +9 -4
- package/dist/api/controllers/webhook.js +10 -8
- package/dist/api/routes/index.js +2 -2
- package/dist/api/routes/migrations.js +9 -0
- package/dist/api/routes/static.js +2 -1
- package/dist/api/routes/tests/utilities/TestFunctions.js +37 -17
- package/dist/app.js +35 -5
- package/dist/automations/automationUtils.js +2 -3
- package/dist/automations/steps/createRow.js +3 -5
- package/dist/automations/steps/deleteRow.js +1 -4
- package/dist/automations/steps/updateRow.js +1 -1
- package/dist/automations/triggers.js +27 -25
- package/dist/automations/utils.js +10 -5
- package/dist/constants/index.js +7 -0
- package/dist/db/linkedRows/LinkController.js +3 -7
- package/dist/db/linkedRows/index.js +16 -27
- package/dist/db/linkedRows/linkUtils.js +6 -6
- package/dist/db/views/staticViews.js +9 -10
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +4 -1
- package/dist/integrations/base/sql.js +62 -21
- package/dist/integrations/googlesheets.js +340 -0
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/utils.js +60 -9
- package/dist/middleware/authorized.js +57 -30
- package/dist/middleware/builder.js +2 -2
- package/dist/middleware/currentapp.js +41 -37
- package/dist/middleware/usageQuota.js +82 -15
- package/dist/migrations/functions/appUrls.js +46 -0
- package/dist/migrations/functions/quotas1.js +50 -0
- package/dist/migrations/functions/usageQuotas/index.js +20 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +29 -0
- package/dist/migrations/functions/usageQuotas/syncRows.js +33 -0
- package/dist/migrations/functions/userEmailViewCasing.js +24 -0
- package/dist/migrations/index.js +62 -0
- package/dist/package.json +8 -5
- package/dist/tests/utilities/TestConfiguration.js +80 -50
- package/dist/threads/automation.js +13 -11
- package/dist/threads/query.js +15 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +4 -3
- package/dist/utilities/global.js +15 -12
- package/dist/utilities/index.js +7 -17
- package/dist/utilities/routing/index.js +5 -5
- package/dist/utilities/rowProcessor/index.js +23 -17
- package/dist/utilities/rowProcessor/utils.js +14 -4
- package/dist/utilities/{usageQuota.js → usageQuota/index.js} +45 -31
- package/dist/utilities/usageQuota/rows.js +78 -0
- package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
- package/dist/utilities/users.js +3 -3
- package/dist/utilities/workerRequests.js +4 -24
- package/nodemon.json +1 -1
- package/package.json +9 -6
- package/scripts/integrations/mssql/data/Dockerfile +1 -1
- package/scripts/integrations/mssql/data/setup.sql +17 -4
- package/scripts/integrations/postgres/init.sql +11 -6
- package/scripts/likeCypress.ts +1 -1
- package/src/api/controllers/application.js +85 -50
- package/src/api/controllers/auth.js +8 -5
- package/src/api/controllers/automation.js +13 -23
- package/src/api/controllers/cloud.js +2 -3
- package/src/api/controllers/component.js +3 -4
- package/src/api/controllers/datasource.js +21 -11
- package/src/api/controllers/deploy/Deployment.js +3 -7
- package/src/api/controllers/deploy/index.js +20 -13
- package/src/api/controllers/dev.js +5 -5
- package/src/api/controllers/layout.js +3 -3
- package/src/api/controllers/metadata.js +4 -9
- package/src/api/controllers/migrations.js +13 -0
- package/src/api/controllers/permission.js +4 -4
- package/src/api/controllers/query/import/index.ts +4 -6
- package/src/api/controllers/query/import/tests/index.spec.js +2 -1
- package/src/api/controllers/query/index.js +11 -10
- package/src/api/controllers/role.js +5 -5
- package/src/api/controllers/routing.js +5 -6
- package/src/api/controllers/row/ExternalRequest.ts +67 -43
- package/src/api/controllers/row/external.js +27 -58
- package/src/api/controllers/row/internal.js +54 -90
- package/src/api/controllers/row/internalSearch.js +23 -17
- package/src/api/controllers/row/staticFormula.js +156 -0
- package/src/api/controllers/row/utils.js +13 -18
- package/src/api/controllers/screen.js +5 -7
- package/src/api/controllers/static/index.js +66 -15
- package/src/api/controllers/table/bulkFormula.js +173 -0
- package/src/api/controllers/table/external.js +7 -10
- package/src/api/controllers/table/index.js +20 -28
- package/src/api/controllers/table/internal.js +24 -19
- package/src/api/controllers/table/utils.js +78 -42
- package/src/api/controllers/user.js +46 -45
- package/src/api/controllers/view/index.js +8 -10
- package/src/api/controllers/view/utils.js +9 -4
- package/src/api/controllers/webhook.js +10 -8
- package/src/api/routes/index.js +2 -2
- package/src/api/routes/migrations.js +14 -0
- package/src/api/routes/static.js +5 -0
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/auth.spec.js +1 -2
- package/src/api/routes/tests/automation.spec.js +1 -0
- package/src/api/routes/tests/misc.spec.js +0 -1
- package/src/api/routes/tests/routing.spec.js +21 -12
- package/src/api/routes/tests/row.spec.js +7 -4
- package/src/api/routes/tests/static.spec.js +98 -0
- package/src/api/routes/tests/utilities/TestFunctions.js +39 -17
- package/src/app.ts +18 -5
- package/src/automations/automationUtils.js +2 -3
- package/src/automations/steps/createRow.js +2 -5
- package/src/automations/steps/deleteRow.js +1 -4
- package/src/automations/steps/updateRow.js +1 -1
- package/src/automations/triggers.js +33 -31
- package/src/automations/utils.js +9 -5
- package/src/constants/index.js +9 -0
- package/src/db/linkedRows/LinkController.js +3 -7
- package/src/db/linkedRows/index.js +16 -31
- package/src/db/linkedRows/linkUtils.js +6 -6
- package/src/db/tests/linkController.spec.js +0 -1
- package/src/db/tests/linkTests.spec.js +5 -6
- package/src/db/views/staticViews.js +8 -10
- package/src/definitions/common.ts +3 -0
- package/src/definitions/datasource.ts +3 -0
- package/src/environment.js +4 -1
- package/src/integrations/base/sql.ts +75 -29
- package/src/integrations/googlesheets.ts +353 -0
- package/src/integrations/index.ts +3 -0
- package/src/integrations/tests/sql.spec.js +16 -0
- package/src/integrations/utils.ts +75 -12
- package/src/middleware/authorized.js +66 -30
- package/src/middleware/builder.js +2 -2
- package/src/middleware/currentapp.js +50 -46
- package/src/middleware/tests/authorized.spec.js +13 -6
- package/src/middleware/tests/currentapp.spec.js +6 -0
- package/src/middleware/tests/usageQuota.spec.js +18 -24
- package/src/middleware/usageQuota.js +93 -17
- package/src/migrations/functions/appUrls.ts +34 -0
- package/src/migrations/functions/quotas1.ts +20 -0
- package/src/migrations/functions/tests/appUrls.spec.js +29 -0
- package/src/migrations/functions/tests/quotas1.spec.js +27 -0
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +25 -0
- package/src/migrations/functions/usageQuotas/index.ts +8 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +18 -0
- package/src/migrations/functions/usageQuotas/syncRows.ts +22 -0
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +37 -0
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +43 -0
- package/src/migrations/functions/userEmailViewCasing.ts +13 -0
- package/src/migrations/index.ts +56 -0
- package/src/module.d.ts +3 -0
- package/src/tests/utilities/TestConfiguration.js +82 -55
- package/src/threads/automation.js +17 -15
- package/src/threads/query.js +17 -12
- package/src/utilities/fileSystem/index.js +4 -3
- package/src/utilities/global.js +15 -12
- package/src/utilities/index.js +7 -17
- package/src/utilities/routing/index.js +5 -5
- package/src/utilities/rowProcessor/index.js +25 -27
- package/src/utilities/rowProcessor/utils.js +23 -7
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
- package/src/utilities/usageQuota/index.js +93 -0
- package/src/utilities/usageQuota/rows.js +75 -0
- package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
- package/src/utilities/users.js +3 -3
- package/src/utilities/workerRequests.js +4 -27
- package/tsconfig.json +2 -1
- package/builder/assets/index.39e01193.css +0 -1
- package/dist/api/controllers/hosting.js +0 -30
- package/dist/api/routes/hosting.js +0 -11
- package/src/api/controllers/hosting.js +0 -22
- package/src/api/routes/hosting.js +0 -13
- package/src/api/routes/tests/hosting.spec.js +0 -36
- package/src/utilities/usageQuota.js +0 -73
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
const CouchDB = require("../../../db")
|
|
2
1
|
const linkRows = require("../../../db/linkedRows")
|
|
3
2
|
const {
|
|
4
|
-
getRowParams,
|
|
5
3
|
generateRowID,
|
|
4
|
+
getRowParams,
|
|
6
5
|
DocumentTypes,
|
|
7
6
|
InternalTables,
|
|
8
7
|
} = require("../../../db/utils")
|
|
@@ -10,11 +9,9 @@ const userController = require("../user")
|
|
|
10
9
|
const {
|
|
11
10
|
inputProcessing,
|
|
12
11
|
outputProcessing,
|
|
13
|
-
processAutoColumn,
|
|
14
12
|
cleanupAttachments,
|
|
15
13
|
} = require("../../../utilities/rowProcessor")
|
|
16
14
|
const { FieldTypes } = require("../../../constants")
|
|
17
|
-
const { isEqual } = require("lodash")
|
|
18
15
|
const { validate, findRow } = require("./utils")
|
|
19
16
|
const { fullSearch, paginatedSearch } = require("./internalSearch")
|
|
20
17
|
const { getGlobalUsersFromMetadata } = require("../../../utilities/global")
|
|
@@ -27,6 +24,8 @@ const {
|
|
|
27
24
|
getFromMemoryDoc,
|
|
28
25
|
} = require("../view/utils")
|
|
29
26
|
const { cloneDeep } = require("lodash/fp")
|
|
27
|
+
const { getAppDB } = require("@budibase/backend-core/context")
|
|
28
|
+
const { finaliseRow, updateRelatedFormula } = require("./staticFormula")
|
|
30
29
|
|
|
31
30
|
const CALCULATION_TYPES = {
|
|
32
31
|
SUM: "sum",
|
|
@@ -34,51 +33,6 @@ const CALCULATION_TYPES = {
|
|
|
34
33
|
STATS: "stats",
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
async function storeResponse(ctx, db, row, oldTable, table) {
|
|
38
|
-
row.type = "row"
|
|
39
|
-
// don't worry about rev, tables handle rev/lastID updates
|
|
40
|
-
// if another row has been written since processing this will
|
|
41
|
-
// handle the auto ID clash
|
|
42
|
-
if (!isEqual(oldTable, table)) {
|
|
43
|
-
try {
|
|
44
|
-
await db.put(table)
|
|
45
|
-
} catch (err) {
|
|
46
|
-
if (err.status === 409) {
|
|
47
|
-
const updatedTable = await db.get(table._id)
|
|
48
|
-
let response = processAutoColumn(null, updatedTable, row, {
|
|
49
|
-
reprocessing: true,
|
|
50
|
-
})
|
|
51
|
-
await db.put(response.table)
|
|
52
|
-
row = response.row
|
|
53
|
-
} else {
|
|
54
|
-
throw err
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const response = await db.put(row)
|
|
59
|
-
row._rev = response.rev
|
|
60
|
-
// process the row before return, to include relationships
|
|
61
|
-
row = await outputProcessing(ctx, table, row, { squash: false })
|
|
62
|
-
return { row, table }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// doesn't do the outputProcessing
|
|
66
|
-
async function getRawTableData(ctx, db, tableId) {
|
|
67
|
-
let rows
|
|
68
|
-
if (tableId === InternalTables.USER_METADATA) {
|
|
69
|
-
await userController.fetchMetadata(ctx)
|
|
70
|
-
rows = ctx.body
|
|
71
|
-
} else {
|
|
72
|
-
const response = await db.allDocs(
|
|
73
|
-
getRowParams(tableId, null, {
|
|
74
|
-
include_docs: true,
|
|
75
|
-
})
|
|
76
|
-
)
|
|
77
|
-
rows = response.rows.map(row => row.doc)
|
|
78
|
-
}
|
|
79
|
-
return rows
|
|
80
|
-
}
|
|
81
|
-
|
|
82
36
|
async function getView(db, viewName) {
|
|
83
37
|
let mainGetter = env.SELF_HOSTED ? getFromDesignDoc : getFromMemoryDoc
|
|
84
38
|
let secondaryGetter = env.SELF_HOSTED ? getFromMemoryDoc : getFromDesignDoc
|
|
@@ -105,9 +59,24 @@ async function getView(db, viewName) {
|
|
|
105
59
|
return viewInfo
|
|
106
60
|
}
|
|
107
61
|
|
|
62
|
+
async function getRawTableData(ctx, db, tableId) {
|
|
63
|
+
let rows
|
|
64
|
+
if (tableId === InternalTables.USER_METADATA) {
|
|
65
|
+
await userController.fetchMetadata(ctx)
|
|
66
|
+
rows = ctx.body
|
|
67
|
+
} else {
|
|
68
|
+
const response = await db.allDocs(
|
|
69
|
+
getRowParams(tableId, null, {
|
|
70
|
+
include_docs: true,
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
rows = response.rows.map(row => row.doc)
|
|
74
|
+
}
|
|
75
|
+
return rows
|
|
76
|
+
}
|
|
77
|
+
|
|
108
78
|
exports.patch = async ctx => {
|
|
109
|
-
const
|
|
110
|
-
const db = new CouchDB(appId)
|
|
79
|
+
const db = getAppDB()
|
|
111
80
|
const inputs = ctx.request.body
|
|
112
81
|
const tableId = inputs.tableId
|
|
113
82
|
const isUserTable = tableId === InternalTables.USER_METADATA
|
|
@@ -146,14 +115,13 @@ exports.patch = async ctx => {
|
|
|
146
115
|
|
|
147
116
|
// returned row is cleaned and prepared for writing to DB
|
|
148
117
|
row = await linkRows.updateLinks({
|
|
149
|
-
appId,
|
|
150
118
|
eventType: linkRows.EventType.ROW_UPDATE,
|
|
151
119
|
row,
|
|
152
120
|
tableId: row.tableId,
|
|
153
121
|
table,
|
|
154
122
|
})
|
|
155
123
|
// check if any attachments removed
|
|
156
|
-
await cleanupAttachments(
|
|
124
|
+
await cleanupAttachments(table, { oldRow, row })
|
|
157
125
|
|
|
158
126
|
if (isUserTable) {
|
|
159
127
|
// the row has been updated, need to put it into the ctx
|
|
@@ -162,12 +130,14 @@ exports.patch = async ctx => {
|
|
|
162
130
|
return { row: ctx.body, table }
|
|
163
131
|
}
|
|
164
132
|
|
|
165
|
-
return
|
|
133
|
+
return finaliseRow(table, row, {
|
|
134
|
+
oldTable: dbTable,
|
|
135
|
+
updateFormula: true,
|
|
136
|
+
})
|
|
166
137
|
}
|
|
167
138
|
|
|
168
139
|
exports.save = async function (ctx) {
|
|
169
|
-
const
|
|
170
|
-
const db = new CouchDB(appId)
|
|
140
|
+
const db = getAppDB()
|
|
171
141
|
let inputs = ctx.request.body
|
|
172
142
|
inputs.tableId = ctx.params.tableId
|
|
173
143
|
|
|
@@ -189,18 +159,19 @@ exports.save = async function (ctx) {
|
|
|
189
159
|
|
|
190
160
|
// make sure link rows are up to date
|
|
191
161
|
row = await linkRows.updateLinks({
|
|
192
|
-
appId,
|
|
193
162
|
eventType: linkRows.EventType.ROW_SAVE,
|
|
194
163
|
row,
|
|
195
164
|
tableId: row.tableId,
|
|
196
165
|
table,
|
|
197
166
|
})
|
|
198
167
|
|
|
199
|
-
return
|
|
168
|
+
return finaliseRow(table, row, {
|
|
169
|
+
oldTable: dbTable,
|
|
170
|
+
updateFormula: true,
|
|
171
|
+
})
|
|
200
172
|
}
|
|
201
173
|
|
|
202
174
|
exports.fetchView = async ctx => {
|
|
203
|
-
const appId = ctx.appId
|
|
204
175
|
const viewName = ctx.params.viewName
|
|
205
176
|
|
|
206
177
|
// if this is a table view being looked for just transfer to that
|
|
@@ -209,7 +180,7 @@ exports.fetchView = async ctx => {
|
|
|
209
180
|
return exports.fetch(ctx)
|
|
210
181
|
}
|
|
211
182
|
|
|
212
|
-
const db =
|
|
183
|
+
const db = getAppDB()
|
|
213
184
|
const { calculation, group, field } = ctx.query
|
|
214
185
|
const viewInfo = await getView(db, viewName)
|
|
215
186
|
let response
|
|
@@ -236,7 +207,7 @@ exports.fetchView = async ctx => {
|
|
|
236
207
|
schema: {},
|
|
237
208
|
}
|
|
238
209
|
}
|
|
239
|
-
rows = await outputProcessing(
|
|
210
|
+
rows = await outputProcessing(table, response.rows)
|
|
240
211
|
}
|
|
241
212
|
|
|
242
213
|
if (calculation === CALCULATION_TYPES.STATS) {
|
|
@@ -263,27 +234,24 @@ exports.fetchView = async ctx => {
|
|
|
263
234
|
}
|
|
264
235
|
|
|
265
236
|
exports.fetch = async ctx => {
|
|
266
|
-
const
|
|
267
|
-
const db = new CouchDB(appId)
|
|
237
|
+
const db = getAppDB()
|
|
268
238
|
|
|
269
239
|
const tableId = ctx.params.tableId
|
|
270
240
|
let table = await db.get(tableId)
|
|
271
241
|
let rows = await getRawTableData(ctx, db, tableId)
|
|
272
|
-
return outputProcessing(
|
|
242
|
+
return outputProcessing(table, rows)
|
|
273
243
|
}
|
|
274
244
|
|
|
275
245
|
exports.find = async ctx => {
|
|
276
|
-
const
|
|
277
|
-
const db = new CouchDB(appId)
|
|
246
|
+
const db = getAppDB()
|
|
278
247
|
const table = await db.get(ctx.params.tableId)
|
|
279
|
-
let row = await findRow(ctx,
|
|
280
|
-
row = await outputProcessing(
|
|
248
|
+
let row = await findRow(ctx, ctx.params.tableId, ctx.params.rowId)
|
|
249
|
+
row = await outputProcessing(table, row)
|
|
281
250
|
return row
|
|
282
251
|
}
|
|
283
252
|
|
|
284
253
|
exports.destroy = async function (ctx) {
|
|
285
|
-
const
|
|
286
|
-
const db = new CouchDB(appId)
|
|
254
|
+
const db = getAppDB()
|
|
287
255
|
const { _id, _rev } = ctx.request.body
|
|
288
256
|
let row = await db.get(_id)
|
|
289
257
|
|
|
@@ -292,16 +260,17 @@ exports.destroy = async function (ctx) {
|
|
|
292
260
|
}
|
|
293
261
|
const table = await db.get(row.tableId)
|
|
294
262
|
// update the row to include full relationships before deleting them
|
|
295
|
-
row = await outputProcessing(
|
|
263
|
+
row = await outputProcessing(table, row, { squash: false })
|
|
296
264
|
// now remove the relationships
|
|
297
265
|
await linkRows.updateLinks({
|
|
298
|
-
appId,
|
|
299
266
|
eventType: linkRows.EventType.ROW_DELETE,
|
|
300
267
|
row,
|
|
301
268
|
tableId: row.tableId,
|
|
302
269
|
})
|
|
303
270
|
// remove any attachments that were on the row from object storage
|
|
304
|
-
await cleanupAttachments(
|
|
271
|
+
await cleanupAttachments(table, { row })
|
|
272
|
+
// remove any static formula
|
|
273
|
+
await updateRelatedFormula(table, row)
|
|
305
274
|
|
|
306
275
|
let response
|
|
307
276
|
if (ctx.params.tableId === InternalTables.USER_METADATA) {
|
|
@@ -317,20 +286,18 @@ exports.destroy = async function (ctx) {
|
|
|
317
286
|
}
|
|
318
287
|
|
|
319
288
|
exports.bulkDestroy = async ctx => {
|
|
320
|
-
const
|
|
321
|
-
const db = new CouchDB(appId)
|
|
289
|
+
const db = getAppDB()
|
|
322
290
|
const tableId = ctx.params.tableId
|
|
323
291
|
const table = await db.get(tableId)
|
|
324
292
|
let { rows } = ctx.request.body
|
|
325
293
|
|
|
326
294
|
// before carrying out any updates, make sure the rows are ready to be returned
|
|
327
295
|
// they need to be the full rows (including previous relationships) for automations
|
|
328
|
-
rows = await outputProcessing(
|
|
296
|
+
rows = await outputProcessing(table, rows, { squash: false })
|
|
329
297
|
|
|
330
298
|
// remove the relationships first
|
|
331
299
|
let updates = rows.map(row =>
|
|
332
300
|
linkRows.updateLinks({
|
|
333
|
-
appId,
|
|
334
301
|
eventType: linkRows.EventType.ROW_DELETE,
|
|
335
302
|
row,
|
|
336
303
|
tableId: row.tableId,
|
|
@@ -349,7 +316,8 @@ exports.bulkDestroy = async ctx => {
|
|
|
349
316
|
await db.bulkDocs(rows.map(row => ({ ...row, _deleted: true })))
|
|
350
317
|
}
|
|
351
318
|
// remove any attachments that were on the rows from object storage
|
|
352
|
-
await cleanupAttachments(
|
|
319
|
+
await cleanupAttachments(table, { rows })
|
|
320
|
+
await updateRelatedFormula(table, rows)
|
|
353
321
|
await Promise.all(updates)
|
|
354
322
|
return { response: { ok: true }, rows }
|
|
355
323
|
}
|
|
@@ -360,28 +328,27 @@ exports.search = async ctx => {
|
|
|
360
328
|
return { rows: await exports.fetch(ctx) }
|
|
361
329
|
}
|
|
362
330
|
|
|
363
|
-
const appId = ctx.appId
|
|
364
331
|
const { tableId } = ctx.params
|
|
365
|
-
const db =
|
|
332
|
+
const db = getAppDB()
|
|
366
333
|
const { paginate, query, ...params } = ctx.request.body
|
|
367
334
|
params.version = ctx.version
|
|
368
335
|
params.tableId = tableId
|
|
369
336
|
|
|
370
337
|
let response
|
|
371
338
|
if (paginate) {
|
|
372
|
-
response = await paginatedSearch(
|
|
339
|
+
response = await paginatedSearch(query, params)
|
|
373
340
|
} else {
|
|
374
|
-
response = await fullSearch(
|
|
341
|
+
response = await fullSearch(query, params)
|
|
375
342
|
}
|
|
376
343
|
|
|
377
344
|
// Enrich search results with relationships
|
|
378
345
|
if (response.rows && response.rows.length) {
|
|
379
346
|
// enrich with global users if from users table
|
|
380
347
|
if (tableId === InternalTables.USER_METADATA) {
|
|
381
|
-
response.rows = await getGlobalUsersFromMetadata(
|
|
348
|
+
response.rows = await getGlobalUsersFromMetadata(response.rows)
|
|
382
349
|
}
|
|
383
350
|
const table = await db.get(tableId)
|
|
384
|
-
response.rows = await outputProcessing(
|
|
351
|
+
response.rows = await outputProcessing(table, response.rows)
|
|
385
352
|
}
|
|
386
353
|
|
|
387
354
|
return response
|
|
@@ -389,25 +356,22 @@ exports.search = async ctx => {
|
|
|
389
356
|
|
|
390
357
|
exports.validate = async ctx => {
|
|
391
358
|
return validate({
|
|
392
|
-
appId: ctx.appId,
|
|
393
359
|
tableId: ctx.params.tableId,
|
|
394
360
|
row: ctx.request.body,
|
|
395
361
|
})
|
|
396
362
|
}
|
|
397
363
|
|
|
398
364
|
exports.fetchEnrichedRow = async ctx => {
|
|
399
|
-
const
|
|
400
|
-
const db = new CouchDB(appId)
|
|
365
|
+
const db = getAppDB()
|
|
401
366
|
const tableId = ctx.params.tableId
|
|
402
367
|
const rowId = ctx.params.rowId
|
|
403
368
|
// need table to work out where links go in row
|
|
404
369
|
let [table, row] = await Promise.all([
|
|
405
370
|
db.get(tableId),
|
|
406
|
-
findRow(ctx,
|
|
371
|
+
findRow(ctx, tableId, rowId),
|
|
407
372
|
])
|
|
408
373
|
// get the link docs
|
|
409
374
|
const linkVals = await linkRows.getLinkDocuments({
|
|
410
|
-
appId,
|
|
411
375
|
tableId,
|
|
412
376
|
rowId,
|
|
413
377
|
})
|
|
@@ -434,7 +398,7 @@ exports.fetchEnrichedRow = async ctx => {
|
|
|
434
398
|
for (let [tableId, rows] of Object.entries(groups)) {
|
|
435
399
|
// need to include the IDs in these rows for any links they may have
|
|
436
400
|
linkedRows = linkedRows.concat(
|
|
437
|
-
await outputProcessing(
|
|
401
|
+
await outputProcessing(tables[tableId], rows)
|
|
438
402
|
)
|
|
439
403
|
}
|
|
440
404
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const { SearchIndexes } = require("../../../db/utils")
|
|
2
2
|
const fetch = require("node-fetch")
|
|
3
3
|
const { getCouchUrl } = require("@budibase/backend-core/db")
|
|
4
|
+
const { getAppId } = require("@budibase/backend-core/context")
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Class to build lucene query URLs.
|
|
7
8
|
* Optionally takes a base lucene query object.
|
|
8
9
|
*/
|
|
9
10
|
class QueryBuilder {
|
|
10
|
-
constructor(
|
|
11
|
-
this.appId = appId
|
|
11
|
+
constructor(base) {
|
|
12
12
|
this.query = {
|
|
13
13
|
string: {},
|
|
14
14
|
fuzzy: {},
|
|
@@ -37,22 +37,30 @@ class QueryBuilder {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
setLimit(limit) {
|
|
40
|
-
|
|
40
|
+
if (limit != null) {
|
|
41
|
+
this.limit = limit
|
|
42
|
+
}
|
|
41
43
|
return this
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
setSort(sort) {
|
|
45
|
-
|
|
47
|
+
if (sort != null) {
|
|
48
|
+
this.sort = sort
|
|
49
|
+
}
|
|
46
50
|
return this
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
setSortOrder(sortOrder) {
|
|
50
|
-
|
|
54
|
+
if (sortOrder != null) {
|
|
55
|
+
this.sortOrder = sortOrder
|
|
56
|
+
}
|
|
51
57
|
return this
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
setSortType(sortType) {
|
|
55
|
-
|
|
61
|
+
if (sortType != null) {
|
|
62
|
+
this.sortType = sortType
|
|
63
|
+
}
|
|
56
64
|
return this
|
|
57
65
|
}
|
|
58
66
|
|
|
@@ -233,7 +241,8 @@ class QueryBuilder {
|
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
async run() {
|
|
236
|
-
const
|
|
244
|
+
const appId = getAppId()
|
|
245
|
+
const url = `${getCouchUrl()}/${appId}/_design/database/_search/${
|
|
237
246
|
SearchIndexes.ROWS
|
|
238
247
|
}`
|
|
239
248
|
const body = this.buildSearchBody()
|
|
@@ -270,7 +279,6 @@ const runQuery = async (url, body) => {
|
|
|
270
279
|
* Gets round the fixed limit of 200 results from a query by fetching as many
|
|
271
280
|
* pages as required and concatenating the results. This recursively operates
|
|
272
281
|
* until enough results have been found.
|
|
273
|
-
* @param appId {string} The app ID to search
|
|
274
282
|
* @param query {object} The JSON query structure
|
|
275
283
|
* @param params {object} The search params including:
|
|
276
284
|
* tableId {string} The table ID to search
|
|
@@ -283,7 +291,7 @@ const runQuery = async (url, body) => {
|
|
|
283
291
|
* rows {array|null} Current results in the recursive search
|
|
284
292
|
* @returns {Promise<*[]|*>}
|
|
285
293
|
*/
|
|
286
|
-
const recursiveSearch = async (
|
|
294
|
+
const recursiveSearch = async (query, params) => {
|
|
287
295
|
const bookmark = params.bookmark
|
|
288
296
|
const rows = params.rows || []
|
|
289
297
|
if (rows.length >= params.limit) {
|
|
@@ -293,7 +301,7 @@ const recursiveSearch = async (appId, query, params) => {
|
|
|
293
301
|
if (rows.length > params.limit - 200) {
|
|
294
302
|
pageSize = params.limit - rows.length
|
|
295
303
|
}
|
|
296
|
-
const page = await new QueryBuilder(
|
|
304
|
+
const page = await new QueryBuilder(query)
|
|
297
305
|
.setVersion(params.version)
|
|
298
306
|
.setTable(params.tableId)
|
|
299
307
|
.setBookmark(bookmark)
|
|
@@ -313,14 +321,13 @@ const recursiveSearch = async (appId, query, params) => {
|
|
|
313
321
|
bookmark: page.bookmark,
|
|
314
322
|
rows: [...rows, ...page.rows],
|
|
315
323
|
}
|
|
316
|
-
return await recursiveSearch(
|
|
324
|
+
return await recursiveSearch(query, newParams)
|
|
317
325
|
}
|
|
318
326
|
|
|
319
327
|
/**
|
|
320
328
|
* Performs a paginated search. A bookmark will be returned to allow the next
|
|
321
329
|
* page to be fetched. There is a max limit off 200 results per page in a
|
|
322
330
|
* paginated search.
|
|
323
|
-
* @param appId {string} The app ID to search
|
|
324
331
|
* @param query {object} The JSON query structure
|
|
325
332
|
* @param params {object} The search params including:
|
|
326
333
|
* tableId {string} The table ID to search
|
|
@@ -332,13 +339,13 @@ const recursiveSearch = async (appId, query, params) => {
|
|
|
332
339
|
* bookmark {string} The bookmark to resume from
|
|
333
340
|
* @returns {Promise<{hasNextPage: boolean, rows: *[]}>}
|
|
334
341
|
*/
|
|
335
|
-
exports.paginatedSearch = async (
|
|
342
|
+
exports.paginatedSearch = async (query, params) => {
|
|
336
343
|
let limit = params.limit
|
|
337
344
|
if (limit == null || isNaN(limit) || limit < 0) {
|
|
338
345
|
limit = 50
|
|
339
346
|
}
|
|
340
347
|
limit = Math.min(limit, 200)
|
|
341
|
-
const search = new QueryBuilder(
|
|
348
|
+
const search = new QueryBuilder(query)
|
|
342
349
|
.setVersion(params.version)
|
|
343
350
|
.setTable(params.tableId)
|
|
344
351
|
.setSort(params.sort)
|
|
@@ -367,7 +374,6 @@ exports.paginatedSearch = async (appId, query, params) => {
|
|
|
367
374
|
* desired amount of results. There is a limit of 1000 results to avoid
|
|
368
375
|
* heavy performance hits, and to avoid client components breaking from
|
|
369
376
|
* handling too much data.
|
|
370
|
-
* @param appId {string} The app ID to search
|
|
371
377
|
* @param query {object} The JSON query structure
|
|
372
378
|
* @param params {object} The search params including:
|
|
373
379
|
* tableId {string} The table ID to search
|
|
@@ -378,12 +384,12 @@ exports.paginatedSearch = async (appId, query, params) => {
|
|
|
378
384
|
* limit {number} The desired number of results
|
|
379
385
|
* @returns {Promise<{rows: *}>}
|
|
380
386
|
*/
|
|
381
|
-
exports.fullSearch = async (
|
|
387
|
+
exports.fullSearch = async (query, params) => {
|
|
382
388
|
let limit = params.limit
|
|
383
389
|
if (limit == null || isNaN(limit) || limit < 0) {
|
|
384
390
|
limit = 1000
|
|
385
391
|
}
|
|
386
392
|
params.limit = Math.min(limit, 1000)
|
|
387
|
-
const rows = await recursiveSearch(
|
|
393
|
+
const rows = await recursiveSearch(query, params)
|
|
388
394
|
return { rows }
|
|
389
395
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const { getRowParams } = require("../../../db/utils")
|
|
2
|
+
const {
|
|
3
|
+
outputProcessing,
|
|
4
|
+
processAutoColumn,
|
|
5
|
+
processFormulas,
|
|
6
|
+
} = require("../../../utilities/rowProcessor")
|
|
7
|
+
const { FieldTypes, FormulaTypes } = require("../../../constants")
|
|
8
|
+
const { isEqual } = require("lodash")
|
|
9
|
+
const { cloneDeep } = require("lodash/fp")
|
|
10
|
+
const { getAppDB } = require("@budibase/backend-core/context")
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function runs through a list of enriched rows, looks at the rows which
|
|
14
|
+
* are related and then checks if they need the state of their formulas
|
|
15
|
+
* updated.
|
|
16
|
+
* NOTE: this will only for affect static formulas.
|
|
17
|
+
*/
|
|
18
|
+
exports.updateRelatedFormula = async (table, enrichedRows) => {
|
|
19
|
+
const db = getAppDB()
|
|
20
|
+
// no formula to update, we're done
|
|
21
|
+
if (!table.relatedFormula) {
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
let promises = []
|
|
25
|
+
for (let enrichedRow of Array.isArray(enrichedRows)
|
|
26
|
+
? enrichedRows
|
|
27
|
+
: [enrichedRows]) {
|
|
28
|
+
// the related rows by tableId
|
|
29
|
+
let relatedRows = {}
|
|
30
|
+
for (let [key, field] of Object.entries(enrichedRow)) {
|
|
31
|
+
const columnDefinition = table.schema[key]
|
|
32
|
+
if (columnDefinition && columnDefinition.type === FieldTypes.LINK) {
|
|
33
|
+
const relatedTableId = columnDefinition.tableId
|
|
34
|
+
if (!relatedRows[relatedTableId]) {
|
|
35
|
+
relatedRows[relatedTableId] = []
|
|
36
|
+
}
|
|
37
|
+
relatedRows[relatedTableId] = relatedRows[relatedTableId].concat(field)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (let tableId of table.relatedFormula) {
|
|
41
|
+
let relatedTable
|
|
42
|
+
try {
|
|
43
|
+
// no rows to update, skip
|
|
44
|
+
if (!relatedRows[tableId] || relatedRows[tableId].length === 0) {
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
relatedTable = await db.get(tableId)
|
|
48
|
+
} catch (err) {
|
|
49
|
+
// no error scenario, table doesn't seem to exist anymore, ignore
|
|
50
|
+
}
|
|
51
|
+
for (let column of Object.values(relatedTable.schema)) {
|
|
52
|
+
// needs updated in related rows
|
|
53
|
+
if (
|
|
54
|
+
column.type === FieldTypes.FORMULA &&
|
|
55
|
+
column.formulaType === FormulaTypes.STATIC
|
|
56
|
+
) {
|
|
57
|
+
// re-enrich rows for all the related, don't update the related formula for them
|
|
58
|
+
promises = promises.concat(
|
|
59
|
+
relatedRows[tableId].map(related =>
|
|
60
|
+
exports.finaliseRow(relatedTable, related, {
|
|
61
|
+
updateFormula: false,
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
await Promise.all(promises)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
exports.updateAllFormulasInTable = async table => {
|
|
73
|
+
const db = getAppDB()
|
|
74
|
+
// start by getting the raw rows (which will be written back to DB after update)
|
|
75
|
+
let rows = (
|
|
76
|
+
await db.allDocs(
|
|
77
|
+
getRowParams(table._id, null, {
|
|
78
|
+
include_docs: true,
|
|
79
|
+
})
|
|
80
|
+
)
|
|
81
|
+
).rows.map(row => row.doc)
|
|
82
|
+
// now enrich the rows, note the clone so that we have the base state of the
|
|
83
|
+
// rows so that we don't write any of the enriched information back
|
|
84
|
+
let enrichedRows = await outputProcessing(table, cloneDeep(rows), {
|
|
85
|
+
squash: false,
|
|
86
|
+
})
|
|
87
|
+
const updatedRows = []
|
|
88
|
+
for (let row of rows) {
|
|
89
|
+
// find the enriched row, if found process the formulas
|
|
90
|
+
const enrichedRow = enrichedRows.find(enriched => enriched._id === row._id)
|
|
91
|
+
if (enrichedRow) {
|
|
92
|
+
const processed = processFormulas(table, cloneDeep(row), {
|
|
93
|
+
dynamic: false,
|
|
94
|
+
contextRows: enrichedRow,
|
|
95
|
+
})
|
|
96
|
+
// values have changed, need to add to bulk docs to update
|
|
97
|
+
if (!isEqual(processed, row)) {
|
|
98
|
+
updatedRows.push(processed)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
await db.bulkDocs(updatedRows)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* This function runs at the end of the save/patch functions of the row controller, all this
|
|
107
|
+
* really does is enrich the row, handle any static formula processing, then return the enriched
|
|
108
|
+
* row. The reason we need to return the enriched row is that the automation row created trigger
|
|
109
|
+
* expects the row to be totally enriched/contain all relationships.
|
|
110
|
+
*/
|
|
111
|
+
exports.finaliseRow = async (
|
|
112
|
+
table,
|
|
113
|
+
row,
|
|
114
|
+
{ oldTable, updateFormula } = { updateFormula: true }
|
|
115
|
+
) => {
|
|
116
|
+
const db = getAppDB()
|
|
117
|
+
row.type = "row"
|
|
118
|
+
// process the row before return, to include relationships
|
|
119
|
+
let enrichedRow = await outputProcessing(table, cloneDeep(row), {
|
|
120
|
+
squash: false,
|
|
121
|
+
})
|
|
122
|
+
// use enriched row to generate formulas for saving, specifically only use as context
|
|
123
|
+
row = processFormulas(table, row, {
|
|
124
|
+
dynamic: false,
|
|
125
|
+
contextRows: enrichedRow,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// don't worry about rev, tables handle rev/lastID updates
|
|
129
|
+
// if another row has been written since processing this will
|
|
130
|
+
// handle the auto ID clash
|
|
131
|
+
if (oldTable && !isEqual(oldTable, table)) {
|
|
132
|
+
try {
|
|
133
|
+
await db.put(table)
|
|
134
|
+
} catch (err) {
|
|
135
|
+
if (err.status === 409) {
|
|
136
|
+
const updatedTable = await db.get(table._id)
|
|
137
|
+
let response = processAutoColumn(null, updatedTable, row, {
|
|
138
|
+
reprocessing: true,
|
|
139
|
+
})
|
|
140
|
+
await db.put(response.table)
|
|
141
|
+
row = response.row
|
|
142
|
+
} else {
|
|
143
|
+
throw err
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const response = await db.put(row)
|
|
148
|
+
// for response, calculate the formulas for the enriched row
|
|
149
|
+
enrichedRow._rev = response.rev
|
|
150
|
+
enrichedRow = await processFormulas(table, enrichedRow, { dynamic: false })
|
|
151
|
+
// this updates the related formulas in other rows based on the relations to this row
|
|
152
|
+
if (updateFormula) {
|
|
153
|
+
await exports.updateRelatedFormula(table, enrichedRow)
|
|
154
|
+
}
|
|
155
|
+
return { row: enrichedRow, table }
|
|
156
|
+
}
|