diff --git a/lerna.json b/lerna.json
index 05183ad6d4..caae7fbaaa 100644
--- a/lerna.json
+++ b/lerna.json
@@ -7,6 +7,7 @@
"packages/account-portal/packages/*"
],
"useNx": true,
+ "concurrency": 20,
"command": {
"publish": {
"ignoreChanges": [
@@ -21,4 +22,4 @@
"loadEnvFiles": false
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/builder/src/components/backend/DataTable/buttons/ExistingRelationshipButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ExistingRelationshipButton.svelte
index 839c396614..03f210e528 100644
--- a/packages/builder/src/components/backend/DataTable/buttons/ExistingRelationshipButton.svelte
+++ b/packages/builder/src/components/backend/DataTable/buttons/ExistingRelationshipButton.svelte
@@ -1,14 +1,19 @@
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
index c9010c0c1a..936eb614d6 100644
--- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
@@ -85,6 +85,7 @@
let relationshipTableIdSecondary = null
let table = $tables.selected
+
let confirmDeleteDialog
let savingColumn
let deleteColName
diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Relationships.svelte b/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Relationships.svelte
index 1a46ecb540..19f2486298 100644
--- a/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Relationships.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/data/datasource/[datasourceId]/_components/panels/Relationships.svelte
@@ -15,7 +15,8 @@
let modal
- $: tables = Object.values(datasource.entities)
+ $: tables =
+ $tablesStore.list.filter(tbl => tbl.sourceId === datasource._id) || []
$: relationships = getRelationships(tables)
function getRelationships(tables) {
@@ -43,14 +44,16 @@
})
})
- return Object.values(relatedColumns).map(({ from, to, through }) => {
- return {
- tables: `${from.tableName} ${through ? "↔" : "→"} ${to.tableName}`,
- columns: `${from.name} to ${to.name}`,
- from,
- to,
- }
- })
+ return Object.values(relatedColumns)
+ .filter(({ from, to }) => from && to)
+ .map(({ from, to, through }) => {
+ return {
+ tables: `${from.tableName} ${through ? "↔" : "→"} ${to.tableName}`,
+ columns: `${from.name} to ${to.name}`,
+ from,
+ to,
+ }
+ })
}
const handleRowClick = ({ detail }) => {
diff --git a/packages/server/src/api/controllers/datasource.ts b/packages/server/src/api/controllers/datasource.ts
index 39bc612b32..0a7430aa94 100644
--- a/packages/server/src/api/controllers/datasource.ts
+++ b/packages/server/src/api/controllers/datasource.ts
@@ -26,6 +26,7 @@ import {
import sdk from "../../sdk"
import { builderSocket } from "../../websockets"
import { setupCreationAuth as googleSetupCreationAuth } from "../../integrations/googlesheets"
+import { isEqual } from "lodash"
async function getConnector(
datasource: Datasource
@@ -198,19 +199,20 @@ async function invalidateVariables(
export async function update(ctx: UserCtx) {
const db = context.getAppDB()
const datasourceId = ctx.params.datasourceId
- let datasource = await sdk.datasources.get(datasourceId)
- const auth = datasource.config?.auth
- await invalidateVariables(datasource, ctx.request.body)
+ const baseDatasource = await sdk.datasources.get(datasourceId)
+ const auth = baseDatasource.config?.auth
+ await invalidateVariables(baseDatasource, ctx.request.body)
- const isBudibaseSource = datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE
+ const isBudibaseSource =
+ baseDatasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE
const dataSourceBody = isBudibaseSource
? { name: ctx.request.body?.name }
: ctx.request.body
- datasource = {
- ...datasource,
- ...sdk.datasources.mergeConfigs(dataSourceBody, datasource),
+ let datasource: Datasource = {
+ ...baseDatasource,
+ ...sdk.datasources.mergeConfigs(dataSourceBody, baseDatasource),
}
if (auth && !ctx.request.body.auth) {
// don't strip auth config from DB
@@ -245,6 +247,15 @@ export async function update(ctx: UserCtx) {
datasource: await sdk.datasources.removeSecretSingle(datasource),
}
builderSocket?.emitDatasourceUpdate(ctx, datasource)
+ // send table updates if they have occurred
+ if (datasource.entities) {
+ for (let table of Object.values(datasource.entities)) {
+ const oldTable = baseDatasource.entities?.[table.name]
+ if (!oldTable || !isEqual(oldTable, table)) {
+ builderSocket?.emitTableUpdate(ctx, table, { includeOriginator: true })
+ }
+ }
+ }
}
const preSaveAction: Partial> = {
diff --git a/packages/server/src/integrations/base/sqlTable.ts b/packages/server/src/integrations/base/sqlTable.ts
index 05954f0d25..1d3f542a10 100644
--- a/packages/server/src/integrations/base/sqlTable.ts
+++ b/packages/server/src/integrations/base/sqlTable.ts
@@ -6,13 +6,19 @@ import {
QueryJson,
RenameColumn,
Table,
+ FieldType,
} from "@budibase/types"
import { breakExternalTableId } from "../utils"
import SchemaBuilder = Knex.SchemaBuilder
import CreateTableBuilder = Knex.CreateTableBuilder
-import { FieldTypes, RelationshipType } from "../../constants"
+import { RelationshipType } from "../../constants"
import { utils } from "@budibase/shared-core"
+function isIgnoredType(type: FieldType) {
+ const ignored = [FieldType.LINK, FieldType.FORMULA]
+ return ignored.indexOf(type) !== -1
+}
+
function generateSchema(
schema: CreateTableBuilder,
table: Table,
@@ -47,13 +53,13 @@ function generateSchema(
continue
}
switch (column.type) {
- case FieldTypes.STRING:
- case FieldTypes.OPTIONS:
- case FieldTypes.LONGFORM:
- case FieldTypes.BARCODEQR:
+ case FieldType.STRING:
+ case FieldType.OPTIONS:
+ case FieldType.LONGFORM:
+ case FieldType.BARCODEQR:
schema.text(key)
break
- case FieldTypes.BB_REFERENCE:
+ case FieldType.BB_REFERENCE:
const subtype = column.subtype as FieldSubtype
switch (subtype) {
case FieldSubtype.USER:
@@ -66,7 +72,7 @@ function generateSchema(
throw utils.unreachable(subtype)
}
break
- case FieldTypes.NUMBER:
+ case FieldType.NUMBER:
// if meta is specified then this is a junction table entry
if (column.meta && column.meta.toKey && column.meta.toTable) {
const { toKey, toTable } = column.meta
@@ -76,21 +82,21 @@ function generateSchema(
schema.float(key)
}
break
- case FieldTypes.BIGINT:
+ case FieldType.BIGINT:
schema.bigint(key)
break
- case FieldTypes.BOOLEAN:
+ case FieldType.BOOLEAN:
schema.boolean(key)
break
- case FieldTypes.DATETIME:
+ case FieldType.DATETIME:
schema.datetime(key, {
useTz: !column.ignoreTimezones,
})
break
- case FieldTypes.ARRAY:
+ case FieldType.ARRAY:
schema.json(key)
break
- case FieldTypes.LINK:
+ case FieldType.LINK:
// this side of the relationship doesn't need any SQL work
if (
column.relationshipType !== RelationshipType.MANY_TO_ONE &&
@@ -121,22 +127,18 @@ function generateSchema(
}
}
- if (renamed) {
+ const oldType = renamed ? oldTable?.schema[renamed.old].type : undefined
+ if (renamed && oldType && !isIgnoredType(oldType)) {
schema.renameColumn(renamed.old, renamed.updated)
}
// need to check if any columns have been deleted
if (oldTable) {
- const deletedColumns = Object.entries(oldTable.schema)
- .filter(
- ([key, schema]) =>
- schema.type !== FieldTypes.LINK &&
- schema.type !== FieldTypes.FORMULA &&
- table.schema[key] == null
- )
- .map(([key]) => key)
- deletedColumns.forEach(key => {
- if (renamed?.old === key) {
+ const deletedColumns = Object.entries(oldTable.schema).filter(
+ ([key, column]) => isIgnoredType(column.type) && table.schema[key] == null
+ )
+ deletedColumns.forEach(([key, column]) => {
+ if (renamed?.old === key || isIgnoredType(column.type)) {
return
}
if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {
diff --git a/yarn.lock b/yarn.lock
index 6d21d3a3ee..c1ea211391 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1999,13 +1999,20 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.13.10":
+ version "7.23.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
+ integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/template@^7.22.5", "@babel/template@^7.3.3":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec"
@@ -5523,16 +5530,16 @@
"@types/passport" "*"
"@types/koa-send@*":
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/@types/koa-send/-/koa-send-4.1.5.tgz#c88362b07f0c12fd94ec9d61590a307be3f81a37"
- integrity sha512-O2qnxAKr7MoAxHHUitJejMWw45b9QtgTra0pnVDl/XoNdYTdZOgwj8wSVDon0qXg/lrcYHye4LFbAaSfSWwnrg==
+ version "4.1.6"
+ resolved "https://registry.yarnpkg.com/@types/koa-send/-/koa-send-4.1.6.tgz#15d90e95e3ccce669a15b6a3c56c3a650a167cea"
+ integrity sha512-vgnNGoOJkx7FrF0Jl6rbK1f8bBecqAchKpXtKuXzqIEdXTDO6dsSTjr+eZ5m7ltSjH4K/E7auNJEQCAd0McUPA==
dependencies:
"@types/koa" "*"
"@types/koa-static@^4.0.2":
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/@types/koa-static/-/koa-static-4.0.3.tgz#e008a7f6d8a7518c112fa67ba526fd2785d4cc85"
- integrity sha512-4U9uZwXqYAudDLDVkw1prJM5avn9/lHLVEwoyyI/ITZluWkBdmirkj8EsOLG6kLr0XFZdViR0ZBtQ3oetSsr3g==
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/@types/koa-static/-/koa-static-4.0.4.tgz#ce6f2a5d14cc7ef19f9bf6ee8e4f3eadfcc77323"
+ integrity sha512-j1AUzzl7eJYEk9g01hNTlhmipFh8RFbOQmaMNLvLcNNAkPw0bdTs3XTa3V045XFlrWN0QYnblbDJv2RzawTn6A==
dependencies:
"@types/koa" "*"
"@types/koa-send" "*"
@@ -5654,7 +5661,7 @@
"@types/node" "*"
form-data "^3.0.0"
-"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0", "@types/node@>=8.1.0":
+"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0":
version "20.8.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08"
integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==
@@ -5681,10 +5688,17 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d"
integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==
+"@types/node@>=8.1.0":
+ version "20.10.4"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198"
+ integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==
+ dependencies:
+ undici-types "~5.26.4"
+
"@types/nodemailer@^6.4.4":
- version "6.4.13"
- resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.13.tgz#3b3b47a27d1a33631a16763eb2ecdbd567147296"
- integrity sha512-889Vq/77eEpidCwh52sVWpbnqQmIwL8yVBekNbrztVEaWKOCRH3Eq6hjIJh1jwsGDEAJEH0RR+YhpH9mfELLKA==
+ version "6.4.14"
+ resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.14.tgz#5c81a5e856db7f8ede80013e6dbad7c5fb2283e2"
+ integrity sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==
dependencies:
"@types/node" "*"
@@ -5694,9 +5708,9 @@
integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
"@types/oauth@*":
- version "0.9.3"
- resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.3.tgz#4be90beb6c4a23e1a1614c966a165af1ef5e5e0d"
- integrity sha512-avZiwxSz/WS6EaEjhchzXKgWtlGGYGnEVJoHuQuDLHf7gIW1Gmm9eIxOMuJ6umQNNKZkJ3Uy+C/rLzEvL3I8Sw==
+ version "0.9.4"
+ resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.4.tgz#dcbab5efa2f34f312b915f80685760ccc8111e0a"
+ integrity sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==
dependencies:
"@types/node" "*"
@@ -5709,9 +5723,9 @@
dotenv "^8.2.0"
"@types/passport-google-oauth@^1.0.42":
- version "1.0.44"
- resolved "https://registry.yarnpkg.com/@types/passport-google-oauth/-/passport-google-oauth-1.0.44.tgz#b450dd05c7bcd01a927be79602364c98b0f81da8"
- integrity sha512-G4whyY+OKENthpR334PGPMxJc1LfvTJXirbJrk6ujr3LRJ/Bv7HoAxROJdYdVrajKNdc0i4v2msKPds9cBUzfw==
+ version "1.0.45"
+ resolved "https://registry.yarnpkg.com/@types/passport-google-oauth/-/passport-google-oauth-1.0.45.tgz#c986c787ec9706b4a596d2bae43342b50b54973d"
+ integrity sha512-O3Y3DDKnf9lR8+DSaUOCEGF6aFjVYdI8TLhQYtySZ3Sq75c5tGYJ0KJRDZw0GsyLD/Que0nqFkP/GnDVwZZL9w==
dependencies:
"@types/express" "*"
"@types/passport" "*"
@@ -5724,18 +5738,18 @@
"@types/passport-oauth2" "*"
"@types/passport-oauth2@*":
- version "1.4.14"
- resolved "https://registry.yarnpkg.com/@types/passport-oauth2/-/passport-oauth2-1.4.14.tgz#6982575b960eb7f001e28103ac3562349f1cded3"
- integrity sha512-wZBvnRwqdvm35l1Jn9ebYm2Q7UtxYIdBu1PjoKXMoxJytniVjXxYJmrlDXn5fMZROWbJbnEnp1XSDANqtvMdGQ==
+ version "1.4.15"
+ resolved "https://registry.yarnpkg.com/@types/passport-oauth2/-/passport-oauth2-1.4.15.tgz#34f2684f53aad36e664cd01ca9879224229f47e7"
+ integrity sha512-9cUTP/HStNSZmhxXGuRrBJfEWzIEJRub2eyJu3CvkA+8HAMc9W3aKdFhVq+Qz1hi42qn+GvSAnz3zwacDSYWpw==
dependencies:
"@types/express" "*"
"@types/oauth" "*"
"@types/passport" "*"
"@types/passport@*":
- version "1.0.14"
- resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.14.tgz#7ca891b04ae08d7ca4dbf30fece7c86174a16db9"
- integrity sha512-D6p2ygR2S7Cq5PO7iUaEIQu/5WrM0tONu6Lxgk0C9r3lafQIlVpWCo3V/KI9To3OqHBxcfQaOeK+8AvwW5RYmw==
+ version "1.0.16"
+ resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.16.tgz#5a2918b180a16924c4d75c31254c31cdca5ce6cf"
+ integrity sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==
dependencies:
"@types/express" "*"
@@ -5979,9 +5993,9 @@
"@types/node" "*"
"@types/server-destroy@^1.0.1":
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/@types/server-destroy/-/server-destroy-1.0.2.tgz#d83dce5ea8cf2b88f643d987863b8c619bc644a4"
- integrity sha512-Ac4skQzgViPGKqWU89yrtDDfZHvwDxQOzGnd4aS6Tab9IL3VatvfYk2LScKGNS/EML21yvF/9Zy4lMl74tXkPw==
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@types/server-destroy/-/server-destroy-1.0.3.tgz#2460932ea3a02a70ec99669c8f40ff089a5b8a2b"
+ integrity sha512-Qq0fn70C7TLDG1W9FCblKufNWW1OckQ41dVKV2Dku5KdZF7bexezG4e2WBaBKhdwL3HZ+cYCEIKwg2BRgzrWmA==
dependencies:
"@types/node" "*"
@@ -18141,7 +18155,14 @@ postgres-interval@^1.1.0:
dependencies:
xtend "^4.0.0"
-posthog-js@^1.13.4, posthog-js@^1.36.0:
+posthog-js@^1.13.4:
+ version "1.94.4"
+ resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.94.4.tgz#f480985e0fc131cc81edeb154d694ac5aca2e135"
+ integrity sha512-1usqOEkGE0ntit99G4TM1iPoq4QBbd5KcuovWroTy0PRJU8cOAfAT3FaJu+lX4B7izWo4DFjvesM/MOaJzLW/Q==
+ dependencies:
+ fflate "^0.4.1"
+
+posthog-js@^1.36.0:
version "1.87.2"
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.87.2.tgz#0e9395ea93d50bb624f0be19f254e62e54ae504d"
integrity sha512-pdxEylfxwEDwwz7g5dunPucvAN51RAOWWQmkcqHsLNHlV5o5bTaTwcAXaWB1IUn3xKPuKYE2lqbdB3vC4H4rFQ==
@@ -23006,19 +23027,6 @@ yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2, yargs@^17.7.2:
y18n "^5.0.5"
yargs-parser "^21.1.1"
-yargs@^17.7.2:
- version "17.7.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
- integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
- dependencies:
- cliui "^8.0.1"
- escalade "^3.1.1"
- get-caller-file "^2.0.5"
- require-directory "^2.1.1"
- string-width "^4.2.3"
- y18n "^5.0.5"
- yargs-parser "^21.1.1"
-
yauzl@^2.4.2:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"