@budibase/server 0.9.185-alpha.2 → 0.9.185-alpha.20
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 +7 -1
- package/__mocks__/oracledb.ts +31 -0
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.7d405e74.css +1 -0
- package/builder/assets/index.83e08172.js +1316 -0
- package/builder/assets/oracle.66592424.png +0 -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 +785 -687
- package/coverage/coverage-final.json +90 -88
- 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 +43 -13
- package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
- 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 +129 -21
- 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 +77 -77
- 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 +48 -210
- 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 +2 -2
- package/coverage/lcov-report/api/controllers/row/index.html +10 -10
- 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 +2 -2
- 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 +29 -8
- package/coverage/lcov-report/api/controllers/table/index.html +20 -20
- package/coverage/lcov-report/api/controllers/table/index.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/internal.js.html +2 -2
- package/coverage/lcov-report/api/controllers/table/utils.js.html +8 -8
- package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
- package/coverage/lcov-report/api/controllers/user.js.html +2 -2
- 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 +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 +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 +44 -23
- 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 +3 -3
- package/coverage/lcov-report/db/utils.js.html +57 -57
- 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 +86 -71
- 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 +4 -4
- 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 +21 -21
- 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} +90 -33
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +278 -0
- package/coverage/lcov-report/threads/query.js.html +278 -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 +2 -2
- package/coverage/lcov-report/utilities/global.js.html +2 -2
- package/coverage/lcov-report/utilities/index.html +21 -21
- package/coverage/lcov-report/utilities/index.js.html +12 -9
- 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 +1247 -1070
- package/dist/api/controllers/application.js +11 -1
- package/dist/api/controllers/datasource.js +31 -7
- package/dist/api/controllers/deploy/index.js +2 -0
- package/dist/api/controllers/dev.js +4 -1
- package/dist/api/controllers/query.js +27 -57
- package/dist/api/controllers/table/external.js +8 -1
- package/dist/api/routes/query.js +1 -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 +6 -0
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +13 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/sql.js +40 -8
- package/dist/integrations/index.js +6 -0
- package/dist/integrations/mysql.js +3 -1
- package/dist/integrations/oracle.js +345 -0
- package/dist/integrations/utils.js +17 -2
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +11 -6
- package/dist/{automations/thread.js → threads/automation.js} +26 -8
- package/dist/threads/index.js +64 -0
- package/dist/threads/query.js +64 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +12 -7
- package/scripts/dev/manage.js +1 -0
- package/scripts/integrations/oracle/docker-compose.yml +19 -0
- package/scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip +0 -0
- package/scripts/integrations/oracle/instantclient/linux/x86-64/install.sh +23 -0
- package/scripts/integrations/oracle/oracle.md +90 -0
- package/scripts/integrations/postgres/docker-compose.yml +3 -3
- package/scripts/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +11 -1
- package/src/api/controllers/datasource.js +45 -9
- package/src/api/controllers/deploy/index.js +2 -0
- package/src/api/controllers/dev.js +4 -1
- package/src/api/controllers/query.js +26 -80
- package/src/api/controllers/table/external.js +8 -1
- package/src/api/routes/query.js +1 -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 +7 -0
- package/src/definitions/datasource.ts +1 -0
- package/src/environment.js +15 -0
- 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 +2 -1
- package/src/integrations/base/sql.ts +41 -9
- package/src/integrations/couchdb.ts +2 -1
- package/src/integrations/dynamodb.ts +2 -1
- package/src/integrations/elasticsearch.ts +2 -1
- package/src/integrations/index.ts +7 -0
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +1 -1
- package/src/integrations/oracle.ts +445 -0
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +2 -1
- package/src/integrations/tests/oracle.spec.js +94 -0
- package/src/integrations/utils.ts +16 -2
- package/src/middleware/builder.js +4 -1
- package/src/{automations/thread.js → threads/automation.js} +27 -8
- package/src/threads/index.js +66 -0
- package/src/threads/query.js +66 -0
- package/src/utilities/index.js +1 -0
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/scriptRunner.js +4 -1
- package/tsconfig.json +1 -1
- package/builder/assets/index.0eadd2f5.js +0 -201
- package/builder/assets/index.a79ec0ef.css +0 -29
- package/builder/assets/vendor.278a305c.js +0 -9
- package/builder/assets/vendor.d75d5eb7.css +0 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const datasource_1 = require("../definitions/datasource");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
const oracledb_1 = __importDefault(require("oracledb"));
|
|
18
|
+
const sql_1 = __importDefault(require("./base/sql"));
|
|
19
|
+
const constants_1 = require("../constants");
|
|
20
|
+
var OracleModule;
|
|
21
|
+
(function (OracleModule) {
|
|
22
|
+
oracledb_1.default.outFormat = oracledb_1.default.OUT_FORMAT_OBJECT;
|
|
23
|
+
const SCHEMA = {
|
|
24
|
+
docs: "https://github.com/oracle/node-oracledb",
|
|
25
|
+
plus: true,
|
|
26
|
+
friendlyName: "Oracle",
|
|
27
|
+
description: "Oracle Database is an object-relational database management system developed by Oracle Corporation",
|
|
28
|
+
datasource: {
|
|
29
|
+
host: {
|
|
30
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
31
|
+
default: "localhost",
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
port: {
|
|
35
|
+
type: datasource_1.DatasourceFieldTypes.NUMBER,
|
|
36
|
+
required: true,
|
|
37
|
+
default: 1521,
|
|
38
|
+
},
|
|
39
|
+
database: {
|
|
40
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
41
|
+
required: true,
|
|
42
|
+
},
|
|
43
|
+
user: {
|
|
44
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
45
|
+
required: true,
|
|
46
|
+
},
|
|
47
|
+
password: {
|
|
48
|
+
type: datasource_1.DatasourceFieldTypes.PASSWORD,
|
|
49
|
+
required: true,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
query: {
|
|
53
|
+
create: {
|
|
54
|
+
type: datasource_1.QueryTypes.SQL,
|
|
55
|
+
},
|
|
56
|
+
read: {
|
|
57
|
+
type: datasource_1.QueryTypes.SQL,
|
|
58
|
+
},
|
|
59
|
+
update: {
|
|
60
|
+
type: datasource_1.QueryTypes.SQL,
|
|
61
|
+
},
|
|
62
|
+
delete: {
|
|
63
|
+
type: datasource_1.QueryTypes.SQL,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
const UNSUPPORTED_TYPES = ["BLOB", "CLOB", "NCLOB"];
|
|
68
|
+
const OracleContraintTypes = {
|
|
69
|
+
PRIMARY: "P",
|
|
70
|
+
NOT_NULL_OR_CHECK: "C",
|
|
71
|
+
FOREIGN_KEY: "R",
|
|
72
|
+
UNIQUE: "U",
|
|
73
|
+
};
|
|
74
|
+
class OracleIntegration extends sql_1.default {
|
|
75
|
+
constructor(config) {
|
|
76
|
+
super(utils_1.SqlClients.ORACLE);
|
|
77
|
+
this.tables = {};
|
|
78
|
+
this.schemaErrors = {};
|
|
79
|
+
this.COLUMNS_SQL = `
|
|
80
|
+
SELECT
|
|
81
|
+
tabs.table_name,
|
|
82
|
+
cols.column_name,
|
|
83
|
+
cols.data_type,
|
|
84
|
+
cols.data_default,
|
|
85
|
+
cols.column_id,
|
|
86
|
+
cons.constraint_name,
|
|
87
|
+
cons.constraint_type,
|
|
88
|
+
cons.r_constraint_name,
|
|
89
|
+
cons.search_condition
|
|
90
|
+
FROM
|
|
91
|
+
user_tables tabs
|
|
92
|
+
JOIN
|
|
93
|
+
user_tab_columns cols
|
|
94
|
+
ON tabs.table_name = cols.table_name
|
|
95
|
+
LEFT JOIN
|
|
96
|
+
user_cons_columns col_cons
|
|
97
|
+
ON cols.column_name = col_cons.column_name
|
|
98
|
+
AND cols.table_name = col_cons.table_name
|
|
99
|
+
LEFT JOIN
|
|
100
|
+
user_constraints cons
|
|
101
|
+
ON col_cons.constraint_name = cons.constraint_name
|
|
102
|
+
AND cons.table_name = cols.table_name
|
|
103
|
+
WHERE
|
|
104
|
+
(cons.status = 'ENABLED'
|
|
105
|
+
OR cons.status IS NULL)
|
|
106
|
+
`;
|
|
107
|
+
this.getConnection = () => __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
//connectString : "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))(CONNECT_DATA =(SID= ORCL)))"
|
|
109
|
+
const connectString = `${this.config.host}:${this.config.port || 1521}/${this.config.database}`;
|
|
110
|
+
const attributes = {
|
|
111
|
+
user: this.config.user,
|
|
112
|
+
password: this.config.user,
|
|
113
|
+
connectString,
|
|
114
|
+
};
|
|
115
|
+
return oracledb_1.default.getConnection(attributes);
|
|
116
|
+
});
|
|
117
|
+
this.config = config;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Map the flat tabular columns and constraints data into a nested object
|
|
121
|
+
*/
|
|
122
|
+
mapColumns(result) {
|
|
123
|
+
const oracleTables = {};
|
|
124
|
+
if (result.rows) {
|
|
125
|
+
result.rows.forEach(row => {
|
|
126
|
+
const tableName = row.TABLE_NAME;
|
|
127
|
+
const columnName = row.COLUMN_NAME;
|
|
128
|
+
const dataType = row.DATA_TYPE;
|
|
129
|
+
const dataDefault = row.DATA_DEFAULT;
|
|
130
|
+
const columnId = row.COLUMN_ID;
|
|
131
|
+
const constraintName = row.CONSTRAINT_NAME;
|
|
132
|
+
const constraintType = row.CONSTRAINT_TYPE;
|
|
133
|
+
const relatedConstraintName = row.R_CONSTRAINT_NAME;
|
|
134
|
+
const searchCondition = row.SEARCH_CONDITION;
|
|
135
|
+
let table = oracleTables[tableName];
|
|
136
|
+
if (!table) {
|
|
137
|
+
table = {
|
|
138
|
+
name: tableName,
|
|
139
|
+
columns: {},
|
|
140
|
+
};
|
|
141
|
+
oracleTables[tableName] = table;
|
|
142
|
+
}
|
|
143
|
+
let column = table.columns[columnName];
|
|
144
|
+
if (!column) {
|
|
145
|
+
column = {
|
|
146
|
+
name: columnName,
|
|
147
|
+
type: dataType,
|
|
148
|
+
default: dataDefault,
|
|
149
|
+
id: columnId,
|
|
150
|
+
constraints: {},
|
|
151
|
+
};
|
|
152
|
+
table.columns[columnName] = column;
|
|
153
|
+
}
|
|
154
|
+
if (constraintName && constraintType) {
|
|
155
|
+
let constraint = column.constraints[constraintName];
|
|
156
|
+
if (!constraint) {
|
|
157
|
+
constraint = {
|
|
158
|
+
name: constraintName,
|
|
159
|
+
type: constraintType,
|
|
160
|
+
relatedConstraintName: relatedConstraintName,
|
|
161
|
+
searchCondition: searchCondition,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
column.constraints[constraintName] = constraint;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return oracleTables;
|
|
169
|
+
}
|
|
170
|
+
isSupportedColumn(column) {
|
|
171
|
+
if (UNSUPPORTED_TYPES.includes(column.type)) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
isAutoColumn(column) {
|
|
177
|
+
if (column.default && column.default.toLowerCase().includes("nextval")) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* No native boolean in oracle. Best we can do is to check if a manual 1 or 0 number constraint has been set up
|
|
184
|
+
* This matches the default behaviour for generating DDL used in knex.
|
|
185
|
+
*/
|
|
186
|
+
isBooleanType(column) {
|
|
187
|
+
if (column.type.toLowerCase() === "number" &&
|
|
188
|
+
Object.values(column.constraints).filter(c => {
|
|
189
|
+
if (c.type === OracleContraintTypes.NOT_NULL_OR_CHECK &&
|
|
190
|
+
c.searchCondition) {
|
|
191
|
+
const condition = c.searchCondition
|
|
192
|
+
.replace(/\s/g, "") // remove spaces
|
|
193
|
+
.replace(/[']+/g, ""); // remove quotes
|
|
194
|
+
if (condition.includes("in(0,1)") ||
|
|
195
|
+
condition.includes("in(1,0)")) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
200
|
+
}).length > 0) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
internalConvertType(column) {
|
|
206
|
+
if (this.isBooleanType(column)) {
|
|
207
|
+
return constants_1.FieldTypes.BOOLEAN;
|
|
208
|
+
}
|
|
209
|
+
return utils_1.convertSqlType(column.type);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Fetches the tables from the oracle table and assigns them to the datasource.
|
|
213
|
+
* @param {*} datasourceId - datasourceId to fetch
|
|
214
|
+
* @param entities - the tables that are to be built
|
|
215
|
+
*/
|
|
216
|
+
buildSchema(datasourceId, entities) {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
const columnsResponse = yield this.internalQuery({
|
|
219
|
+
sql: this.COLUMNS_SQL,
|
|
220
|
+
});
|
|
221
|
+
const oracleTables = this.mapColumns(columnsResponse);
|
|
222
|
+
const tables = {};
|
|
223
|
+
// iterate each table
|
|
224
|
+
Object.values(oracleTables).forEach(oracleTable => {
|
|
225
|
+
let table = tables[oracleTable.name];
|
|
226
|
+
if (!table) {
|
|
227
|
+
table = {
|
|
228
|
+
_id: utils_1.buildExternalTableId(datasourceId, oracleTable.name),
|
|
229
|
+
primary: [],
|
|
230
|
+
name: oracleTable.name,
|
|
231
|
+
schema: {},
|
|
232
|
+
};
|
|
233
|
+
tables[oracleTable.name] = table;
|
|
234
|
+
}
|
|
235
|
+
// iterate each column on the table
|
|
236
|
+
Object.values(oracleTable.columns)
|
|
237
|
+
// remove columns that we can't read / save
|
|
238
|
+
.filter(oracleColumn => this.isSupportedColumn(oracleColumn))
|
|
239
|
+
// match the order of the columns in the db
|
|
240
|
+
.sort((c1, c2) => c1.id - c2.id)
|
|
241
|
+
.forEach(oracleColumn => {
|
|
242
|
+
const columnName = oracleColumn.name;
|
|
243
|
+
let fieldSchema = table.schema[columnName];
|
|
244
|
+
if (!fieldSchema) {
|
|
245
|
+
fieldSchema = {
|
|
246
|
+
autocolumn: this.isAutoColumn(oracleColumn),
|
|
247
|
+
name: columnName,
|
|
248
|
+
type: this.internalConvertType(oracleColumn),
|
|
249
|
+
};
|
|
250
|
+
table.schema[columnName] = fieldSchema;
|
|
251
|
+
}
|
|
252
|
+
// iterate each constraint on the column
|
|
253
|
+
Object.values(oracleColumn.constraints).forEach(oracleConstraint => {
|
|
254
|
+
if (oracleConstraint.type === OracleContraintTypes.PRIMARY) {
|
|
255
|
+
table.primary.push(columnName);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
const final = utils_1.finaliseExternalTables(tables, entities);
|
|
261
|
+
this.tables = final.tables;
|
|
262
|
+
this.schemaErrors = final.errors;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Knex default returning behaviour does not work with oracle
|
|
267
|
+
* Manually add the behaviour for the return column
|
|
268
|
+
*/
|
|
269
|
+
addReturning(query, bindings, returnColumn) {
|
|
270
|
+
if (bindings instanceof Array) {
|
|
271
|
+
bindings.push({ dir: oracledb_1.default.BIND_OUT });
|
|
272
|
+
query.sql = query.sql + ` returning \"${returnColumn}\" into :${bindings.length}`;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
internalQuery(query, returnColum, operation) {
|
|
276
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
+
let connection;
|
|
278
|
+
try {
|
|
279
|
+
connection = yield this.getConnection();
|
|
280
|
+
const options = { autoCommit: true };
|
|
281
|
+
const bindings = query.bindings || [];
|
|
282
|
+
if (returnColum && (operation === datasource_1.Operation.CREATE || operation === datasource_1.Operation.UPDATE)) {
|
|
283
|
+
this.addReturning(query, bindings, returnColum);
|
|
284
|
+
}
|
|
285
|
+
const result = yield connection.execute(query.sql, bindings, options);
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
288
|
+
finally {
|
|
289
|
+
if (connection) {
|
|
290
|
+
try {
|
|
291
|
+
yield connection.close();
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
console.error(err);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
create(query) {
|
|
301
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
const response = yield this.internalQuery(utils_1.getSqlQuery(query));
|
|
303
|
+
return response.rows && response.rows.length
|
|
304
|
+
? response.rows
|
|
305
|
+
: [{ created: true }];
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
read(query) {
|
|
309
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
310
|
+
const response = yield this.internalQuery(utils_1.getSqlQuery(query));
|
|
311
|
+
return response.rows ? response.rows : [];
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
update(query) {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
const response = yield this.internalQuery(utils_1.getSqlQuery(query));
|
|
317
|
+
return response.rows && response.rows.length
|
|
318
|
+
? response.rows
|
|
319
|
+
: [{ updated: true }];
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
delete(query) {
|
|
323
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
324
|
+
const response = yield this.internalQuery(utils_1.getSqlQuery(query));
|
|
325
|
+
return response.rows && response.rows.length
|
|
326
|
+
? response.rows
|
|
327
|
+
: [{ deleted: true }];
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
query(json) {
|
|
331
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
332
|
+
const primaryKeys = json.meta.table.primary;
|
|
333
|
+
const primaryKey = primaryKeys ? primaryKeys[0] : undefined;
|
|
334
|
+
const queryFn = (query, operation) => this.internalQuery(query, primaryKey, operation);
|
|
335
|
+
const processFn = (response) => response.rows ? response.rows : [];
|
|
336
|
+
const output = yield this.queryWithReturning(json, queryFn, processFn);
|
|
337
|
+
return output;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
module.exports = {
|
|
342
|
+
schema: SCHEMA,
|
|
343
|
+
integration: OracleIntegration,
|
|
344
|
+
};
|
|
345
|
+
})(OracleModule || (OracleModule = {}));
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.finaliseExternalTables = exports.isIsoDateString = exports.isSQL = exports.getSqlQuery = exports.convertSqlType = exports.breakRowIdField = exports.convertRowId = exports.isRowId = exports.generateRowIdField = exports.breakExternalTableId = exports.buildExternalTableId = exports.isExternalTable = exports.SqlClients = void 0;
|
|
4
4
|
const datasource_1 = require("../definitions/datasource");
|
|
5
5
|
const { DocumentTypes, SEPARATOR } = require("../db/utils");
|
|
6
|
-
const { FieldTypes, BuildSchemaErrors } = require("../constants");
|
|
6
|
+
const { FieldTypes, BuildSchemaErrors, InvalidColumns } = require("../constants");
|
|
7
7
|
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`;
|
|
8
8
|
const ROW_ID_REGEX = /^\[.*]$/g;
|
|
9
9
|
const SQL_TYPE_MAP = {
|
|
@@ -31,12 +31,17 @@ const SQL_TYPE_MAP = {
|
|
|
31
31
|
fixed: FieldTypes.NUMBER,
|
|
32
32
|
datetime: FieldTypes.DATETIME,
|
|
33
33
|
tinyint: FieldTypes.BOOLEAN,
|
|
34
|
+
long: FieldTypes.LONGFORM,
|
|
35
|
+
number: FieldTypes.NUMBER,
|
|
36
|
+
binary_float: FieldTypes.NUMBER,
|
|
37
|
+
binary_double: FieldTypes.NUMBER,
|
|
34
38
|
};
|
|
35
39
|
var SqlClients;
|
|
36
40
|
(function (SqlClients) {
|
|
37
41
|
SqlClients["MS_SQL"] = "mssql";
|
|
38
42
|
SqlClients["POSTGRES"] = "pg";
|
|
39
43
|
SqlClients["MY_SQL"] = "mysql";
|
|
44
|
+
SqlClients["ORACLE"] = "oracledb";
|
|
40
45
|
})(SqlClients = exports.SqlClients || (exports.SqlClients = {}));
|
|
41
46
|
function isExternalTable(tableId) {
|
|
42
47
|
return tableId.includes(DocumentTypes.DATASOURCE);
|
|
@@ -151,17 +156,27 @@ function copyExistingPropsOver(tableName, table, entities) {
|
|
|
151
156
|
return table;
|
|
152
157
|
}
|
|
153
158
|
function finaliseExternalTables(tables, entities) {
|
|
154
|
-
const
|
|
159
|
+
const invalidColumns = Object.values(InvalidColumns);
|
|
160
|
+
let finalTables = {};
|
|
155
161
|
const errors = {};
|
|
156
162
|
for (let [name, table] of Object.entries(tables)) {
|
|
163
|
+
const schemaFields = Object.keys(table.schema);
|
|
157
164
|
// make sure every table has a key
|
|
158
165
|
if (table.primary == null || table.primary.length === 0) {
|
|
159
166
|
errors[name] = BuildSchemaErrors.NO_KEY;
|
|
160
167
|
continue;
|
|
161
168
|
}
|
|
169
|
+
else if (schemaFields.find(field => invalidColumns.includes(field))) {
|
|
170
|
+
errors[name] = BuildSchemaErrors.INVALID_COLUMN;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
162
173
|
// make sure all previous props have been added back
|
|
163
174
|
finalTables[name] = copyExistingPropsOver(name, table, entities);
|
|
164
175
|
}
|
|
176
|
+
// sort the tables by name
|
|
177
|
+
finalTables = Object.entries(finalTables)
|
|
178
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
179
|
+
.reduce((r, [k, v]) => (Object.assign(Object.assign({}, r), { [k]: v })), {});
|
|
165
180
|
return { tables: finalTables, errors };
|
|
166
181
|
}
|
|
167
182
|
exports.finaliseExternalTables = finaliseExternalTables;
|
|
@@ -13,6 +13,7 @@ const { doesUserHaveLock, updateLock, checkDebounce, setDebounce, } = require(".
|
|
|
13
13
|
const CouchDB = require("../db");
|
|
14
14
|
const { DocumentTypes } = require("../db/utils");
|
|
15
15
|
const { PermissionTypes } = require("@budibase/auth/permissions");
|
|
16
|
+
const { app: appCache } = require("@budibase/auth/cache");
|
|
16
17
|
const DEBOUNCE_TIME_SEC = 30;
|
|
17
18
|
/************************************************** *
|
|
18
19
|
* This middleware has been broken out of the *
|
|
@@ -51,7 +52,9 @@ function updateAppUpdatedAt(ctx) {
|
|
|
51
52
|
const db = new CouchDB(appId);
|
|
52
53
|
const metadata = yield db.get(DocumentTypes.APP_METADATA);
|
|
53
54
|
metadata.updatedAt = new Date().toISOString();
|
|
54
|
-
yield db.put(metadata);
|
|
55
|
+
const response = yield db.put(metadata);
|
|
56
|
+
metadata._rev = response.rev;
|
|
57
|
+
yield appCache.invalidateAppMetadata(appId, metadata);
|
|
55
58
|
// set a new debounce record with a short TTL
|
|
56
59
|
yield setDebounce(appId, DEBOUNCE_TIME_SEC);
|
|
57
60
|
});
|
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "0.9.185-alpha.
|
|
4
|
+
"version": "0.9.185-alpha.19",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -68,9 +68,11 @@
|
|
|
68
68
|
"author": "Budibase",
|
|
69
69
|
"license": "AGPL-3.0-or-later",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@budibase/auth": "^0.9.185-alpha.
|
|
72
|
-
"@budibase/client": "^0.9.185-alpha.
|
|
73
|
-
"@budibase/string-templates": "^0.9.185-alpha.
|
|
71
|
+
"@budibase/auth": "^0.9.185-alpha.19",
|
|
72
|
+
"@budibase/client": "^0.9.185-alpha.19",
|
|
73
|
+
"@budibase/string-templates": "^0.9.185-alpha.19",
|
|
74
|
+
"@bull-board/api": "^3.7.0",
|
|
75
|
+
"@bull-board/koa": "^3.7.0",
|
|
74
76
|
"@elastic/elasticsearch": "7.10.0",
|
|
75
77
|
"@koa/router": "8.0.0",
|
|
76
78
|
"@sendgrid/mail": "7.1.1",
|
|
@@ -80,7 +82,6 @@
|
|
|
80
82
|
"aws-sdk": "^2.767.0",
|
|
81
83
|
"bcryptjs": "2.4.3",
|
|
82
84
|
"bull": "^3.22.4",
|
|
83
|
-
"bull-board": "^2.0.1",
|
|
84
85
|
"chmodr": "1.2.0",
|
|
85
86
|
"csvtojson": "2.0.10",
|
|
86
87
|
"dotenv": "8.2.0",
|
|
@@ -120,6 +121,7 @@
|
|
|
120
121
|
"uuid": "3.3.2",
|
|
121
122
|
"validate.js": "0.13.1",
|
|
122
123
|
"vm2": "^3.9.3",
|
|
124
|
+
"worker-farm": "^1.7.0",
|
|
123
125
|
"yargs": "13.2.4",
|
|
124
126
|
"zlib": "1.0.5"
|
|
125
127
|
},
|
|
@@ -133,12 +135,12 @@
|
|
|
133
135
|
"@types/koa": "^2.13.3",
|
|
134
136
|
"@types/koa-router": "^7.4.2",
|
|
135
137
|
"@types/node": "^15.12.4",
|
|
138
|
+
"@types/oracledb": "^5.2.1",
|
|
136
139
|
"@typescript-eslint/parser": "4.28.0",
|
|
137
140
|
"babel-jest": "^27.0.2",
|
|
138
141
|
"copyfiles": "^2.4.1",
|
|
139
142
|
"docker-compose": "^0.23.6",
|
|
140
143
|
"eslint": "^6.8.0",
|
|
141
|
-
"express": "^4.17.1",
|
|
142
144
|
"jest": "^27.0.5",
|
|
143
145
|
"nodemon": "^2.0.4",
|
|
144
146
|
"prettier": "^2.3.1",
|
|
@@ -149,5 +151,8 @@
|
|
|
149
151
|
"typescript": "^4.3.5",
|
|
150
152
|
"update-dotenv": "^1.1.1"
|
|
151
153
|
},
|
|
154
|
+
"optionalDependencies": {
|
|
155
|
+
"oracledb": "^5.3.0"
|
|
156
|
+
},
|
|
152
157
|
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
|
|
153
158
|
}
|
|
@@ -8,17 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
const
|
|
11
|
+
// when thread starts, make sure it is recorded
|
|
12
|
+
const env = require("../environment");
|
|
13
|
+
env.setInThread();
|
|
14
|
+
const actions = require("../automations/actions");
|
|
15
|
+
const automationUtils = require("../automations/automationUtils");
|
|
13
16
|
const AutomationEmitter = require("../events/AutomationEmitter");
|
|
14
17
|
const { processObject } = require("@budibase/string-templates");
|
|
15
18
|
const { DEFAULT_TENANT_ID } = require("@budibase/auth").constants;
|
|
16
19
|
const CouchDB = require("../db");
|
|
17
20
|
const { DocumentTypes, isDevAppID } = require("../db/utils");
|
|
18
21
|
const { doInTenant } = require("@budibase/auth/tenancy");
|
|
19
|
-
const env = require("../environment");
|
|
20
22
|
const usage = require("../utilities/usageQuota");
|
|
23
|
+
const { definitions: triggerDefs } = require("../automations/triggerInfo");
|
|
21
24
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId;
|
|
25
|
+
const CRON_STEP_ID = triggerDefs.CRON.stepId;
|
|
22
26
|
const STOPPED_STATUS = { success: false, status: "STOPPED" };
|
|
23
27
|
/**
|
|
24
28
|
* The automation orchestrator is a class responsible for executing automations.
|
|
@@ -31,6 +35,8 @@ class Orchestrator {
|
|
|
31
35
|
this._chainCount = this._metadata ? this._metadata.automationChainCount : 0;
|
|
32
36
|
this._appId = triggerOutput.appId;
|
|
33
37
|
this._app = null;
|
|
38
|
+
const triggerStepId = automation.definition.trigger.stepId;
|
|
39
|
+
triggerOutput = this.cleanupTriggerOutputs(triggerStepId, triggerOutput);
|
|
34
40
|
// remove from context
|
|
35
41
|
delete triggerOutput.appId;
|
|
36
42
|
delete triggerOutput.metadata;
|
|
@@ -42,10 +48,15 @@ class Orchestrator {
|
|
|
42
48
|
this._emitter = new AutomationEmitter(this._chainCount + 1);
|
|
43
49
|
this.executionOutput = { trigger: {}, steps: [] };
|
|
44
50
|
// setup the execution output
|
|
45
|
-
const triggerStepId = automation.definition.trigger.stepId;
|
|
46
51
|
const triggerId = automation.definition.trigger.id;
|
|
47
52
|
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput);
|
|
48
53
|
}
|
|
54
|
+
cleanupTriggerOutputs(stepId, triggerOutput) {
|
|
55
|
+
if (stepId === CRON_STEP_ID) {
|
|
56
|
+
triggerOutput.timestamp = Date.now();
|
|
57
|
+
}
|
|
58
|
+
return triggerOutput;
|
|
59
|
+
}
|
|
49
60
|
getStepFunctionality(stepId) {
|
|
50
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
62
|
let step = yield actions.getAction(stepId);
|
|
@@ -122,7 +133,14 @@ class Orchestrator {
|
|
|
122
133
|
});
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
|
-
module.exports = (
|
|
126
|
-
const automationOrchestrator = new Orchestrator(
|
|
127
|
-
|
|
128
|
-
|
|
136
|
+
module.exports = (input, callback) => {
|
|
137
|
+
const automationOrchestrator = new Orchestrator(input.data.automation, input.data.event);
|
|
138
|
+
automationOrchestrator
|
|
139
|
+
.execute()
|
|
140
|
+
.then(response => {
|
|
141
|
+
callback(null, response);
|
|
142
|
+
})
|
|
143
|
+
.catch(err => {
|
|
144
|
+
callback(err);
|
|
145
|
+
});
|
|
146
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const workerFarm = require("worker-farm");
|
|
3
|
+
const env = require("../environment");
|
|
4
|
+
const ThreadType = {
|
|
5
|
+
QUERY: "query",
|
|
6
|
+
AUTOMATION: "automation",
|
|
7
|
+
};
|
|
8
|
+
function typeToFile(type) {
|
|
9
|
+
let filename = null;
|
|
10
|
+
switch (type) {
|
|
11
|
+
case ThreadType.QUERY:
|
|
12
|
+
filename = "./query";
|
|
13
|
+
break;
|
|
14
|
+
case ThreadType.AUTOMATION:
|
|
15
|
+
filename = "./automation";
|
|
16
|
+
break;
|
|
17
|
+
default:
|
|
18
|
+
throw "Unknown thread type";
|
|
19
|
+
}
|
|
20
|
+
return require.resolve(filename);
|
|
21
|
+
}
|
|
22
|
+
class Thread {
|
|
23
|
+
constructor(type, opts = { timeoutMs: null, count: 1 }) {
|
|
24
|
+
this.type = type;
|
|
25
|
+
this.count = opts.count ? opts.count : 1;
|
|
26
|
+
this.disableThreading =
|
|
27
|
+
env.isTest() ||
|
|
28
|
+
env.DISABLE_THREADING ||
|
|
29
|
+
this.count === 0 ||
|
|
30
|
+
env.isInThread();
|
|
31
|
+
if (!this.disableThreading) {
|
|
32
|
+
const workerOpts = {
|
|
33
|
+
autoStart: true,
|
|
34
|
+
maxConcurrentWorkers: this.count,
|
|
35
|
+
};
|
|
36
|
+
if (opts.timeoutMs) {
|
|
37
|
+
workerOpts.maxCallTime = opts.timeoutMs;
|
|
38
|
+
}
|
|
39
|
+
this.workers = workerFarm(workerOpts, typeToFile(type));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
run(data) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
let fncToCall;
|
|
45
|
+
// if in test then don't use threading
|
|
46
|
+
if (this.disableThreading) {
|
|
47
|
+
fncToCall = require(typeToFile(this.type));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
fncToCall = this.workers;
|
|
51
|
+
}
|
|
52
|
+
fncToCall(data, (err, response) => {
|
|
53
|
+
if (err) {
|
|
54
|
+
reject(err);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
resolve(response);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
module.exports.Thread = Thread;
|
|
64
|
+
module.exports.ThreadType = ThreadType;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
// when thread starts, make sure it is recorded
|
|
12
|
+
const env = require("../environment");
|
|
13
|
+
env.setInThread();
|
|
14
|
+
const ScriptRunner = require("../utilities/scriptRunner");
|
|
15
|
+
const { integrations } = require("../integrations");
|
|
16
|
+
function formatResponse(resp) {
|
|
17
|
+
if (typeof resp === "string") {
|
|
18
|
+
try {
|
|
19
|
+
resp = JSON.parse(resp);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
resp = { response: resp };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return resp;
|
|
26
|
+
}
|
|
27
|
+
function runAndTransform(datasource, queryVerb, query, transformer) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const Integration = integrations[datasource.source];
|
|
30
|
+
if (!Integration) {
|
|
31
|
+
throw "Integration type does not exist.";
|
|
32
|
+
}
|
|
33
|
+
const integration = new Integration(datasource.config);
|
|
34
|
+
let rows = formatResponse(yield integration[queryVerb](query));
|
|
35
|
+
// transform as required
|
|
36
|
+
if (transformer) {
|
|
37
|
+
const runner = new ScriptRunner(transformer, { data: rows });
|
|
38
|
+
rows = runner.execute();
|
|
39
|
+
}
|
|
40
|
+
// needs to an array for next step
|
|
41
|
+
if (!Array.isArray(rows)) {
|
|
42
|
+
rows = [rows];
|
|
43
|
+
}
|
|
44
|
+
// map into JSON if just raw primitive here
|
|
45
|
+
if (rows.find(row => typeof row !== "object")) {
|
|
46
|
+
rows = rows.map(value => ({ value }));
|
|
47
|
+
}
|
|
48
|
+
// get all the potential fields in the schema
|
|
49
|
+
let keys = rows.flatMap(Object.keys);
|
|
50
|
+
if (integration.end) {
|
|
51
|
+
integration.end();
|
|
52
|
+
}
|
|
53
|
+
return { rows, keys };
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
module.exports = (input, callback) => {
|
|
57
|
+
runAndTransform(input.datasource, input.queryVerb, input.query, input.transformer)
|
|
58
|
+
.then(response => {
|
|
59
|
+
callback(null, response);
|
|
60
|
+
})
|
|
61
|
+
.catch(err => {
|
|
62
|
+
callback(err);
|
|
63
|
+
});
|
|
64
|
+
};
|