@budibase/server 0.9.184 → 0.9.185-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1 -1
- package/__mocks__/mssql.ts +1 -1
- package/__mocks__/pg.ts +3 -0
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.053c6f7a.js +1321 -0
- package/builder/assets/index.4a7c5636.css +1 -0
- package/builder/assets/vendor.470042a4.js +152 -0
- package/builder/assets/vendor.5e1fe644.css +1 -0
- package/builder/index.html +4 -4
- package/coverage/clover.xml +1357 -959
- package/coverage/coverage-final.json +91 -87
- package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
- package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
- package/coverage/lcov-report/api/controllers/application.js.html +65 -14
- package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
- package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
- 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 +4 -4
- package/coverage/lcov-report/api/controllers/datasource.js.html +147 -27
- package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
- package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
- package/coverage/lcov-report/api/controllers/index.html +90 -90
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
- package/coverage/lcov-report/api/controllers/query.js.html +53 -209
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
- package/coverage/lcov-report/api/controllers/row/external.js.html +12 -6
- package/coverage/lcov-report/api/controllers/row/index.html +26 -26
- package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
- package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
- package/coverage/lcov-report/api/controllers/script.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/external.js.html +980 -0
- package/coverage/lcov-report/api/controllers/table/index.html +56 -26
- package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
- package/coverage/lcov-report/api/controllers/table/internal.js.html +545 -0
- package/coverage/lcov-report/api/controllers/table/utils.js.html +172 -49
- package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
- package/coverage/lcov-report/api/controllers/user.js.html +390 -33
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +9 -9
- package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
- package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
- 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 +2 -2
- package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +4 -4
- 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 +5 -2
- 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 +2 -2
- package/coverage/lcov-report/api/routes/table.js.html +35 -2
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +17 -2
- 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 +2 -2
- package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
- package/coverage/lcov-report/automations/bullboard.js.html +71 -20
- package/coverage/lcov-report/automations/index.html +33 -48
- package/coverage/lcov-report/automations/index.js.html +2 -2
- 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 +3 -3
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +14 -14
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
- package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
- 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 +7 -7
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- 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 +22 -10
- package/coverage/lcov-report/automations/utils.js.html +42 -12
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +49 -4
- 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 +2 -2
- package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
- package/coverage/lcov-report/db/index.html +2 -2
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
- 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 +6 -6
- package/coverage/lcov-report/events/index.html +6 -6
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +5 -5
- package/coverage/lcov-report/index.html +98 -83
- 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 +2 -2
- package/coverage/lcov-report/middleware/authorized.js.html +11 -8
- package/coverage/lcov-report/middleware/builder.js.html +16 -7
- package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
- package/coverage/lcov-report/middleware/index.html +23 -23
- package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
- package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
- package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
- package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +83 -32
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +260 -0
- package/coverage/lcov-report/threads/query.js.html +269 -0
- 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 +144 -15
- package/coverage/lcov-report/utilities/global.js.html +26 -11
- package/coverage/lcov-report/utilities/index.html +49 -49
- package/coverage/lcov-report/utilities/index.js.html +65 -17
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
- package/coverage/lcov-report/utilities/queue/index.html +14 -14
- 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 +4 -4
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
- package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
- package/coverage/lcov-report/utilities/security.js.html +3 -3
- 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 +5 -5
- package/coverage/lcov.info +2301 -1599
- package/dist/api/controllers/application.js +16 -2
- package/dist/api/controllers/auth.js +3 -3
- package/dist/api/controllers/datasource.js +47 -16
- package/dist/api/controllers/deploy/index.js +2 -0
- package/dist/api/controllers/dev.js +4 -1
- package/dist/api/controllers/query.js +30 -58
- package/dist/api/controllers/row/ExternalRequest.js +37 -14
- package/dist/api/controllers/row/external.js +1 -0
- package/dist/api/controllers/row/utils.js +6 -12
- package/dist/api/controllers/static/index.js +1 -1
- package/dist/api/controllers/table/external.js +242 -0
- package/dist/api/controllers/table/index.js +49 -123
- package/dist/api/controllers/table/internal.js +150 -0
- package/dist/api/controllers/table/utils.js +62 -28
- package/dist/api/controllers/user.js +123 -11
- package/dist/api/routes/query.js +1 -1
- package/dist/api/routes/table.js +7 -1
- package/dist/api/routes/user.js +2 -1
- package/dist/app.js +2 -11
- package/dist/automations/bullboard.js +37 -10
- package/dist/automations/triggers.js +7 -3
- package/dist/automations/utils.js +11 -2
- package/dist/constants/index.js +13 -0
- package/dist/definitions/datasource.js +4 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/datasourcePlus.js +2 -0
- package/dist/integrations/base/sql.js +334 -180
- package/dist/integrations/base/sqlTable.js +143 -0
- package/dist/integrations/base/utils.js +30 -0
- package/dist/integrations/microsoftSqlServer.js +117 -9
- package/dist/integrations/mysql.js +14 -84
- package/dist/integrations/postgres.js +35 -28
- package/dist/integrations/utils.js +56 -9
- package/dist/middleware/authorized.js +2 -1
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +7 -6
- package/dist/tests/utilities/TestConfiguration.js +2 -1
- package/dist/{automations/thread.js → threads/automation.js} +23 -7
- package/dist/threads/index.js +58 -0
- package/dist/threads/query.js +61 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/csvParser.js +46 -5
- package/dist/utilities/global.js +6 -2
- package/dist/utilities/index.js +18 -2
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +8 -7
- package/scripts/integrations/mssql/data/Dockerfile +9 -0
- package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
- package/scripts/integrations/mssql/data/setup.sql +54 -0
- package/scripts/integrations/mssql/docker-compose.yaml +12 -0
- package/scripts/integrations/mssql/reset.sh +3 -0
- package/scripts/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +19 -2
- package/src/api/controllers/auth.js +3 -0
- package/src/api/controllers/datasource.js +56 -16
- package/src/api/controllers/deploy/index.js +2 -0
- package/src/api/controllers/dev.js +4 -1
- package/src/api/controllers/query.js +29 -81
- package/src/api/controllers/row/ExternalRequest.ts +47 -16
- package/src/api/controllers/row/external.js +2 -0
- package/src/api/controllers/row/utils.js +8 -11
- package/src/api/controllers/static/index.js +1 -1
- package/src/api/controllers/table/external.js +300 -0
- package/src/api/controllers/table/index.js +47 -137
- package/src/api/controllers/table/internal.js +155 -0
- package/src/api/controllers/table/utils.js +74 -33
- package/src/api/controllers/user.js +132 -13
- package/src/api/routes/query.js +1 -0
- package/src/api/routes/table.js +11 -0
- package/src/api/routes/tests/datasource.spec.js +2 -2
- package/src/api/routes/tests/misc.spec.js +5 -1
- package/src/api/routes/tests/query.spec.js +0 -1
- package/src/api/routes/user.js +5 -0
- package/src/app.ts +2 -10
- package/src/automations/bullboard.js +28 -11
- package/src/automations/tests/automation.spec.js +3 -4
- package/src/automations/triggers.js +7 -3
- package/src/automations/utils.js +12 -2
- package/src/constants/index.js +15 -0
- package/src/definitions/common.ts +7 -1
- package/src/definitions/datasource.ts +9 -3
- package/src/integrations/airtable.ts +2 -1
- package/src/integrations/arangodb.ts +2 -1
- package/src/integrations/base/IntegrationBase.ts +6 -0
- package/src/integrations/base/datasourcePlus.ts +9 -0
- package/src/integrations/base/sql.ts +359 -222
- package/src/integrations/base/sqlTable.ts +180 -0
- package/src/integrations/base/utils.ts +22 -0
- package/src/integrations/couchdb.ts +2 -1
- package/src/integrations/dynamodb.ts +2 -1
- package/src/integrations/elasticsearch.ts +2 -1
- package/src/integrations/microsoftSqlServer.ts +145 -13
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +20 -94
- package/src/integrations/postgres.ts +45 -35
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +2 -1
- package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
- package/src/integrations/tests/postgres.spec.js +4 -0
- package/src/integrations/utils.ts +60 -8
- package/src/middleware/authorized.js +2 -1
- package/src/middleware/builder.js +4 -1
- package/src/tests/utilities/TestConfiguration.js +2 -1
- package/src/{automations/thread.js → threads/automation.js} +24 -7
- package/src/threads/index.js +60 -0
- package/src/threads/query.js +63 -0
- package/src/utilities/csvParser.js +48 -5
- package/src/utilities/global.js +7 -2
- package/src/utilities/index.js +18 -2
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/scriptRunner.js +4 -1
- package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
- package/src/utilities/tests/csvParser.spec.js +3 -0
- package/tsconfig.json +1 -1
- package/builder/assets/index.34964222.js +0 -201
- package/builder/assets/index.7469e1e4.css +0 -29
- package/builder/assets/vendor.278a305c.js +0 -9
- package/builder/assets/vendor.d75d5eb7.css +0 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Knex, knex } from "knex"
|
|
2
|
+
import { Table } from "../../definitions/common"
|
|
3
|
+
import { Operation, QueryJson } from "../../definitions/datasource"
|
|
4
|
+
import { breakExternalTableId } from "../utils"
|
|
5
|
+
import SchemaBuilder = Knex.SchemaBuilder
|
|
6
|
+
import CreateTableBuilder = Knex.CreateTableBuilder
|
|
7
|
+
const { FieldTypes, RelationshipTypes } = require("../../constants")
|
|
8
|
+
|
|
9
|
+
function generateSchema(
|
|
10
|
+
schema: CreateTableBuilder,
|
|
11
|
+
table: Table,
|
|
12
|
+
tables: Record<string, Table>,
|
|
13
|
+
oldTable: null | Table = null
|
|
14
|
+
) {
|
|
15
|
+
let primaryKey = table && table.primary ? table.primary[0] : null
|
|
16
|
+
const columns = Object.values(table.schema)
|
|
17
|
+
// all columns in a junction table will be meta
|
|
18
|
+
let metaCols = columns.filter(col => col.meta)
|
|
19
|
+
let isJunction = metaCols.length === columns.length
|
|
20
|
+
// can't change primary once its set for now
|
|
21
|
+
if (primaryKey && !oldTable && !isJunction) {
|
|
22
|
+
schema.increments(primaryKey).primary()
|
|
23
|
+
} else if (!oldTable && isJunction) {
|
|
24
|
+
schema.primary(metaCols.map(col => col.name))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// check if any columns need added
|
|
28
|
+
const foreignKeys = Object.values(table.schema).map(col => col.foreignKey)
|
|
29
|
+
for (let [key, column] of Object.entries(table.schema)) {
|
|
30
|
+
// skip things that are already correct
|
|
31
|
+
const oldColumn = oldTable ? oldTable.schema[key] : null
|
|
32
|
+
if ((oldColumn && oldColumn.type) || (primaryKey === key && !isJunction)) {
|
|
33
|
+
continue
|
|
34
|
+
}
|
|
35
|
+
switch (column.type) {
|
|
36
|
+
case FieldTypes.STRING:
|
|
37
|
+
case FieldTypes.OPTIONS:
|
|
38
|
+
case FieldTypes.LONGFORM:
|
|
39
|
+
schema.string(key)
|
|
40
|
+
break
|
|
41
|
+
case FieldTypes.NUMBER:
|
|
42
|
+
// if meta is specified then this is a junction table entry
|
|
43
|
+
if (column.meta && column.meta.toKey && column.meta.toTable) {
|
|
44
|
+
const { toKey, toTable } = column.meta
|
|
45
|
+
schema.integer(key).unsigned()
|
|
46
|
+
schema.foreign(key).references(`${toTable}.${toKey}`)
|
|
47
|
+
} else if (foreignKeys.indexOf(key) === -1) {
|
|
48
|
+
schema.float(key)
|
|
49
|
+
}
|
|
50
|
+
break
|
|
51
|
+
case FieldTypes.BOOLEAN:
|
|
52
|
+
schema.boolean(key)
|
|
53
|
+
break
|
|
54
|
+
case FieldTypes.DATETIME:
|
|
55
|
+
schema.datetime(key)
|
|
56
|
+
break
|
|
57
|
+
case FieldTypes.ARRAY:
|
|
58
|
+
schema.json(key)
|
|
59
|
+
break
|
|
60
|
+
case FieldTypes.LINK:
|
|
61
|
+
// this side of the relationship doesn't need any SQL work
|
|
62
|
+
if (
|
|
63
|
+
column.relationshipType !== RelationshipTypes.MANY_TO_ONE &&
|
|
64
|
+
column.relationshipType !== RelationshipTypes.MANY_TO_MANY
|
|
65
|
+
) {
|
|
66
|
+
if (!column.foreignKey || !column.tableId) {
|
|
67
|
+
throw "Invalid relationship schema"
|
|
68
|
+
}
|
|
69
|
+
const { tableName } = breakExternalTableId(column.tableId)
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
const relatedTable = tables[tableName]
|
|
72
|
+
if (!relatedTable) {
|
|
73
|
+
throw "Referenced table doesn't exist"
|
|
74
|
+
}
|
|
75
|
+
schema.integer(column.foreignKey).unsigned()
|
|
76
|
+
schema
|
|
77
|
+
.foreign(column.foreignKey)
|
|
78
|
+
.references(`${tableName}.${relatedTable.primary[0]}`)
|
|
79
|
+
}
|
|
80
|
+
break
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// need to check if any columns have been deleted
|
|
85
|
+
if (oldTable) {
|
|
86
|
+
const deletedColumns = Object.entries(oldTable.schema)
|
|
87
|
+
.filter(
|
|
88
|
+
([key, schema]) =>
|
|
89
|
+
schema.type !== FieldTypes.LINK && table.schema[key] == null
|
|
90
|
+
)
|
|
91
|
+
.map(([key]) => key)
|
|
92
|
+
deletedColumns.forEach(key => {
|
|
93
|
+
if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {
|
|
94
|
+
schema.dropForeign(key)
|
|
95
|
+
}
|
|
96
|
+
schema.dropColumn(key)
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return schema
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function buildCreateTable(
|
|
104
|
+
knex: Knex,
|
|
105
|
+
table: Table,
|
|
106
|
+
tables: Record<string, Table>
|
|
107
|
+
): SchemaBuilder {
|
|
108
|
+
return knex.schema.createTable(table.name, schema => {
|
|
109
|
+
generateSchema(schema, table, tables)
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function buildUpdateTable(
|
|
114
|
+
knex: Knex,
|
|
115
|
+
table: Table,
|
|
116
|
+
tables: Record<string, Table>,
|
|
117
|
+
oldTable: Table
|
|
118
|
+
): SchemaBuilder {
|
|
119
|
+
return knex.schema.alterTable(table.name, schema => {
|
|
120
|
+
generateSchema(schema, table, tables, oldTable)
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function buildDeleteTable(knex: Knex, table: Table): SchemaBuilder {
|
|
125
|
+
return knex.schema.dropTable(table.name)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class SqlTableQueryBuilder {
|
|
129
|
+
private readonly sqlClient: string
|
|
130
|
+
|
|
131
|
+
// pass through client to get flavour of SQL
|
|
132
|
+
constructor(client: string) {
|
|
133
|
+
this.sqlClient = client
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getSqlClient(): string {
|
|
137
|
+
return this.sqlClient
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param json the input JSON structure from which an SQL query will be built.
|
|
142
|
+
* @return {string} the operation that was found in the JSON.
|
|
143
|
+
*/
|
|
144
|
+
_operation(json: QueryJson): Operation {
|
|
145
|
+
return json.endpoint.operation
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
_tableQuery(json: QueryJson): any {
|
|
149
|
+
const client = knex({ client: this.sqlClient })
|
|
150
|
+
let query
|
|
151
|
+
if (!json.table || !json.meta || !json.meta.tables) {
|
|
152
|
+
throw "Cannot execute without table being specified"
|
|
153
|
+
}
|
|
154
|
+
switch (this._operation(json)) {
|
|
155
|
+
case Operation.CREATE_TABLE:
|
|
156
|
+
query = buildCreateTable(client, json.table, json.meta.tables)
|
|
157
|
+
break
|
|
158
|
+
case Operation.UPDATE_TABLE:
|
|
159
|
+
if (!json.meta || !json.meta.table) {
|
|
160
|
+
throw "Must specify old table for update"
|
|
161
|
+
}
|
|
162
|
+
query = buildUpdateTable(
|
|
163
|
+
client,
|
|
164
|
+
json.table,
|
|
165
|
+
json.meta.tables,
|
|
166
|
+
json.meta.table
|
|
167
|
+
)
|
|
168
|
+
break
|
|
169
|
+
case Operation.DELETE_TABLE:
|
|
170
|
+
query = buildDeleteTable(client, json.table)
|
|
171
|
+
break
|
|
172
|
+
default:
|
|
173
|
+
throw "Table operation is of unknown type"
|
|
174
|
+
}
|
|
175
|
+
return query.toSQL()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export default SqlTableQueryBuilder
|
|
180
|
+
module.exports = SqlTableQueryBuilder
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { QueryJson } from "../../definitions/datasource"
|
|
2
|
+
import { Datasource } from "../../definitions/common"
|
|
3
|
+
|
|
4
|
+
module DatasourceUtils {
|
|
5
|
+
const { integrations } = require("../index")
|
|
6
|
+
|
|
7
|
+
export async function makeExternalQuery(
|
|
8
|
+
datasource: Datasource,
|
|
9
|
+
json: QueryJson
|
|
10
|
+
) {
|
|
11
|
+
const Integration = integrations[datasource.source]
|
|
12
|
+
// query is the opinionated function
|
|
13
|
+
if (Integration.prototype.query) {
|
|
14
|
+
const integration = new Integration(datasource.config)
|
|
15
|
+
return integration.query(json)
|
|
16
|
+
} else {
|
|
17
|
+
throw "Datasource does not support query."
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports.makeExternalQuery = makeExternalQuery
|
|
22
|
+
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module CouchDBModule {
|
|
8
9
|
const PouchDB = require("pouchdb")
|
|
@@ -50,7 +51,7 @@ module CouchDBModule {
|
|
|
50
51
|
},
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
class CouchDBIntegration {
|
|
54
|
+
class CouchDBIntegration implements IntegrationBase {
|
|
54
55
|
private config: CouchDBConfig
|
|
55
56
|
private client: any
|
|
56
57
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module DynamoModule {
|
|
8
9
|
const AWS = require("aws-sdk")
|
|
@@ -113,7 +114,7 @@ module DynamoModule {
|
|
|
113
114
|
},
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
class DynamoDBIntegration {
|
|
117
|
+
class DynamoDBIntegration implements IntegrationBase {
|
|
117
118
|
private config: DynamoDBConfig
|
|
118
119
|
private client: any
|
|
119
120
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module ElasticsearchModule {
|
|
8
9
|
const { Client } = require("@elastic/elasticsearch")
|
|
@@ -74,7 +75,7 @@ module ElasticsearchModule {
|
|
|
74
75
|
},
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
class ElasticSearchIntegration {
|
|
78
|
+
class ElasticSearchIntegration implements IntegrationBase {
|
|
78
79
|
private config: ElasticsearchConfig
|
|
79
80
|
private client: any
|
|
80
81
|
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Integration,
|
|
3
2
|
DatasourceFieldTypes,
|
|
4
|
-
|
|
3
|
+
Integration,
|
|
4
|
+
Operation,
|
|
5
5
|
QueryJson,
|
|
6
|
+
QueryTypes,
|
|
6
7
|
SqlQuery,
|
|
7
8
|
} from "../definitions/datasource"
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getSqlQuery,
|
|
11
|
+
buildExternalTableId,
|
|
12
|
+
convertSqlType,
|
|
13
|
+
finaliseExternalTables,
|
|
14
|
+
SqlClients,
|
|
15
|
+
} from "./utils"
|
|
16
|
+
import { DatasourcePlus } from "./base/datasourcePlus"
|
|
17
|
+
import { Table, TableSchema } from "../definitions/common"
|
|
9
18
|
|
|
10
19
|
module MSSQLModule {
|
|
11
20
|
const sqlServer = require("mssql")
|
|
@@ -22,6 +31,7 @@ module MSSQLModule {
|
|
|
22
31
|
|
|
23
32
|
const SCHEMA: Integration = {
|
|
24
33
|
docs: "https://github.com/tediousjs/node-mssql",
|
|
34
|
+
plus: true,
|
|
25
35
|
description:
|
|
26
36
|
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
|
27
37
|
friendlyName: "MS SQL Server",
|
|
@@ -69,26 +79,84 @@ module MSSQLModule {
|
|
|
69
79
|
},
|
|
70
80
|
}
|
|
71
81
|
|
|
72
|
-
async function internalQuery(
|
|
82
|
+
async function internalQuery(
|
|
83
|
+
client: any,
|
|
84
|
+
query: SqlQuery,
|
|
85
|
+
operation: string | undefined = undefined
|
|
86
|
+
) {
|
|
87
|
+
const request = client.request()
|
|
73
88
|
try {
|
|
74
|
-
|
|
89
|
+
if (Array.isArray(query.bindings)) {
|
|
90
|
+
let count = 0
|
|
91
|
+
for (let binding of query.bindings) {
|
|
92
|
+
request.input(`p${count++}`, binding)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// this is a hack to get the inserted ID back,
|
|
96
|
+
// no way to do this with Knex nicely
|
|
97
|
+
const sql =
|
|
98
|
+
operation === Operation.CREATE
|
|
99
|
+
? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`
|
|
100
|
+
: query.sql
|
|
101
|
+
return await request.query(sql)
|
|
75
102
|
} catch (err) {
|
|
76
103
|
// @ts-ignore
|
|
77
104
|
throw new Error(err)
|
|
78
105
|
}
|
|
79
106
|
}
|
|
80
107
|
|
|
81
|
-
class SqlServerIntegration extends Sql {
|
|
108
|
+
class SqlServerIntegration extends Sql implements DatasourcePlus {
|
|
82
109
|
private readonly config: MSSQLConfig
|
|
83
110
|
static pool: any
|
|
111
|
+
public tables: Record<string, Table> = {}
|
|
112
|
+
public schemaErrors: Record<string, string> = {}
|
|
113
|
+
|
|
114
|
+
MASTER_TABLES = [
|
|
115
|
+
"spt_fallback_db",
|
|
116
|
+
"spt_fallback_dev",
|
|
117
|
+
"spt_fallback_usg",
|
|
118
|
+
"spt_monitor",
|
|
119
|
+
"MSreplication_options",
|
|
120
|
+
]
|
|
121
|
+
TABLES_SQL =
|
|
122
|
+
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"
|
|
123
|
+
|
|
124
|
+
getDefinitionSQL(tableName: string) {
|
|
125
|
+
return `select *
|
|
126
|
+
from INFORMATION_SCHEMA.COLUMNS
|
|
127
|
+
where TABLE_NAME='${tableName}'`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getConstraintsSQL(tableName: string) {
|
|
131
|
+
return `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
|
|
132
|
+
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
|
|
133
|
+
ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
|
|
134
|
+
AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
|
|
135
|
+
AND KU.table_name='${tableName}'
|
|
136
|
+
ORDER BY
|
|
137
|
+
KU.TABLE_NAME,
|
|
138
|
+
KU.ORDINAL_POSITION;`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
getAutoColumnsSQL(tableName: string) {
|
|
142
|
+
return `SELECT
|
|
143
|
+
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed')
|
|
144
|
+
AS IS_COMPUTED,
|
|
145
|
+
COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity')
|
|
146
|
+
AS IS_IDENTITY,
|
|
147
|
+
*
|
|
148
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
149
|
+
WHERE TABLE_NAME='${tableName}'`
|
|
150
|
+
}
|
|
84
151
|
|
|
85
152
|
constructor(config: MSSQLConfig) {
|
|
86
|
-
super(
|
|
153
|
+
super(SqlClients.MS_SQL)
|
|
87
154
|
this.config = config
|
|
88
155
|
const clientCfg = {
|
|
89
156
|
...this.config,
|
|
90
157
|
options: {
|
|
91
158
|
encrypt: this.config.encrypt,
|
|
159
|
+
enableArithAbort: true,
|
|
92
160
|
},
|
|
93
161
|
}
|
|
94
162
|
delete clientCfg.encrypt
|
|
@@ -99,14 +167,75 @@ module MSSQLModule {
|
|
|
99
167
|
|
|
100
168
|
async connect() {
|
|
101
169
|
try {
|
|
102
|
-
|
|
103
|
-
this.client = client.request()
|
|
170
|
+
this.client = await this.pool.connect()
|
|
104
171
|
} catch (err) {
|
|
105
172
|
// @ts-ignore
|
|
106
173
|
throw new Error(err)
|
|
107
174
|
}
|
|
108
175
|
}
|
|
109
176
|
|
|
177
|
+
async runSQL(sql: string) {
|
|
178
|
+
return (await internalQuery(this.client, getSqlQuery(sql))).recordset
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Fetches the tables from the sql server database and assigns them to the datasource.
|
|
183
|
+
* @param {*} datasourceId - datasourceId to fetch
|
|
184
|
+
* @param entities - the tables that are to be built
|
|
185
|
+
*/
|
|
186
|
+
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
|
|
187
|
+
await this.connect()
|
|
188
|
+
let tableNames = await this.runSQL(this.TABLES_SQL)
|
|
189
|
+
if (tableNames == null || !Array.isArray(tableNames)) {
|
|
190
|
+
throw "Unable to get list of tables in database"
|
|
191
|
+
}
|
|
192
|
+
tableNames = tableNames
|
|
193
|
+
.map((record: any) => record.TABLE_NAME)
|
|
194
|
+
.filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)
|
|
195
|
+
|
|
196
|
+
const tables: Record<string, Table> = {}
|
|
197
|
+
for (let tableName of tableNames) {
|
|
198
|
+
// get the column definition (type)
|
|
199
|
+
const definition = await this.runSQL(this.getDefinitionSQL(tableName))
|
|
200
|
+
// find primary key constraints
|
|
201
|
+
const constraints = await this.runSQL(this.getConstraintsSQL(tableName))
|
|
202
|
+
// find the computed and identity columns (auto columns)
|
|
203
|
+
const columns = await this.runSQL(this.getAutoColumnsSQL(tableName))
|
|
204
|
+
const primaryKeys = constraints
|
|
205
|
+
.filter(
|
|
206
|
+
(constraint: any) => constraint.CONSTRAINT_TYPE === "PRIMARY KEY"
|
|
207
|
+
)
|
|
208
|
+
.map((constraint: any) => constraint.COLUMN_NAME)
|
|
209
|
+
const autoColumns = columns
|
|
210
|
+
.filter((col: any) => col.IS_COMPUTED || col.IS_IDENTITY)
|
|
211
|
+
.map((col: any) => col.COLUMN_NAME)
|
|
212
|
+
|
|
213
|
+
let schema: TableSchema = {}
|
|
214
|
+
for (let def of definition) {
|
|
215
|
+
const name = def.COLUMN_NAME
|
|
216
|
+
if (typeof name !== "string") {
|
|
217
|
+
continue
|
|
218
|
+
}
|
|
219
|
+
const type: string = convertSqlType(def.DATA_TYPE)
|
|
220
|
+
|
|
221
|
+
schema[name] = {
|
|
222
|
+
autocolumn: !!autoColumns.find((col: string) => col === name),
|
|
223
|
+
name: name,
|
|
224
|
+
type,
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
tables[tableName] = {
|
|
228
|
+
_id: buildExternalTableId(datasourceId, tableName),
|
|
229
|
+
primary: primaryKeys,
|
|
230
|
+
name: tableName,
|
|
231
|
+
schema,
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const final = finaliseExternalTables(tables, entities)
|
|
235
|
+
this.tables = final.tables
|
|
236
|
+
this.schemaErrors = final.errors
|
|
237
|
+
}
|
|
238
|
+
|
|
110
239
|
async read(query: SqlQuery | string) {
|
|
111
240
|
await this.connect()
|
|
112
241
|
const response = await internalQuery(this.client, getSqlQuery(query))
|
|
@@ -132,10 +261,13 @@ module MSSQLModule {
|
|
|
132
261
|
}
|
|
133
262
|
|
|
134
263
|
async query(json: QueryJson) {
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
264
|
+
await this.connect()
|
|
265
|
+
const operation = this._operation(json)
|
|
266
|
+
const queryFn = (query: any, op: string) =>
|
|
267
|
+
internalQuery(this.client, query, op)
|
|
268
|
+
const processFn = (result: any) =>
|
|
269
|
+
result.recordset ? result.recordset : [{ [operation]: true }]
|
|
270
|
+
return this.queryWithReturning(json, queryFn, processFn)
|
|
139
271
|
}
|
|
140
272
|
}
|
|
141
273
|
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
5
|
} from "../definitions/datasource"
|
|
6
|
+
import { IntegrationBase } from "./base/IntegrationBase"
|
|
6
7
|
|
|
7
8
|
module MongoDBModule {
|
|
8
9
|
const { MongoClient } = require("mongodb")
|
|
@@ -62,7 +63,7 @@ module MongoDBModule {
|
|
|
62
63
|
},
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
class MongoIntegration {
|
|
66
|
+
class MongoIntegration implements IntegrationBase {
|
|
66
67
|
private config: MongoDBConfig
|
|
67
68
|
private client: any
|
|
68
69
|
|
|
@@ -2,22 +2,22 @@ import {
|
|
|
2
2
|
Integration,
|
|
3
3
|
DatasourceFieldTypes,
|
|
4
4
|
QueryTypes,
|
|
5
|
-
Operation,
|
|
6
5
|
QueryJson,
|
|
7
6
|
SqlQuery,
|
|
8
7
|
} from "../definitions/datasource"
|
|
9
8
|
import { Table, TableSchema } from "../definitions/common"
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getSqlQuery,
|
|
11
|
+
SqlClients,
|
|
12
|
+
buildExternalTableId,
|
|
13
|
+
convertSqlType,
|
|
14
|
+
finaliseExternalTables,
|
|
15
|
+
} from "./utils"
|
|
16
|
+
import { DatasourcePlus } from "./base/datasourcePlus"
|
|
11
17
|
|
|
12
18
|
module MySQLModule {
|
|
13
19
|
const mysql = require("mysql2")
|
|
14
20
|
const Sql = require("./base/sql")
|
|
15
|
-
const {
|
|
16
|
-
buildExternalTableId,
|
|
17
|
-
convertType,
|
|
18
|
-
copyExistingPropsOver,
|
|
19
|
-
} = require("./utils")
|
|
20
|
-
const { FieldTypes } = require("../constants")
|
|
21
21
|
|
|
22
22
|
interface MySQLConfig {
|
|
23
23
|
host: string
|
|
@@ -28,30 +28,6 @@ module MySQLModule {
|
|
|
28
28
|
ssl?: object
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const TYPE_MAP = {
|
|
32
|
-
text: FieldTypes.LONGFORM,
|
|
33
|
-
blob: FieldTypes.LONGFORM,
|
|
34
|
-
enum: FieldTypes.STRING,
|
|
35
|
-
varchar: FieldTypes.STRING,
|
|
36
|
-
float: FieldTypes.NUMBER,
|
|
37
|
-
int: FieldTypes.NUMBER,
|
|
38
|
-
numeric: FieldTypes.NUMBER,
|
|
39
|
-
bigint: FieldTypes.NUMBER,
|
|
40
|
-
mediumint: FieldTypes.NUMBER,
|
|
41
|
-
decimal: FieldTypes.NUMBER,
|
|
42
|
-
dec: FieldTypes.NUMBER,
|
|
43
|
-
double: FieldTypes.NUMBER,
|
|
44
|
-
real: FieldTypes.NUMBER,
|
|
45
|
-
fixed: FieldTypes.NUMBER,
|
|
46
|
-
smallint: FieldTypes.NUMBER,
|
|
47
|
-
timestamp: FieldTypes.DATETIME,
|
|
48
|
-
date: FieldTypes.DATETIME,
|
|
49
|
-
datetime: FieldTypes.DATETIME,
|
|
50
|
-
time: FieldTypes.DATETIME,
|
|
51
|
-
tinyint: FieldTypes.BOOLEAN,
|
|
52
|
-
json: DatasourceFieldTypes.JSON,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
31
|
const SCHEMA: Integration = {
|
|
56
32
|
docs: "https://github.com/mysqljs/mysql",
|
|
57
33
|
plus: true,
|
|
@@ -131,12 +107,14 @@ module MySQLModule {
|
|
|
131
107
|
})
|
|
132
108
|
}
|
|
133
109
|
|
|
134
|
-
class MySQLIntegration extends Sql {
|
|
110
|
+
class MySQLIntegration extends Sql implements DatasourcePlus {
|
|
135
111
|
private config: MySQLConfig
|
|
136
112
|
private readonly client: any
|
|
113
|
+
public tables: Record<string, Table> = {}
|
|
114
|
+
public schemaErrors: Record<string, string> = {}
|
|
137
115
|
|
|
138
116
|
constructor(config: MySQLConfig) {
|
|
139
|
-
super(
|
|
117
|
+
super(SqlClients.MY_SQL)
|
|
140
118
|
this.config = config
|
|
141
119
|
if (config.ssl && Object.keys(config.ssl).length === 0) {
|
|
142
120
|
delete config.ssl
|
|
@@ -181,14 +159,10 @@ module MySQLModule {
|
|
|
181
159
|
schema[columnName] = {
|
|
182
160
|
name: columnName,
|
|
183
161
|
autocolumn: isAuto,
|
|
184
|
-
type:
|
|
162
|
+
type: convertSqlType(column.Type),
|
|
185
163
|
constraints,
|
|
186
164
|
}
|
|
187
165
|
}
|
|
188
|
-
// for now just default to first column
|
|
189
|
-
if (primaryKeys.length === 0) {
|
|
190
|
-
primaryKeys.push(descResp[0].Field)
|
|
191
|
-
}
|
|
192
166
|
if (!tables[tableName]) {
|
|
193
167
|
tables[tableName] = {
|
|
194
168
|
_id: buildExternalTableId(datasourceId, tableName),
|
|
@@ -197,12 +171,12 @@ module MySQLModule {
|
|
|
197
171
|
schema,
|
|
198
172
|
}
|
|
199
173
|
}
|
|
200
|
-
|
|
201
|
-
copyExistingPropsOver(tableName, tables, entities)
|
|
202
174
|
}
|
|
203
175
|
|
|
204
176
|
this.client.end()
|
|
205
|
-
|
|
177
|
+
const final = finaliseExternalTables(tables, entities)
|
|
178
|
+
this.tables = final.tables
|
|
179
|
+
this.schemaErrors = final.errors
|
|
206
180
|
}
|
|
207
181
|
|
|
208
182
|
async create(query: SqlQuery | string) {
|
|
@@ -210,7 +184,7 @@ module MySQLModule {
|
|
|
210
184
|
return results.length ? results : [{ created: true }]
|
|
211
185
|
}
|
|
212
186
|
|
|
213
|
-
read(query: SqlQuery | string) {
|
|
187
|
+
async read(query: SqlQuery | string) {
|
|
214
188
|
return internalQuery(this.client, getSqlQuery(query))
|
|
215
189
|
}
|
|
216
190
|
|
|
@@ -224,60 +198,12 @@ module MySQLModule {
|
|
|
224
198
|
return results.length ? results : [{ deleted: true }]
|
|
225
199
|
}
|
|
226
200
|
|
|
227
|
-
async getReturningRow(json: QueryJson) {
|
|
228
|
-
if (!json.extra || !json.extra.idFilter) {
|
|
229
|
-
return {}
|
|
230
|
-
}
|
|
231
|
-
const input = this._query({
|
|
232
|
-
endpoint: {
|
|
233
|
-
...json.endpoint,
|
|
234
|
-
operation: Operation.READ,
|
|
235
|
-
},
|
|
236
|
-
fields: [],
|
|
237
|
-
filters: json.extra.idFilter,
|
|
238
|
-
paginate: {
|
|
239
|
-
limit: 1,
|
|
240
|
-
},
|
|
241
|
-
})
|
|
242
|
-
return internalQuery(this.client, input, false)
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// when creating if an ID has been inserted need to make sure
|
|
246
|
-
// the id filter is enriched with it before trying to retrieve the row
|
|
247
|
-
checkLookupKeys(results: any, json: QueryJson) {
|
|
248
|
-
if (!results?.insertId || !json.meta?.table || !json.meta.table.primary) {
|
|
249
|
-
return json
|
|
250
|
-
}
|
|
251
|
-
const primaryKey = json.meta.table.primary?.[0]
|
|
252
|
-
json.extra = {
|
|
253
|
-
idFilter: {
|
|
254
|
-
equal: {
|
|
255
|
-
[primaryKey]: results.insertId,
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
}
|
|
259
|
-
return json
|
|
260
|
-
}
|
|
261
|
-
|
|
262
201
|
async query(json: QueryJson) {
|
|
263
|
-
const operation = this._operation(json)
|
|
264
202
|
this.client.connect()
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
// need to manage returning, a feature mySQL can't do
|
|
268
|
-
if (operation === operation.DELETE) {
|
|
269
|
-
row = this.getReturningRow(json)
|
|
270
|
-
}
|
|
271
|
-
const results = await internalQuery(this.client, input, false)
|
|
272
|
-
// same as delete, manage returning
|
|
273
|
-
if (operation === Operation.CREATE || operation === Operation.UPDATE) {
|
|
274
|
-
row = this.getReturningRow(this.checkLookupKeys(results, json))
|
|
275
|
-
}
|
|
203
|
+
const queryFn = (query: any) => internalQuery(this.client, query, false)
|
|
204
|
+
const output = await this.queryWithReturning(json, queryFn)
|
|
276
205
|
this.client.end()
|
|
277
|
-
|
|
278
|
-
return row
|
|
279
|
-
}
|
|
280
|
-
return results.length ? results : [{ [operation.toLowerCase()]: true }]
|
|
206
|
+
return output
|
|
281
207
|
}
|
|
282
208
|
}
|
|
283
209
|
|