@budibase/server 2.6.19-alpha.2 → 2.6.19-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.
@@ -8,7 +8,7 @@
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" />
9
9
  <link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap"
10
10
  rel="stylesheet" />
11
- <script type="module" crossorigin src="/builder/assets/index.6c1171e2.js"></script>
11
+ <script type="module" crossorigin src="/builder/assets/index.3d5c50fb.js"></script>
12
12
  <link rel="stylesheet" href="/builder/assets/index.07382a47.css">
13
13
  </head>
14
14
 
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.query = exports.find = exports.destroy = exports.save = exports.update = exports.buildSchemaFromDb = exports.verify = exports.fetch = void 0;
15
+ exports.query = exports.find = exports.destroy = exports.save = exports.update = exports.buildSchemaFromDb = exports.information = exports.verify = exports.fetch = void 0;
16
16
  const utils_1 = require("../../db/utils");
17
17
  const internal_1 = require("./table/internal");
18
18
  const constants_1 = require("../../constants");
@@ -121,6 +121,21 @@ function verify(ctx) {
121
121
  });
122
122
  }
123
123
  exports.verify = verify;
124
+ function information(ctx) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const datasourceId = ctx.params.datasourceId;
127
+ const datasource = yield sdk_1.default.datasources.get(datasourceId, { enriched: true });
128
+ const connector = (yield getConnector(datasource));
129
+ if (!connector.getTableNames) {
130
+ ctx.throw(400, "Table name fetching not supported by datasource");
131
+ }
132
+ const tableNames = yield connector.getTableNames();
133
+ ctx.body = {
134
+ tableNames,
135
+ };
136
+ });
137
+ }
138
+ exports.information = information;
124
139
  function buildSchemaFromDb(ctx) {
125
140
  return __awaiter(this, void 0, void 0, function* () {
126
141
  const db = backend_core_1.context.getAppDB();
@@ -35,6 +35,7 @@ const router = new router_1.default();
35
35
  router
36
36
  .get("/api/datasources", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), datasourceController.fetch)
37
37
  .post("/api/datasources/verify", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), datasourceController.verify)
38
+ .get("/api/datasources/:datasourceId/info", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), datasourceController.information)
38
39
  .get("/api/datasources/:datasourceId", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), datasourceController.find)
39
40
  .put("/api/datasources/:datasourceId", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), datasourceController.update)
40
41
  .post("/api/datasources/query", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), (0, validators_1.datasourceQueryValidator)(), datasourceController.query)
@@ -37,10 +37,13 @@ const SCHEMA = {
37
37
  },
38
38
  relationships: false,
39
39
  docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
40
- description: "Create and collaborate on online spreadsheets in real-time and from any device. ",
40
+ description: "Create and collaborate on online spreadsheets in real-time and from any device.",
41
41
  friendlyName: "Google Sheets",
42
42
  type: "Spreadsheet",
43
- features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
43
+ features: [
44
+ types_1.DatasourceFeature.CONNECTION_CHECKING,
45
+ types_1.DatasourceFeature.FETCH_TABLE_NAMES,
46
+ ],
44
47
  datasource: {
45
48
  spreadsheetId: {
46
49
  display: "Google Sheet URL",
@@ -115,7 +118,6 @@ class GoogleSheetsIntegration {
115
118
  return __awaiter(this, void 0, void 0, function* () {
116
119
  try {
117
120
  yield this.connect();
118
- yield this.client.loadInfo();
119
121
  return { connected: true };
120
122
  }
121
123
  catch (e) {
@@ -196,6 +198,13 @@ class GoogleSheetsIntegration {
196
198
  }
197
199
  });
198
200
  }
201
+ getTableNames() {
202
+ return __awaiter(this, void 0, void 0, function* () {
203
+ yield this.connect();
204
+ const sheets = this.client.sheetsByIndex;
205
+ return sheets.map(s => s.title);
206
+ });
207
+ }
199
208
  getTableSchema(title, headerValues, id) {
200
209
  // base table
201
210
  const table = {
@@ -23,7 +23,10 @@ const SCHEMA = {
23
23
  description: "Microsoft SQL Server is a relational database management system developed by Microsoft. ",
24
24
  friendlyName: "MS SQL Server",
25
25
  type: "Relational",
26
- features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
26
+ features: [
27
+ types_1.DatasourceFeature.CONNECTION_CHECKING,
28
+ types_1.DatasourceFeature.FETCH_TABLE_NAMES,
29
+ ],
27
30
  datasource: {
28
31
  user: {
29
32
  type: types_1.DatasourceFieldType.STRING,
@@ -241,6 +244,22 @@ class SqlServerIntegration extends sql_1.default {
241
244
  this.schemaErrors = final.errors;
242
245
  });
243
246
  }
247
+ queryTableNames() {
248
+ return __awaiter(this, void 0, void 0, function* () {
249
+ let tableInfo = yield this.runSQL(this.TABLES_SQL);
250
+ const schema = this.config.schema || DEFAULT_SCHEMA;
251
+ return tableInfo
252
+ .filter((record) => record.TABLE_SCHEMA === schema)
253
+ .map((record) => record.TABLE_NAME)
254
+ .filter((name) => this.MASTER_TABLES.indexOf(name) === -1);
255
+ });
256
+ }
257
+ getTableNames() {
258
+ return __awaiter(this, void 0, void 0, function* () {
259
+ yield this.connect();
260
+ return this.queryTableNames();
261
+ });
262
+ }
244
263
  read(query) {
245
264
  return __awaiter(this, void 0, void 0, function* () {
246
265
  yield this.connect();
@@ -24,7 +24,10 @@ const SCHEMA = {
24
24
  friendlyName: "MySQL",
25
25
  type: "Relational",
26
26
  description: "MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
27
- features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
27
+ features: [
28
+ types_1.DatasourceFeature.CONNECTION_CHECKING,
29
+ types_1.DatasourceFeature.FETCH_TABLE_NAMES,
30
+ ],
28
31
  datasource: {
29
32
  host: {
30
33
  type: types_1.DatasourceFieldType.STRING,
@@ -186,13 +189,10 @@ class MySQLIntegration extends sql_1.default {
186
189
  buildSchema(datasourceId, entities) {
187
190
  return __awaiter(this, void 0, void 0, function* () {
188
191
  const tables = {};
189
- const database = this.config.database;
190
192
  yield this.connect();
191
193
  try {
192
194
  // get the tables first
193
- const tablesResp = yield this.internalQuery({ sql: "SHOW TABLES;" }, { connect: false });
194
- const tableNames = tablesResp.map((obj) => obj[`Tables_in_${database}`] ||
195
- obj[`Tables_in_${database.toLowerCase()}`]);
195
+ const tableNames = yield this.queryTableNames();
196
196
  for (let tableName of tableNames) {
197
197
  const primaryKeys = [];
198
198
  const schema = {};
@@ -230,6 +230,25 @@ class MySQLIntegration extends sql_1.default {
230
230
  this.schemaErrors = final.errors;
231
231
  });
232
232
  }
233
+ queryTableNames() {
234
+ return __awaiter(this, void 0, void 0, function* () {
235
+ const database = this.config.database;
236
+ const tablesResp = yield this.internalQuery({ sql: "SHOW TABLES;" }, { connect: false });
237
+ return tablesResp.map((obj) => obj[`Tables_in_${database}`] ||
238
+ obj[`Tables_in_${database.toLowerCase()}`]);
239
+ });
240
+ }
241
+ getTableNames() {
242
+ return __awaiter(this, void 0, void 0, function* () {
243
+ yield this.connect();
244
+ try {
245
+ return this.queryTableNames();
246
+ }
247
+ finally {
248
+ yield this.disconnect();
249
+ }
250
+ });
251
+ }
233
252
  create(query) {
234
253
  return __awaiter(this, void 0, void 0, function* () {
235
254
  const results = yield this.internalQuery((0, utils_1.getSqlQuery)(query));
@@ -30,7 +30,10 @@ const SCHEMA = {
30
30
  friendlyName: "Oracle",
31
31
  type: "Relational",
32
32
  description: "Oracle Database is an object-relational database management system developed by Oracle Corporation",
33
- features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
33
+ features: [
34
+ types_1.DatasourceFeature.CONNECTION_CHECKING,
35
+ types_1.DatasourceFeature.FETCH_TABLE_NAMES,
36
+ ],
34
37
  datasource: {
35
38
  host: {
36
39
  type: types_1.DatasourceFieldType.STRING,
@@ -272,6 +275,14 @@ class OracleIntegration extends sql_1.default {
272
275
  this.schemaErrors = final.errors;
273
276
  });
274
277
  }
278
+ getTableNames() {
279
+ return __awaiter(this, void 0, void 0, function* () {
280
+ const columnsResponse = yield this.internalQuery({
281
+ sql: this.COLUMNS_SQL,
282
+ });
283
+ return (columnsResponse.rows || []).map(row => row.TABLE_NAME);
284
+ });
285
+ }
275
286
  testConnection() {
276
287
  return __awaiter(this, void 0, void 0, function* () {
277
288
  const response = {
@@ -32,7 +32,10 @@ const SCHEMA = {
32
32
  friendlyName: "PostgreSQL",
33
33
  type: "Relational",
34
34
  description: "PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
35
- features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
35
+ features: [
36
+ types_1.DatasourceFeature.CONNECTION_CHECKING,
37
+ types_1.DatasourceFeature.FETCH_TABLE_NAMES,
38
+ ],
36
39
  datasource: {
37
40
  host: {
38
41
  type: types_1.DatasourceFieldType.STRING,
@@ -101,14 +104,15 @@ class PostgresIntegration extends sql_1.default {
101
104
  this.index = 1;
102
105
  this.tables = {};
103
106
  this.schemaErrors = {};
104
- this.PRIMARY_KEYS_SQL = `
105
- select tc.table_schema, tc.table_name, kc.column_name as primary_key
106
- from information_schema.table_constraints tc
107
- join
108
- information_schema.key_column_usage kc on kc.table_name = tc.table_name
109
- and kc.table_schema = tc.table_schema
110
- and kc.constraint_name = tc.constraint_name
111
- where tc.constraint_type = 'PRIMARY KEY';
107
+ this.PRIMARY_KEYS_SQL = () => `
108
+ SELECT pg_namespace.nspname table_schema
109
+ , pg_class.relname table_name
110
+ , pg_attribute.attname primary_key
111
+ FROM pg_class
112
+ JOIN pg_index ON pg_class.oid = pg_index.indrelid AND pg_index.indisprimary
113
+ JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY(pg_index.indkey)
114
+ JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
115
+ WHERE pg_namespace.nspname = '${this.config.schema}';
112
116
  `;
113
117
  this.config = config;
114
118
  let newConfig = Object.assign(Object.assign({}, this.config), { ssl: this.config.ssl
@@ -212,7 +216,7 @@ class PostgresIntegration extends sql_1.default {
212
216
  let tableKeys = {};
213
217
  yield this.openConnection();
214
218
  try {
215
- const primaryKeysResponse = yield this.client.query(this.PRIMARY_KEYS_SQL);
219
+ const primaryKeysResponse = yield this.client.query(this.PRIMARY_KEYS_SQL());
216
220
  for (let table of primaryKeysResponse.rows) {
217
221
  const tableName = table.table_name;
218
222
  if (!tableKeys[tableName]) {
@@ -270,6 +274,18 @@ class PostgresIntegration extends sql_1.default {
270
274
  }
271
275
  });
272
276
  }
277
+ getTableNames() {
278
+ return __awaiter(this, void 0, void 0, function* () {
279
+ try {
280
+ yield this.openConnection();
281
+ const columnsResponse = yield this.client.query(this.COLUMNS_SQL);
282
+ return columnsResponse.rows.map(row => row.table_name);
283
+ }
284
+ finally {
285
+ yield this.closeConnection();
286
+ }
287
+ });
288
+ }
273
289
  create(query) {
274
290
  return __awaiter(this, void 0, void 0, function* () {
275
291
  const response = yield this.internalQuery((0, utils_1.getSqlQuery)(query));