@budibase/server 1.0.80-alpha.1 → 1.0.80-alpha.4
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.c0b657be.js → index.db9b03fd.js} +1 -1
- package/builder/index.html +1 -1
- package/coverage/clover.xml +103 -99
- package/coverage/coverage-final.json +1 -1
- 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/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/migrations.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 +1 -1
- 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/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- 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/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +51 -9
- package/coverage/lcov-report/api/controllers/table/index.html +14 -14
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
- 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/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/migrations.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/utils/index.html +1 -1
- package/coverage/lcov-report/api/routes/utils/validators.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 +14 -14
- 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 +1 -1
- package/coverage/lcov-report/middleware/index.html +1 -1
- 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/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.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 +169 -162
- package/dist/api/controllers/table/external.js +8 -2
- package/dist/integrations/base/sql.js +16 -1
- package/dist/integrations/base/sqlTable.js +21 -9
- package/dist/integrations/microsoftSqlServer.js +28 -17
- package/dist/integrations/utils.js +32 -15
- package/dist/package.json +4 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/scripts/integrations/mssql/data/setup.sql +18 -1
- package/scripts/integrations/postgres/init.sql +6 -0
- package/specs/generate.js +13 -2
- package/specs/openapi.json +13 -3
- package/specs/openapi.yaml +10 -2
- package/src/api/controllers/table/external.js +16 -2
- package/src/definitions/datasource.ts +7 -0
- package/src/integrations/base/sql.ts +16 -1
- package/src/integrations/base/sqlTable.ts +35 -13
- package/src/integrations/microsoftSqlServer.ts +52 -32
- package/src/integrations/utils.ts +43 -15
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.80-alpha.
|
|
4
|
+
"version": "1.0.80-alpha.4",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
"license": "GPL-3.0",
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@apidevtools/swagger-parser": "^10.0.3",
|
|
74
|
-
"@budibase/backend-core": "^1.0.80-alpha.
|
|
75
|
-
"@budibase/client": "^1.0.80-alpha.
|
|
76
|
-
"@budibase/string-templates": "^1.0.80-alpha.
|
|
74
|
+
"@budibase/backend-core": "^1.0.80-alpha.4",
|
|
75
|
+
"@budibase/client": "^1.0.80-alpha.4",
|
|
76
|
+
"@budibase/string-templates": "^1.0.80-alpha.4",
|
|
77
77
|
"@bull-board/api": "^3.7.0",
|
|
78
78
|
"@bull-board/koa": "^3.7.0",
|
|
79
79
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -175,5 +175,5 @@
|
|
|
175
175
|
"optionalDependencies": {
|
|
176
176
|
"oracledb": "^5.3.0"
|
|
177
177
|
},
|
|
178
|
-
"gitHead": "
|
|
178
|
+
"gitHead": "b39d0edec7890af5dcdf92998eee7cfe33f70b95"
|
|
179
179
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
USE master;
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
IF NOT EXISTS(SELECT 1 FROM sys.schemas WHERE name = 'Chains')
|
|
4
|
+
BEGIN
|
|
5
|
+
EXEC sys.sp_executesql N'CREATE SCHEMA Chains;'
|
|
6
|
+
END
|
|
7
|
+
|
|
3
8
|
IF OBJECT_ID ('dbo.products', 'U') IS NOT NULL
|
|
4
9
|
DROP TABLE products;
|
|
5
10
|
GO
|
|
@@ -61,3 +66,15 @@ VALUES ('Bob', '30'),
|
|
|
61
66
|
('Bobert', '99'),
|
|
62
67
|
('Jan', '22'),
|
|
63
68
|
('Megan', '11');
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
IF OBJECT_ID ('Chains.sizes', 'U') IS NOT NULL
|
|
72
|
+
DROP TABLE Chains.sizes;
|
|
73
|
+
GO
|
|
74
|
+
CREATE TABLE Chains.sizes
|
|
75
|
+
(
|
|
76
|
+
sizeid int IDENTITY(1, 1),
|
|
77
|
+
name varchar(30),
|
|
78
|
+
CONSTRAINT pk_size PRIMARY KEY NONCLUSTERED (sizeid)
|
|
79
|
+
);
|
|
80
|
+
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
SELECT 'CREATE DATABASE main'
|
|
2
2
|
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'main')\gexec
|
|
3
|
+
CREATE SCHEMA test;
|
|
3
4
|
CREATE TYPE person_job AS ENUM ('qa', 'programmer', 'designer');
|
|
4
5
|
CREATE TABLE Persons (
|
|
5
6
|
PersonID SERIAL PRIMARY KEY,
|
|
@@ -37,6 +38,10 @@ CREATE TABLE Products_Tasks (
|
|
|
37
38
|
REFERENCES Tasks(TaskID),
|
|
38
39
|
PRIMARY KEY (ProductID, TaskID)
|
|
39
40
|
);
|
|
41
|
+
CREATE TABLE test.table1 (
|
|
42
|
+
id SERIAL PRIMARY KEY,
|
|
43
|
+
Name varchar(255)
|
|
44
|
+
);
|
|
40
45
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type) VALUES ('Mike', 'Hughes', '123 Fake Street', 'Belfast', 'qa');
|
|
41
46
|
INSERT INTO Persons (FirstName, LastName, Address, City, Type) VALUES ('John', 'Smith', '64 Updown Road', 'Dublin', 'programmer');
|
|
42
47
|
INSERT INTO Tasks (ExecutorID, QaID, TaskName, Completed) VALUES (1, 2, 'assembling', TRUE);
|
|
@@ -48,3 +53,4 @@ INSERT INTO Products_Tasks (ProductID, TaskID) VALUES (1, 1);
|
|
|
48
53
|
INSERT INTO Products_Tasks (ProductID, TaskID) VALUES (2, 1);
|
|
49
54
|
INSERT INTO Products_Tasks (ProductID, TaskID) VALUES (3, 1);
|
|
50
55
|
INSERT INTO Products_Tasks (ProductID, TaskID) VALUES (1, 2);
|
|
56
|
+
INSERT INTO test.table1 (Name) VALUES ('Test');
|
package/specs/generate.js
CHANGED
|
@@ -17,12 +17,23 @@ const options = {
|
|
|
17
17
|
},
|
|
18
18
|
servers: [
|
|
19
19
|
{
|
|
20
|
-
url: "
|
|
20
|
+
url: "https://budibase.app/api/public/v1",
|
|
21
21
|
description: "Budibase Cloud API",
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
url: "{protocol}://{hostname}
|
|
24
|
+
url: "{protocol}://{hostname}/api/public/v1",
|
|
25
25
|
description: "Budibase self hosted API",
|
|
26
|
+
variables: {
|
|
27
|
+
protocol: {
|
|
28
|
+
default: "http",
|
|
29
|
+
description:
|
|
30
|
+
"Whether HTTP or HTTPS should be used to communicate with your Budibase instance.",
|
|
31
|
+
},
|
|
32
|
+
hostname: {
|
|
33
|
+
default: "localhost:10000",
|
|
34
|
+
description: "The URL of your Budibase instance.",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
26
37
|
},
|
|
27
38
|
],
|
|
28
39
|
components: {
|
package/specs/openapi.json
CHANGED
|
@@ -7,12 +7,22 @@
|
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
10
|
-
"url": "
|
|
10
|
+
"url": "https://budibase.app/api/public/v1",
|
|
11
11
|
"description": "Budibase Cloud API"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
|
-
"url": "{protocol}://{hostname}
|
|
15
|
-
"description": "Budibase self hosted API"
|
|
14
|
+
"url": "{protocol}://{hostname}/api/public/v1",
|
|
15
|
+
"description": "Budibase self hosted API",
|
|
16
|
+
"variables": {
|
|
17
|
+
"protocol": {
|
|
18
|
+
"default": "http",
|
|
19
|
+
"description": "Whether HTTP or HTTPS should be used to communicate with your Budibase instance."
|
|
20
|
+
},
|
|
21
|
+
"hostname": {
|
|
22
|
+
"default": "localhost:10000",
|
|
23
|
+
"description": "The URL of your Budibase instance."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
}
|
|
17
27
|
],
|
|
18
28
|
"components": {
|
package/specs/openapi.yaml
CHANGED
|
@@ -4,10 +4,18 @@ info:
|
|
|
4
4
|
description: The public API for Budibase apps and its services.
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
servers:
|
|
7
|
-
- url:
|
|
7
|
+
- url: https://budibase.app/api/public/v1
|
|
8
8
|
description: Budibase Cloud API
|
|
9
|
-
- url: "{protocol}://{hostname}
|
|
9
|
+
- url: "{protocol}://{hostname}/api/public/v1"
|
|
10
10
|
description: Budibase self hosted API
|
|
11
|
+
variables:
|
|
12
|
+
protocol:
|
|
13
|
+
default: http
|
|
14
|
+
description: Whether HTTP or HTTPS should be used to communicate with your
|
|
15
|
+
Budibase instance.
|
|
16
|
+
hostname:
|
|
17
|
+
default: localhost:10000
|
|
18
|
+
description: The URL of your Budibase instance.
|
|
11
19
|
components:
|
|
12
20
|
parameters:
|
|
13
21
|
tableId:
|
|
@@ -25,7 +25,8 @@ async function makeTableRequest(
|
|
|
25
25
|
operation,
|
|
26
26
|
table,
|
|
27
27
|
tables,
|
|
28
|
-
oldTable = null
|
|
28
|
+
oldTable = null,
|
|
29
|
+
renamed = null
|
|
29
30
|
) {
|
|
30
31
|
const json = {
|
|
31
32
|
endpoint: {
|
|
@@ -41,6 +42,9 @@ async function makeTableRequest(
|
|
|
41
42
|
if (oldTable) {
|
|
42
43
|
json.meta.table = oldTable
|
|
43
44
|
}
|
|
45
|
+
if (renamed) {
|
|
46
|
+
json.meta.renamed = renamed
|
|
47
|
+
}
|
|
44
48
|
return makeExternalQuery(datasource, json)
|
|
45
49
|
}
|
|
46
50
|
|
|
@@ -160,6 +164,7 @@ function isRelationshipSetup(column) {
|
|
|
160
164
|
|
|
161
165
|
exports.save = async function (ctx) {
|
|
162
166
|
const table = ctx.request.body
|
|
167
|
+
const { _rename: renamed } = table
|
|
163
168
|
// can't do this right now
|
|
164
169
|
delete table.dataImport
|
|
165
170
|
const datasourceId = getDatasourceId(ctx.request.body)
|
|
@@ -241,7 +246,14 @@ exports.save = async function (ctx) {
|
|
|
241
246
|
const operation = oldTable
|
|
242
247
|
? DataSourceOperation.UPDATE_TABLE
|
|
243
248
|
: DataSourceOperation.CREATE_TABLE
|
|
244
|
-
await makeTableRequest(
|
|
249
|
+
await makeTableRequest(
|
|
250
|
+
datasource,
|
|
251
|
+
operation,
|
|
252
|
+
tableToSave,
|
|
253
|
+
tables,
|
|
254
|
+
oldTable,
|
|
255
|
+
renamed
|
|
256
|
+
)
|
|
245
257
|
// update any extra tables (like foreign keys in other tables)
|
|
246
258
|
for (let extraTable of extraTablesToUpdate) {
|
|
247
259
|
const oldExtraTable = oldTables[extraTable.name]
|
|
@@ -258,6 +270,8 @@ exports.save = async function (ctx) {
|
|
|
258
270
|
)
|
|
259
271
|
}
|
|
260
272
|
|
|
273
|
+
// remove the rename prop
|
|
274
|
+
delete tableToSave._rename
|
|
261
275
|
// store it into couch now for budibase reference
|
|
262
276
|
datasource.entities[tableToSave.name] = tableToSave
|
|
263
277
|
await db.put(datasource)
|
|
@@ -138,6 +138,11 @@ export interface PaginationJson {
|
|
|
138
138
|
page?: string | number
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
export interface RenameColumn {
|
|
142
|
+
old: string
|
|
143
|
+
updated: string
|
|
144
|
+
}
|
|
145
|
+
|
|
141
146
|
export interface RelationshipsJson {
|
|
142
147
|
through?: string
|
|
143
148
|
from?: string
|
|
@@ -153,6 +158,7 @@ export interface QueryJson {
|
|
|
153
158
|
datasourceId: string
|
|
154
159
|
entityId: string
|
|
155
160
|
operation: Operation
|
|
161
|
+
schema?: string
|
|
156
162
|
}
|
|
157
163
|
resource: {
|
|
158
164
|
fields: string[]
|
|
@@ -165,6 +171,7 @@ export interface QueryJson {
|
|
|
165
171
|
meta?: {
|
|
166
172
|
table?: Table
|
|
167
173
|
tables?: Record<string, Table>
|
|
174
|
+
renamed: RenameColumn
|
|
168
175
|
}
|
|
169
176
|
extra?: {
|
|
170
177
|
idFilter?: SearchFilters
|
|
@@ -249,6 +249,9 @@ class InternalBuilder {
|
|
|
249
249
|
create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
250
250
|
const { endpoint, body } = json
|
|
251
251
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
252
|
+
if (endpoint.schema) {
|
|
253
|
+
query = query.withSchema(endpoint.schema)
|
|
254
|
+
}
|
|
252
255
|
const parsedBody = parseBody(body)
|
|
253
256
|
// make sure no null values in body for creation
|
|
254
257
|
for (let [key, value] of Object.entries(parsedBody)) {
|
|
@@ -267,6 +270,9 @@ class InternalBuilder {
|
|
|
267
270
|
bulkCreate(knex: Knex, json: QueryJson): KnexQuery {
|
|
268
271
|
const { endpoint, body } = json
|
|
269
272
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
273
|
+
if (endpoint.schema) {
|
|
274
|
+
query = query.withSchema(endpoint.schema)
|
|
275
|
+
}
|
|
270
276
|
if (!Array.isArray(body)) {
|
|
271
277
|
return query
|
|
272
278
|
}
|
|
@@ -275,7 +281,7 @@ class InternalBuilder {
|
|
|
275
281
|
}
|
|
276
282
|
|
|
277
283
|
read(knex: Knex, json: QueryJson, limit: number): KnexQuery {
|
|
278
|
-
let { endpoint, resource, filters,
|
|
284
|
+
let { endpoint, resource, filters, paginate, relationships } = json
|
|
279
285
|
const tableName = endpoint.entityId
|
|
280
286
|
// select all if not specified
|
|
281
287
|
if (!resource) {
|
|
@@ -302,6 +308,9 @@ class InternalBuilder {
|
|
|
302
308
|
}
|
|
303
309
|
// start building the query
|
|
304
310
|
let query: KnexQuery = knex(tableName).limit(foundLimit)
|
|
311
|
+
if (endpoint.schema) {
|
|
312
|
+
query = query.withSchema(endpoint.schema)
|
|
313
|
+
}
|
|
305
314
|
if (foundOffset) {
|
|
306
315
|
query = query.offset(foundOffset)
|
|
307
316
|
}
|
|
@@ -331,6 +340,9 @@ class InternalBuilder {
|
|
|
331
340
|
update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
332
341
|
const { endpoint, body, filters } = json
|
|
333
342
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
343
|
+
if (endpoint.schema) {
|
|
344
|
+
query = query.withSchema(endpoint.schema)
|
|
345
|
+
}
|
|
334
346
|
const parsedBody = parseBody(body)
|
|
335
347
|
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
336
348
|
// mysql can't use returning
|
|
@@ -344,6 +356,9 @@ class InternalBuilder {
|
|
|
344
356
|
delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {
|
|
345
357
|
const { endpoint, filters } = json
|
|
346
358
|
let query: KnexQuery = knex(endpoint.entityId)
|
|
359
|
+
if (endpoint.schema) {
|
|
360
|
+
query = query.withSchema(endpoint.schema)
|
|
361
|
+
}
|
|
347
362
|
query = this.addFilters(query, filters, { tableName: endpoint.entityId })
|
|
348
363
|
// mysql can't use returning
|
|
349
364
|
if (opts.disableReturning) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Knex, knex } from "knex"
|
|
2
2
|
import { Table } from "../../definitions/common"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Operation,
|
|
5
|
+
QueryJson,
|
|
6
|
+
RenameColumn,
|
|
7
|
+
} from "../../definitions/datasource"
|
|
4
8
|
import { breakExternalTableId } from "../utils"
|
|
5
9
|
import SchemaBuilder = Knex.SchemaBuilder
|
|
6
10
|
import CreateTableBuilder = Knex.CreateTableBuilder
|
|
@@ -10,7 +14,8 @@ function generateSchema(
|
|
|
10
14
|
schema: CreateTableBuilder,
|
|
11
15
|
table: Table,
|
|
12
16
|
tables: Record<string, Table>,
|
|
13
|
-
oldTable: null | Table = null
|
|
17
|
+
oldTable: null | Table = null,
|
|
18
|
+
renamed?: RenameColumn
|
|
14
19
|
) {
|
|
15
20
|
let primaryKey = table && table.primary ? table.primary[0] : null
|
|
16
21
|
const columns = Object.values(table.schema)
|
|
@@ -29,7 +34,11 @@ function generateSchema(
|
|
|
29
34
|
for (let [key, column] of Object.entries(table.schema)) {
|
|
30
35
|
// skip things that are already correct
|
|
31
36
|
const oldColumn = oldTable ? oldTable.schema[key] : null
|
|
32
|
-
if (
|
|
37
|
+
if (
|
|
38
|
+
(oldColumn && oldColumn.type) ||
|
|
39
|
+
(primaryKey === key && !isJunction) ||
|
|
40
|
+
renamed?.updated === key
|
|
41
|
+
) {
|
|
33
42
|
continue
|
|
34
43
|
}
|
|
35
44
|
switch (column.type) {
|
|
@@ -81,6 +90,10 @@ function generateSchema(
|
|
|
81
90
|
}
|
|
82
91
|
}
|
|
83
92
|
|
|
93
|
+
if (renamed) {
|
|
94
|
+
schema.renameColumn(renamed.old, renamed.updated)
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
// need to check if any columns have been deleted
|
|
85
98
|
if (oldTable) {
|
|
86
99
|
const deletedColumns = Object.entries(oldTable.schema)
|
|
@@ -90,6 +103,9 @@ function generateSchema(
|
|
|
90
103
|
)
|
|
91
104
|
.map(([key]) => key)
|
|
92
105
|
deletedColumns.forEach(key => {
|
|
106
|
+
if (renamed?.old === key) {
|
|
107
|
+
return
|
|
108
|
+
}
|
|
93
109
|
if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {
|
|
94
110
|
schema.dropForeign(key)
|
|
95
111
|
}
|
|
@@ -101,28 +117,29 @@ function generateSchema(
|
|
|
101
117
|
}
|
|
102
118
|
|
|
103
119
|
function buildCreateTable(
|
|
104
|
-
knex:
|
|
120
|
+
knex: SchemaBuilder,
|
|
105
121
|
table: Table,
|
|
106
122
|
tables: Record<string, Table>
|
|
107
123
|
): SchemaBuilder {
|
|
108
|
-
return knex.
|
|
124
|
+
return knex.createTable(table.name, schema => {
|
|
109
125
|
generateSchema(schema, table, tables)
|
|
110
126
|
})
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
function buildUpdateTable(
|
|
114
|
-
knex:
|
|
130
|
+
knex: SchemaBuilder,
|
|
115
131
|
table: Table,
|
|
116
132
|
tables: Record<string, Table>,
|
|
117
|
-
oldTable: Table
|
|
133
|
+
oldTable: Table,
|
|
134
|
+
renamed: RenameColumn
|
|
118
135
|
): SchemaBuilder {
|
|
119
|
-
return knex.
|
|
120
|
-
generateSchema(schema, table, tables, oldTable)
|
|
136
|
+
return knex.alterTable(table.name, schema => {
|
|
137
|
+
generateSchema(schema, table, tables, oldTable, renamed)
|
|
121
138
|
})
|
|
122
139
|
}
|
|
123
140
|
|
|
124
|
-
function buildDeleteTable(knex:
|
|
125
|
-
return knex.
|
|
141
|
+
function buildDeleteTable(knex: SchemaBuilder, table: Table): SchemaBuilder {
|
|
142
|
+
return knex.dropTable(table.name)
|
|
126
143
|
}
|
|
127
144
|
|
|
128
145
|
class SqlTableQueryBuilder {
|
|
@@ -146,7 +163,11 @@ class SqlTableQueryBuilder {
|
|
|
146
163
|
}
|
|
147
164
|
|
|
148
165
|
_tableQuery(json: QueryJson): any {
|
|
149
|
-
|
|
166
|
+
let client = knex({ client: this.sqlClient }).schema
|
|
167
|
+
if (json?.endpoint?.schema) {
|
|
168
|
+
client = client.withSchema(json.endpoint.schema)
|
|
169
|
+
}
|
|
170
|
+
|
|
150
171
|
let query
|
|
151
172
|
if (!json.table || !json.meta || !json.meta.tables) {
|
|
152
173
|
throw "Cannot execute without table being specified"
|
|
@@ -163,7 +184,8 @@ class SqlTableQueryBuilder {
|
|
|
163
184
|
client,
|
|
164
185
|
json.table,
|
|
165
186
|
json.meta.tables,
|
|
166
|
-
json.meta.table
|
|
187
|
+
json.meta.table,
|
|
188
|
+
json.meta.renamed
|
|
167
189
|
)
|
|
168
190
|
break
|
|
169
191
|
case Operation.DELETE_TABLE:
|
|
@@ -19,6 +19,7 @@ import { Table, TableSchema } from "../definitions/common"
|
|
|
19
19
|
module MSSQLModule {
|
|
20
20
|
const sqlServer = require("mssql")
|
|
21
21
|
const Sql = require("./base/sql")
|
|
22
|
+
const DEFAULT_SCHEMA = "dbo"
|
|
22
23
|
|
|
23
24
|
interface MSSQLConfig {
|
|
24
25
|
user: string
|
|
@@ -26,9 +27,17 @@ module MSSQLModule {
|
|
|
26
27
|
server: string
|
|
27
28
|
port: number
|
|
28
29
|
database: string
|
|
30
|
+
schema: string
|
|
29
31
|
encrypt?: boolean
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
interface TablesResponse {
|
|
35
|
+
TABLE_CATALOG: string
|
|
36
|
+
TABLE_SCHEMA: string
|
|
37
|
+
TABLE_NAME: string
|
|
38
|
+
TABLE_TYPE: string
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
const SCHEMA: Integration = {
|
|
33
42
|
docs: "https://github.com/tediousjs/node-mssql",
|
|
34
43
|
plus: true,
|
|
@@ -58,6 +67,10 @@ module MSSQLModule {
|
|
|
58
67
|
type: DatasourceFieldTypes.STRING,
|
|
59
68
|
default: "root",
|
|
60
69
|
},
|
|
70
|
+
schema: {
|
|
71
|
+
type: DatasourceFieldTypes.STRING,
|
|
72
|
+
default: DEFAULT_SCHEMA,
|
|
73
|
+
},
|
|
61
74
|
encrypt: {
|
|
62
75
|
type: DatasourceFieldTypes.BOOLEAN,
|
|
63
76
|
default: true,
|
|
@@ -96,6 +109,35 @@ module MSSQLModule {
|
|
|
96
109
|
TABLES_SQL =
|
|
97
110
|
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"
|
|
98
111
|
|
|
112
|
+
constructor(config: MSSQLConfig) {
|
|
113
|
+
super(SqlClients.MS_SQL)
|
|
114
|
+
this.config = config
|
|
115
|
+
const clientCfg = {
|
|
116
|
+
...this.config,
|
|
117
|
+
options: {
|
|
118
|
+
encrypt: this.config.encrypt,
|
|
119
|
+
enableArithAbort: true,
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
delete clientCfg.encrypt
|
|
123
|
+
if (!this.pool) {
|
|
124
|
+
this.pool = new sqlServer.ConnectionPool(clientCfg)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getBindingIdentifier(): string {
|
|
129
|
+
return `(@p${this.index++})`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async connect() {
|
|
133
|
+
try {
|
|
134
|
+
this.client = await this.pool.connect()
|
|
135
|
+
} catch (err) {
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
throw new Error(err)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
99
141
|
async internalQuery(
|
|
100
142
|
query: SqlQuery,
|
|
101
143
|
operation: string | undefined = undefined
|
|
@@ -151,35 +193,6 @@ module MSSQLModule {
|
|
|
151
193
|
WHERE TABLE_NAME='${tableName}'`
|
|
152
194
|
}
|
|
153
195
|
|
|
154
|
-
constructor(config: MSSQLConfig) {
|
|
155
|
-
super(SqlClients.MS_SQL)
|
|
156
|
-
this.config = config
|
|
157
|
-
const clientCfg = {
|
|
158
|
-
...this.config,
|
|
159
|
-
options: {
|
|
160
|
-
encrypt: this.config.encrypt,
|
|
161
|
-
enableArithAbort: true,
|
|
162
|
-
},
|
|
163
|
-
}
|
|
164
|
-
delete clientCfg.encrypt
|
|
165
|
-
if (!this.pool) {
|
|
166
|
-
this.pool = new sqlServer.ConnectionPool(clientCfg)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
getBindingIdentifier(): string {
|
|
171
|
-
return `(@p${this.index++})`
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async connect() {
|
|
175
|
-
try {
|
|
176
|
-
this.client = await this.pool.connect()
|
|
177
|
-
} catch (err) {
|
|
178
|
-
// @ts-ignore
|
|
179
|
-
throw new Error(err)
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
196
|
async runSQL(sql: string) {
|
|
184
197
|
return (await this.internalQuery(getSqlQuery(sql))).recordset
|
|
185
198
|
}
|
|
@@ -191,11 +204,14 @@ module MSSQLModule {
|
|
|
191
204
|
*/
|
|
192
205
|
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
|
|
193
206
|
await this.connect()
|
|
194
|
-
let
|
|
195
|
-
if (
|
|
207
|
+
let tableInfo: TablesResponse[] = await this.runSQL(this.TABLES_SQL)
|
|
208
|
+
if (tableInfo == null || !Array.isArray(tableInfo)) {
|
|
196
209
|
throw "Unable to get list of tables in database"
|
|
197
210
|
}
|
|
198
|
-
|
|
211
|
+
|
|
212
|
+
const schema = this.config.schema || DEFAULT_SCHEMA
|
|
213
|
+
const tableNames = tableInfo
|
|
214
|
+
.filter((record: any) => record.TABLE_SCHEMA === schema)
|
|
199
215
|
.map((record: any) => record.TABLE_NAME)
|
|
200
216
|
.filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)
|
|
201
217
|
|
|
@@ -267,7 +283,11 @@ module MSSQLModule {
|
|
|
267
283
|
}
|
|
268
284
|
|
|
269
285
|
async query(json: QueryJson) {
|
|
286
|
+
const schema = this.config.schema
|
|
270
287
|
await this.connect()
|
|
288
|
+
if (schema && schema !== DEFAULT_SCHEMA && json?.endpoint) {
|
|
289
|
+
json.endpoint.schema = schema
|
|
290
|
+
}
|
|
271
291
|
const operation = this._operation(json)
|
|
272
292
|
const queryFn = (query: any, op: string) => this.internalQuery(query, op)
|
|
273
293
|
const processFn = (result: any) =>
|
|
@@ -6,35 +6,63 @@ import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants"
|
|
|
6
6
|
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
|
7
7
|
const ROW_ID_REGEX = /^\[.*]$/g
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
text: FieldTypes.LONGFORM,
|
|
11
|
-
varchar: FieldTypes.STRING,
|
|
9
|
+
const SQL_NUMBER_TYPE_MAP = {
|
|
12
10
|
integer: FieldTypes.NUMBER,
|
|
11
|
+
int: FieldTypes.NUMBER,
|
|
13
12
|
bigint: FieldTypes.NUMBER,
|
|
14
13
|
decimal: FieldTypes.NUMBER,
|
|
15
14
|
smallint: FieldTypes.NUMBER,
|
|
16
15
|
real: FieldTypes.NUMBER,
|
|
17
|
-
"double precision": FieldTypes.NUMBER,
|
|
18
|
-
timestamp: FieldTypes.DATETIME,
|
|
19
|
-
time: FieldTypes.DATETIME,
|
|
20
|
-
boolean: FieldTypes.BOOLEAN,
|
|
21
|
-
json: FieldTypes.JSON,
|
|
22
|
-
date: FieldTypes.DATETIME,
|
|
23
|
-
blob: FieldTypes.LONGFORM,
|
|
24
|
-
enum: FieldTypes.STRING,
|
|
25
16
|
float: FieldTypes.NUMBER,
|
|
26
|
-
int: FieldTypes.NUMBER,
|
|
27
17
|
numeric: FieldTypes.NUMBER,
|
|
28
18
|
mediumint: FieldTypes.NUMBER,
|
|
29
19
|
dec: FieldTypes.NUMBER,
|
|
30
20
|
double: FieldTypes.NUMBER,
|
|
31
21
|
fixed: FieldTypes.NUMBER,
|
|
32
|
-
|
|
33
|
-
tinyint: FieldTypes.BOOLEAN,
|
|
34
|
-
long: FieldTypes.LONGFORM,
|
|
22
|
+
"double precision": FieldTypes.NUMBER,
|
|
35
23
|
number: FieldTypes.NUMBER,
|
|
36
24
|
binary_float: FieldTypes.NUMBER,
|
|
37
25
|
binary_double: FieldTypes.NUMBER,
|
|
26
|
+
money: FieldTypes.NUMBER,
|
|
27
|
+
smallmoney: FieldTypes.NUMBER,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const SQL_DATE_TYPE_MAP = {
|
|
31
|
+
timestamp: FieldTypes.DATETIME,
|
|
32
|
+
time: FieldTypes.DATETIME,
|
|
33
|
+
datetime: FieldTypes.DATETIME,
|
|
34
|
+
smalldatetime: FieldTypes.DATETIME,
|
|
35
|
+
date: FieldTypes.DATETIME,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const SQL_STRING_TYPE_MAP = {
|
|
39
|
+
varchar: FieldTypes.STRING,
|
|
40
|
+
char: FieldTypes.STRING,
|
|
41
|
+
nchar: FieldTypes.STRING,
|
|
42
|
+
nvarchar: FieldTypes.STRING,
|
|
43
|
+
ntext: FieldTypes.STRING,
|
|
44
|
+
enum: FieldTypes.STRING,
|
|
45
|
+
blob: FieldTypes.LONGFORM,
|
|
46
|
+
long: FieldTypes.LONGFORM,
|
|
47
|
+
text: FieldTypes.LONGFORM,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const SQL_BOOLEAN_TYPE_MAP = {
|
|
51
|
+
boolean: FieldTypes.BOOLEAN,
|
|
52
|
+
bit: FieldTypes.BOOLEAN,
|
|
53
|
+
tinyint: FieldTypes.BOOLEAN,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const SQL_MISC_TYPE_MAP = {
|
|
57
|
+
json: FieldTypes.JSON,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const SQL_TYPE_MAP = {
|
|
61
|
+
...SQL_NUMBER_TYPE_MAP,
|
|
62
|
+
...SQL_DATE_TYPE_MAP,
|
|
63
|
+
...SQL_STRING_TYPE_MAP,
|
|
64
|
+
...SQL_BOOLEAN_TYPE_MAP,
|
|
65
|
+
...SQL_MISC_TYPE_MAP,
|
|
38
66
|
}
|
|
39
67
|
|
|
40
68
|
export enum SqlClients {
|