@budibase/server 1.0.44 → 1.0.46-alpha.2
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/builder/assets/{index.39e01193.css → index.0df4f7ab.css} +1 -1
- package/builder/assets/{index.bc00c307.js → index.89280093.js} +230 -228
- package/builder/assets/{vendor.f9faf6ab.js → vendor.10e2ad1b.js} +12 -12
- package/builder/index.html +3 -3
- package/coverage/clover.xml +217 -208
- package/coverage/coverage-final.json +4 -4
- 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 +1 -1
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +1 -1
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +15 -15
- package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +29 -14
- package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +17 -17
- package/coverage/lcov-report/api/controllers/table/index.js.html +34 -16
- package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/utils.js.html +16 -7
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- 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/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +1 -1
- package/coverage/lcov-report/api/routes/index.js.html +1 -1
- 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/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 +1 -1
- 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 +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +1 -1
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/automations/utils.js.html +1 -1
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +1 -1
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/client.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- 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 +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +25 -25
- 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 +1 -1
- package/coverage/lcov-report/middleware/builder.js.html +1 -1
- package/coverage/lcov-report/middleware/currentapp.js.html +33 -6
- package/coverage/lcov-report/middleware/index.html +10 -10
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- 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 +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +1 -1
- package/coverage/lcov-report/threads/index.js.html +1 -1
- package/coverage/lcov-report/threads/query.js.html +1 -1
- package/coverage/lcov-report/threads/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +1 -1
- package/coverage/lcov-report/utilities/index.html +1 -1
- package/coverage/lcov-report/utilities/index.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
- 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 +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +1 -1
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
- package/coverage/lcov.info +361 -347
- package/dist/api/controllers/row/utils.js +12 -6
- package/dist/api/controllers/table/index.js +10 -4
- package/dist/api/controllers/table/utils.js +4 -2
- package/dist/integrations/base/sql.js +13 -6
- package/dist/integrations/utils.js +53 -8
- package/dist/middleware/currentapp.js +9 -0
- package/dist/package.json +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/api/controllers/row/utils.js +11 -6
- package/src/api/controllers/table/index.js +15 -9
- package/src/api/controllers/table/utils.js +4 -1
- package/src/integrations/base/sql.ts +14 -7
- package/src/integrations/tests/sql.spec.js +16 -0
- package/src/integrations/utils.ts +57 -10
- package/src/middleware/currentapp.js +9 -0
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.
|
|
4
|
+
"version": "1.0.46-alpha.2",
|
|
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.
|
|
74
|
-
"@budibase/client": "^1.0.
|
|
75
|
-
"@budibase/string-templates": "^1.0.
|
|
73
|
+
"@budibase/backend-core": "^1.0.46-alpha.2",
|
|
74
|
+
"@budibase/client": "^1.0.46-alpha.2",
|
|
75
|
+
"@budibase/string-templates": "^1.0.46-alpha.2",
|
|
76
76
|
"@bull-board/api": "^3.7.0",
|
|
77
77
|
"@bull-board/koa": "^3.7.0",
|
|
78
78
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -165,5 +165,5 @@
|
|
|
165
165
|
"optionalDependencies": {
|
|
166
166
|
"oracledb": "^5.3.0"
|
|
167
167
|
},
|
|
168
|
-
"gitHead": "
|
|
168
|
+
"gitHead": "74c2b625437c6cace5a8547347470b8343c8fe4f"
|
|
169
169
|
}
|
|
@@ -61,12 +61,17 @@ exports.validate = async ({ appId, tableId, row, table }) => {
|
|
|
61
61
|
let res
|
|
62
62
|
|
|
63
63
|
// Validate.js doesn't seem to handle array
|
|
64
|
-
if (type === FieldTypes.ARRAY && row[fieldName]
|
|
65
|
-
row[fieldName].
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
if (type === FieldTypes.ARRAY && row[fieldName]) {
|
|
65
|
+
if (row[fieldName].length) {
|
|
66
|
+
row[fieldName].map(val => {
|
|
67
|
+
if (!constraints.inclusion.includes(val)) {
|
|
68
|
+
errors[fieldName] = "Field not in list"
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
} else if (constraints.presence && row[fieldName].length === 0) {
|
|
72
|
+
// non required MultiSelect creates an empty array, which should not throw errors
|
|
73
|
+
errors[fieldName] = [`${fieldName} is required`]
|
|
74
|
+
}
|
|
70
75
|
} else if (type === FieldTypes.JSON && typeof row[fieldName] === "string") {
|
|
71
76
|
// this should only happen if there is an error
|
|
72
77
|
try {
|
|
@@ -2,7 +2,7 @@ const CouchDB = require("../../../db")
|
|
|
2
2
|
const internal = require("./internal")
|
|
3
3
|
const external = require("./external")
|
|
4
4
|
const csvParser = require("../../../utilities/csvParser")
|
|
5
|
-
const { isExternalTable } = require("../../../integrations/utils")
|
|
5
|
+
const { isExternalTable, isSQL } = require("../../../integrations/utils")
|
|
6
6
|
const {
|
|
7
7
|
getTableParams,
|
|
8
8
|
getDatasourceParams,
|
|
@@ -32,8 +32,8 @@ exports.fetch = async function (ctx) {
|
|
|
32
32
|
})
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
const internal = internalTables.rows.map(
|
|
36
|
-
...
|
|
35
|
+
const internal = internalTables.rows.map(tableDoc => ({
|
|
36
|
+
...tableDoc.doc,
|
|
37
37
|
type: "internal",
|
|
38
38
|
sourceId: BudibaseInternalDB._id,
|
|
39
39
|
}))
|
|
@@ -44,12 +44,18 @@ exports.fetch = async function (ctx) {
|
|
|
44
44
|
})
|
|
45
45
|
)
|
|
46
46
|
|
|
47
|
-
const external = externalTables.rows.flatMap(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
const external = externalTables.rows.flatMap(tableDoc => {
|
|
48
|
+
let entities = tableDoc.doc.entities
|
|
49
|
+
if (entities) {
|
|
50
|
+
return Object.values(entities).map(entity => ({
|
|
51
|
+
...entity,
|
|
52
|
+
type: "external",
|
|
53
|
+
sourceId: tableDoc.doc._id,
|
|
54
|
+
sql: isSQL(tableDoc.doc),
|
|
55
|
+
}))
|
|
56
|
+
} else {
|
|
57
|
+
return []
|
|
58
|
+
}
|
|
53
59
|
})
|
|
54
60
|
|
|
55
61
|
ctx.body = [...internal, ...external]
|
|
@@ -12,6 +12,7 @@ const { USERS_TABLE_SCHEMA, SwitchableTypes } = require("../../../constants")
|
|
|
12
12
|
const {
|
|
13
13
|
isExternalTable,
|
|
14
14
|
breakExternalTableId,
|
|
15
|
+
isSQL,
|
|
15
16
|
} = require("../../../integrations/utils")
|
|
16
17
|
const { getViews, saveView } = require("../view/utils")
|
|
17
18
|
const viewTemplate = require("../view/viewBuilder")
|
|
@@ -242,7 +243,9 @@ exports.getTable = async (appId, tableId) => {
|
|
|
242
243
|
const db = new CouchDB(appId)
|
|
243
244
|
if (isExternalTable(tableId)) {
|
|
244
245
|
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
245
|
-
|
|
246
|
+
const datasource = await db.get(datasourceId)
|
|
247
|
+
const table = await exports.getExternalTable(appId, datasourceId, tableName)
|
|
248
|
+
return { ...table, sql: isSQL(datasource) }
|
|
246
249
|
} else {
|
|
247
250
|
return db.get(tableId)
|
|
248
251
|
}
|
|
@@ -72,16 +72,22 @@ class InternalBuilder {
|
|
|
72
72
|
|
|
73
73
|
// right now we only do filters on the specific table being queried
|
|
74
74
|
addFilters(
|
|
75
|
-
tableName: string,
|
|
76
75
|
query: KnexQuery,
|
|
77
|
-
filters: SearchFilters | undefined
|
|
76
|
+
filters: SearchFilters | undefined,
|
|
77
|
+
opts: { relationship?: boolean; tableName?: string }
|
|
78
78
|
): KnexQuery {
|
|
79
79
|
function iterate(
|
|
80
80
|
structure: { [key: string]: any },
|
|
81
81
|
fn: (key: string, value: any) => void
|
|
82
82
|
) {
|
|
83
83
|
for (let [key, value] of Object.entries(structure)) {
|
|
84
|
-
|
|
84
|
+
const isRelationshipField = key.includes(".")
|
|
85
|
+
if (!opts.relationship && !isRelationshipField) {
|
|
86
|
+
fn(`${opts.tableName}.${key}`, value)
|
|
87
|
+
}
|
|
88
|
+
if (opts.relationship && isRelationshipField) {
|
|
89
|
+
fn(key, value)
|
|
90
|
+
}
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
if (!filters) {
|
|
@@ -272,7 +278,7 @@ class InternalBuilder {
|
|
|
272
278
|
if (foundOffset) {
|
|
273
279
|
query = query.offset(foundOffset)
|
|
274
280
|
}
|
|
275
|
-
query = this.addFilters(
|
|
281
|
+
query = this.addFilters(query, filters, { tableName })
|
|
276
282
|
// add sorting to pre-query
|
|
277
283
|
query = this.addSorting(query, json)
|
|
278
284
|
// @ts-ignore
|
|
@@ -285,20 +291,21 @@ class InternalBuilder {
|
|
|
285
291
|
preQuery = this.addSorting(preQuery, json)
|
|
286
292
|
}
|
|
287
293
|
// handle joins
|
|
288
|
-
|
|
294
|
+
query = this.addRelationships(
|
|
289
295
|
knex,
|
|
290
296
|
preQuery,
|
|
291
297
|
selectStatement,
|
|
292
298
|
tableName,
|
|
293
299
|
relationships
|
|
294
300
|
)
|
|
301
|
+
return this.addFilters(query, filters, { relationship: true })
|
|
295
302
|
}
|
|
296
303
|
|
|
297
304
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
298
305
|
const { endpoint, body, filters } = json
|
|
299
306
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
300
307
|
const parsedBody = parseBody(body)
|
|
301
|
-
query = this.addFilters(endpoint.entityId
|
|
308
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
302
309
|
// mysql can't use returning
|
|
303
310
|
if (opts.disableReturning) {
|
|
304
311
|
return query.update(parsedBody)
|
|
@@ -310,7 +317,7 @@ class InternalBuilder {
|
|
|
310
317
|
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
311
318
|
const { endpoint, filters } = json
|
|
312
319
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
313
|
-
query = this.addFilters(endpoint.entityId
|
|
320
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
314
321
|
// mysql can't use returning
|
|
315
322
|
if (opts.disableReturning) {
|
|
316
323
|
return query.delete()
|
|
@@ -119,6 +119,22 @@ describe("SQL query builder", () => {
|
|
|
119
119
|
})
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
+
it("should allow filtering on a related field", () => {
|
|
123
|
+
const query = sql._query(generateReadJson({
|
|
124
|
+
filters: {
|
|
125
|
+
equal: {
|
|
126
|
+
age: 10,
|
|
127
|
+
"task.name": "task 1",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
}))
|
|
131
|
+
// order of bindings changes because relationship filters occur outside inner query
|
|
132
|
+
expect(query).toEqual({
|
|
133
|
+
bindings: [10, limit, "task 1"],
|
|
134
|
+
sql: `select * from (select * from "${TABLE_NAME}" where "${TABLE_NAME}"."age" = $1 limit $2) as "${TABLE_NAME}" where "task"."name" = $3`
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
|
|
122
138
|
it("should test an create statement", () => {
|
|
123
139
|
const query = sql._query(generateCreateJson(TABLE_NAME, {
|
|
124
140
|
name: "Michael",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { SqlQuery } from "../definitions/datasource"
|
|
1
|
+
import { SourceNames, SqlQuery } from "../definitions/datasource"
|
|
2
2
|
import { Datasource, Table } from "../definitions/common"
|
|
3
|
-
import { SourceNames } from "../definitions/datasource"
|
|
4
3
|
import { DocumentTypes, SEPARATOR } from "../db/utils"
|
|
5
4
|
import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants"
|
|
6
5
|
|
|
@@ -127,7 +126,12 @@ export function isSQL(datasource: Datasource): boolean {
|
|
|
127
126
|
if (!datasource || !datasource.source) {
|
|
128
127
|
return false
|
|
129
128
|
}
|
|
130
|
-
const SQL = [
|
|
129
|
+
const SQL = [
|
|
130
|
+
SourceNames.POSTGRES,
|
|
131
|
+
SourceNames.SQL_SERVER,
|
|
132
|
+
SourceNames.MYSQL,
|
|
133
|
+
SourceNames.ORACLE,
|
|
134
|
+
]
|
|
131
135
|
return SQL.indexOf(datasource.source) !== -1
|
|
132
136
|
}
|
|
133
137
|
|
|
@@ -139,11 +143,46 @@ export function isIsoDateString(str: string) {
|
|
|
139
143
|
return d.toISOString() === str
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
|
|
146
|
+
/**
|
|
147
|
+
* This function will determine whether a column is a relationship and whether it
|
|
148
|
+
* is currently valid. The reason for the validity check is that tables can be deleted
|
|
149
|
+
* outside of Budibase control and if this is the case it will break Budibase relationships.
|
|
150
|
+
* The tableIds is a list passed down from the main finalise tables function, which is
|
|
151
|
+
* based on the tables that have just been fetched. This will only really be used on subsequent
|
|
152
|
+
* fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.
|
|
153
|
+
* @param column The column to check, to see if it is a valid relationship.
|
|
154
|
+
* @param tableIds The IDs of the tables which currently exist.
|
|
155
|
+
*/
|
|
156
|
+
function shouldCopyRelationship(column: { type: string, tableId?: string }, tableIds: [string]) {
|
|
157
|
+
return column.type === FieldTypes.LINK && column.tableId && tableIds.includes(column.tableId)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean
|
|
162
|
+
* types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make
|
|
163
|
+
* sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a
|
|
164
|
+
* column has changed type in the external database then copying it over may not be possible.
|
|
165
|
+
* @param column The column to check for options or boolean type.
|
|
166
|
+
* @param fetchedColumn The fetched column to check for the type in the external database.
|
|
167
|
+
*/
|
|
168
|
+
function shouldCopySpecialColumn(column: { type: string }, fetchedColumn: { type: string } | undefined) {
|
|
169
|
+
return column.type === FieldTypes.OPTIONS ||
|
|
170
|
+
((!fetchedColumn || fetchedColumn.type === FieldTypes.NUMBER) && column.type === FieldTypes.BOOLEAN)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Looks for columns which need to be copied over into the new table definitions, like relationships
|
|
175
|
+
* and options types.
|
|
176
|
+
* @param tableName The name of the table which is being checked.
|
|
177
|
+
* @param table The specific table which is being checked.
|
|
178
|
+
* @param entities All the tables that existed before - the old table definitions.
|
|
179
|
+
* @param tableIds The IDs of the tables which exist now, to check if anything has been removed.
|
|
180
|
+
*/
|
|
143
181
|
function copyExistingPropsOver(
|
|
144
182
|
tableName: string,
|
|
145
183
|
table: Table,
|
|
146
|
-
entities: { [key: string]: any }
|
|
184
|
+
entities: { [key: string]: any },
|
|
185
|
+
tableIds: [string]
|
|
147
186
|
) {
|
|
148
187
|
if (entities && entities[tableName]) {
|
|
149
188
|
if (entities[tableName].primaryDisplay) {
|
|
@@ -154,11 +193,10 @@ function copyExistingPropsOver(
|
|
|
154
193
|
if (!existingTableSchema.hasOwnProperty(key)) {
|
|
155
194
|
continue
|
|
156
195
|
}
|
|
196
|
+
const column = existingTableSchema[key]
|
|
157
197
|
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
((!table.schema[key] || table.schema[key].type === FieldTypes.NUMBER) &&
|
|
161
|
-
existingTableSchema[key].type === FieldTypes.BOOLEAN)
|
|
198
|
+
shouldCopyRelationship(column, tableIds) ||
|
|
199
|
+
shouldCopySpecialColumn(column, table.schema[key])
|
|
162
200
|
) {
|
|
163
201
|
table.schema[key] = existingTableSchema[key]
|
|
164
202
|
}
|
|
@@ -167,6 +205,13 @@ function copyExistingPropsOver(
|
|
|
167
205
|
return table
|
|
168
206
|
}
|
|
169
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Look through the final table definitions to see if anything needs to be
|
|
210
|
+
* copied over from the old and if any errors have occurred mark them so
|
|
211
|
+
* that the user can be made aware.
|
|
212
|
+
* @param tables The list of tables that have been retrieved from the external database.
|
|
213
|
+
* @param entities The old list of tables, if there was any to look for definitions in.
|
|
214
|
+
*/
|
|
170
215
|
export function finaliseExternalTables(
|
|
171
216
|
tables: { [key: string]: any },
|
|
172
217
|
entities: { [key: string]: any }
|
|
@@ -174,6 +219,8 @@ export function finaliseExternalTables(
|
|
|
174
219
|
const invalidColumns = Object.values(InvalidColumns)
|
|
175
220
|
let finalTables: { [key: string]: any } = {}
|
|
176
221
|
const errors: { [key: string]: string } = {}
|
|
222
|
+
// @ts-ignore
|
|
223
|
+
const tableIds: [string] = Object.values(tables).map(table => table._id)
|
|
177
224
|
for (let [name, table] of Object.entries(tables)) {
|
|
178
225
|
const schemaFields = Object.keys(table.schema)
|
|
179
226
|
// make sure every table has a key
|
|
@@ -185,7 +232,7 @@ export function finaliseExternalTables(
|
|
|
185
232
|
continue
|
|
186
233
|
}
|
|
187
234
|
// make sure all previous props have been added back
|
|
188
|
-
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
|
235
|
+
finalTables[name] = copyExistingPropsOver(name, table, entities, tableIds)
|
|
189
236
|
}
|
|
190
237
|
// sort the tables by name
|
|
191
238
|
finalTables = Object.entries(finalTables)
|
|
@@ -47,6 +47,15 @@ module.exports = async (ctx, next) => {
|
|
|
47
47
|
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
|
48
48
|
) {
|
|
49
49
|
clearCookie(ctx, Cookies.CurrentApp)
|
|
50
|
+
// have to set the return url on the server side as client side is not available
|
|
51
|
+
setCookie(ctx, ctx.url, Cookies.RETURN_URL, {
|
|
52
|
+
// don't sign so the browser can easily read
|
|
53
|
+
sign: false,
|
|
54
|
+
// use the request domain to match how ui handles the return url cookie.
|
|
55
|
+
// it's important we don't use the shared domain here as the builder
|
|
56
|
+
// can't delete from it without awareness of the domain.
|
|
57
|
+
requestDomain: true,
|
|
58
|
+
})
|
|
50
59
|
return ctx.redirect("/")
|
|
51
60
|
}
|
|
52
61
|
|