Major update to make the table.type always 'table' and then adding a new sourceType which states what source the table came from, external or internal. Don't want to keep using a type that should be static as two different things.

This commit is contained in:
mike12345567 2023-10-26 13:19:09 +01:00
parent fd0d8f17f2
commit ed0670a008
44 changed files with 236 additions and 136 deletions

View File

@ -580,7 +580,7 @@ export const getFrontendStore = () => {
let table = validTables.find(table => { let table = validTables.find(table => {
return ( return (
table.sourceId !== BUDIBASE_INTERNAL_DB_ID && table.sourceId !== BUDIBASE_INTERNAL_DB_ID &&
table.type === DB_TYPE_INTERNAL table.sourceType === DB_TYPE_INTERNAL
) )
}) })
if (table) { if (table) {
@ -591,7 +591,7 @@ export const getFrontendStore = () => {
table = validTables.find(table => { table = validTables.find(table => {
return ( return (
table.sourceId === BUDIBASE_INTERNAL_DB_ID && table.sourceId === BUDIBASE_INTERNAL_DB_ID &&
table.type === DB_TYPE_INTERNAL table.sourceType === DB_TYPE_INTERNAL
) )
}) })
if (table) { if (table) {
@ -599,7 +599,7 @@ export const getFrontendStore = () => {
} }
// Finally try an external table // Finally try an external table
return validTables.find(table => table.type === DB_TYPE_EXTERNAL) return validTables.find(table => table.sourceType === DB_TYPE_EXTERNAL)
}, },
enrichEmptySettings: (component, opts) => { enrichEmptySettings: (component, opts) => {
if (!component?._component) { if (!component?._component) {

View File

@ -16,7 +16,6 @@
$: linkedTable = $tables.list.find(table => table._id === linkedTableId) $: linkedTable = $tables.list.find(table => table._id === linkedTableId)
$: schema = linkedTable?.schema $: schema = linkedTable?.schema
$: table = $tables.list.find(table => table._id === tableId) $: table = $tables.list.find(table => table._id === tableId)
$: type = table?.type
$: fetchData(tableId, rowId) $: fetchData(tableId, rowId)
$: { $: {
let rowLabel = row?.[table?.primaryDisplay] let rowLabel = row?.[table?.primaryDisplay]
@ -41,5 +40,5 @@
</script> </script>
{#if row && row._id === rowId} {#if row && row._id === rowId}
<Table {title} {schema} {data} {type} /> <Table {title} {schema} {data} />
{/if} {/if}

View File

@ -16,6 +16,7 @@
import GridRelationshipButton from "components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte" import GridRelationshipButton from "components/backend/DataTable/buttons/grid/GridRelationshipButton.svelte"
import GridEditColumnModal from "components/backend/DataTable/modals/grid/GridEditColumnModal.svelte" import GridEditColumnModal from "components/backend/DataTable/modals/grid/GridEditColumnModal.svelte"
import GridUsersTableButton from "components/backend/DataTable/modals/grid/GridUsersTableButton.svelte" import GridUsersTableButton from "components/backend/DataTable/modals/grid/GridUsersTableButton.svelte"
import { DB_TYPE_EXTERNAL } from "constants/backend"
const userSchemaOverrides = { const userSchemaOverrides = {
firstName: { displayName: "First name", disabled: true }, firstName: { displayName: "First name", disabled: true },
@ -27,7 +28,7 @@
$: id = $tables.selected?._id $: id = $tables.selected?._id
$: isUsersTable = id === TableNames.USERS $: isUsersTable = id === TableNames.USERS
$: isInternal = $tables.selected?.type !== "external" $: isInternal = $tables.selected?.sourceType !== DB_TYPE_EXTERNAL
$: gridDatasource = { $: gridDatasource = {
type: "table", type: "table",
tableId: id, tableId: id,
@ -46,10 +47,7 @@
tables.replaceTable(id, e.detail) tables.replaceTable(id, e.detail)
// We need to refresh datasources when an external table changes. // We need to refresh datasources when an external table changes.
// Type "external" may exist - sometimes type is "table" and sometimes it if (e.detail?.sourceType === DB_TYPE_EXTERNAL || e.detail?.sql) {
// is "external" - it has different meanings in different endpoints.
// If we check both these then we hopefully catch all external tables.
if (e.detail?.type === "external" || e.detail?.sql) {
await datasources.fetch() await datasources.fetch()
} }
} }

View File

@ -17,7 +17,6 @@
let hideAutocolumns = true let hideAutocolumns = true
let data = [] let data = []
let loading = false let loading = false
let type = "internal"
$: name = view.name $: name = view.name
$: calculation = view.calculation $: calculation = view.calculation
@ -65,7 +64,6 @@
tableId={view.tableId} tableId={view.tableId}
{data} {data}
{loading} {loading}
{type}
rowCount={10} rowCount={10}
allowEditing={false} allowEditing={false}
bind:hideAutocolumns bind:hideAutocolumns

View File

@ -10,6 +10,6 @@
<ImportButton <ImportButton
{disabled} {disabled}
tableId={$datasource?.tableId} tableId={$datasource?.tableId}
tableType={$definition?.type} tableType={$definition?.sourceType}
on:importrows={rows.actions.refreshData} on:importrows={rows.actions.refreshData}
/> />

View File

@ -26,6 +26,7 @@
ALLOWABLE_NUMBER_TYPES, ALLOWABLE_NUMBER_TYPES,
SWITCHABLE_TYPES, SWITCHABLE_TYPES,
PrettyRelationshipDefinitions, PrettyRelationshipDefinitions,
DB_TYPE_EXTERNAL,
} from "constants/backend" } from "constants/backend"
import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils" import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
@ -254,10 +255,11 @@
!uneditable && !uneditable &&
editableColumn?.type !== AUTO_TYPE && editableColumn?.type !== AUTO_TYPE &&
!editableColumn.autocolumn !editableColumn.autocolumn
$: external = table.type === "external" $: externalTable = table.sourceType === DB_TYPE_EXTERNAL
// in the case of internal tables the sourceId will just be undefined // in the case of internal tables the sourceId will just be undefined
$: tableOptions = $tables.list.filter( $: tableOptions = $tables.list.filter(
opt => opt.type === table.type && table.sourceId === opt.sourceId opt =>
opt.sourceType === table.sourceType && table.sourceId === opt.sourceId
) )
$: typeEnabled = $: typeEnabled =
!originalName || !originalName ||
@ -409,7 +411,7 @@
editableColumn.type === FieldType.BB_REFERENCE && editableColumn.type === FieldType.BB_REFERENCE &&
editableColumn.subtype === FieldSubtype.USERS editableColumn.subtype === FieldSubtype.USERS
if (!external) { if (!externalTable) {
return [ return [
FIELDS.STRING, FIELDS.STRING,
FIELDS.BARCODEQR, FIELDS.BARCODEQR,
@ -441,7 +443,7 @@
isUsers ? FIELDS.USERS : FIELDS.USER, isUsers ? FIELDS.USERS : FIELDS.USER,
] ]
// no-sql or a spreadsheet // no-sql or a spreadsheet
if (!external || table.sql) { if (!externalTable || table.sql) {
fields = [...fields, FIELDS.LINK, FIELDS.ARRAY] fields = [...fields, FIELDS.LINK, FIELDS.ARRAY]
} }
return fields return fields
@ -486,7 +488,7 @@
}) })
} }
const newError = {} const newError = {}
if (!external && fieldInfo.name?.startsWith("_")) { if (!externalTable && fieldInfo.name?.startsWith("_")) {
newError.name = `Column name cannot start with an underscore.` newError.name = `Column name cannot start with an underscore.`
} else if (fieldInfo.name && !fieldInfo.name.match(ValidColumnNameRegex)) { } else if (fieldInfo.name && !fieldInfo.name.match(ValidColumnNameRegex)) {
newError.name = `Illegal character; must be alpha-numeric.` newError.name = `Illegal character; must be alpha-numeric.`
@ -498,7 +500,7 @@
newError.name = `Column name already in use.` newError.name = `Column name already in use.`
} }
if (fieldInfo.type == "auto" && !fieldInfo.subtype) { if (fieldInfo.type === "auto" && !fieldInfo.subtype) {
newError.subtype = `Auto Column requires a type` newError.subtype = `Auto Column requires a type`
} }

View File

@ -1,6 +1,6 @@
<script> <script>
import { Select, Toggle, Multiselect } from "@budibase/bbui" import { Select, Toggle, Multiselect } from "@budibase/bbui"
import { FIELDS } from "constants/backend" import { DB_TYPE_INTERNAL, FIELDS } from "constants/backend"
import { API } from "api" import { API } from "api"
import { parseFile } from "./utils" import { parseFile } from "./utils"
@ -169,7 +169,7 @@
</div> </div>
{/each} {/each}
</div> </div>
{#if tableType === "internal"} {#if tableType === DB_TYPE_INTERNAL}
<br /> <br />
<Toggle <Toggle
bind:value={updateExistingRows} bind:value={updateExistingRows}

View File

@ -8,6 +8,7 @@
import { import {
BUDIBASE_INTERNAL_DB_ID, BUDIBASE_INTERNAL_DB_ID,
BUDIBASE_DATASOURCE_TYPE, BUDIBASE_DATASOURCE_TYPE,
DB_TYPE_INTERNAL,
} from "constants/backend" } from "constants/backend"
$: tableNames = $tables.list.map(table => table.name) $: tableNames = $tables.list.map(table => table.name)
@ -55,8 +56,9 @@
name, name,
schema: { ...schema }, schema: { ...schema },
rows, rows,
type: "internal", type: "table",
sourceId: targetDatasourceId, sourceId: targetDatasourceId,
sourceType: DB_TYPE_INTERNAL,
} }
// Only set primary display if defined // Only set primary display if defined

View File

@ -13,6 +13,7 @@
notifications, notifications,
} from "@budibase/bbui" } from "@budibase/bbui"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { DB_TYPE_EXTERNAL } from "constants/backend"
export let table export let table
@ -27,8 +28,8 @@
let willBeDeleted let willBeDeleted
let deleteTableName let deleteTableName
$: external = table?.type === "external" $: externalTable = table?.sourceType === DB_TYPE_EXTERNAL
$: allowDeletion = !external || table?.created $: allowDeletion = !externalTable || table?.created
function showDeleteModal() { function showDeleteModal() {
templateScreens = $store.screens.filter( templateScreens = $store.screens.filter(
@ -48,7 +49,7 @@
for (let screen of templateScreens) { for (let screen of templateScreens) {
await store.actions.screens.delete(screen) await store.actions.screens.delete(screen)
} }
if (table.type === "external") { if (table.sourceType === DB_TYPE_EXTERNAL) {
await datasources.fetch() await datasources.fetch()
} }
notifications.success("Table deleted") notifications.success("Table deleted")
@ -91,7 +92,7 @@
<div slot="control" class="icon"> <div slot="control" class="icon">
<Icon s hoverable name="MoreSmallList" /> <Icon s hoverable name="MoreSmallList" />
</div> </div>
{#if !external} {#if !externalTable}
<MenuItem icon="Edit" on:click={editorModal.show}>Edit</MenuItem> <MenuItem icon="Edit" on:click={editorModal.show}>Edit</MenuItem>
{/if} {/if}
<MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem> <MenuItem icon="Delete" on:click={showDeleteModal}>Delete</MenuItem>

View File

@ -23,7 +23,7 @@
</script> </script>
<div class="table"> <div class="table">
<Table {schema} data={rowsCopy} type="external" allowEditing={false} /> <Table {schema} data={rowsCopy} allowEditing={false} />
</div> </div>
<style> <style>

View File

@ -2,6 +2,7 @@
import { ModalContent, Body, Input, notifications } from "@budibase/bbui" import { ModalContent, Body, Input, notifications } from "@budibase/bbui"
import { tables, datasources } from "stores/backend" import { tables, datasources } from "stores/backend"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { DB_TYPE_EXTERNAL } from "constants/backend"
export let datasource export let datasource
@ -16,9 +17,10 @@
function buildDefaultTable(tableName, datasourceId) { function buildDefaultTable(tableName, datasourceId) {
return { return {
name: tableName, name: tableName,
type: "external", type: "table",
primary: ["id"], primary: ["id"],
sourceId: datasourceId, sourceId: datasourceId,
sourceType: DB_TYPE_EXTERNAL,
schema: { schema: {
id: { id: {
autocolumn: true, autocolumn: true,

View File

@ -5,7 +5,7 @@
import { tables, datasources } from "stores/backend" import { tables, datasources } from "stores/backend"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { onMount } from "svelte" import { onMount } from "svelte"
import { BUDIBASE_INTERNAL_DB_ID } from "constants/backend" import { BUDIBASE_INTERNAL_DB_ID, DB_TYPE_EXTERNAL } from "constants/backend"
import { TableNames } from "constants" import { TableNames } from "constants"
import { store } from "builderStore" import { store } from "builderStore"
@ -14,7 +14,7 @@
$: store.actions.websocket.selectResource(BUDIBASE_INTERNAL_DB_ID) $: store.actions.websocket.selectResource(BUDIBASE_INTERNAL_DB_ID)
$: internalTablesBySourceId = $tables.list.filter( $: internalTablesBySourceId = $tables.list.filter(
table => table =>
table.type !== "external" && table.sourceType !== DB_TYPE_EXTERNAL &&
table.sourceId === BUDIBASE_INTERNAL_DB_ID && table.sourceId === BUDIBASE_INTERNAL_DB_ID &&
table._id !== TableNames.USERS table._id !== TableNames.USERS
) )

View File

@ -4,7 +4,7 @@
import ICONS from "components/backend/DatasourceNavigator/icons" import ICONS from "components/backend/DatasourceNavigator/icons"
import { tables, datasources } from "stores/backend" import { tables, datasources } from "stores/backend"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { DEFAULT_BB_DATASOURCE_ID } from "constants/backend" import { DEFAULT_BB_DATASOURCE_ID, DB_TYPE_EXTERNAL } from "constants/backend"
import { onMount } from "svelte" import { onMount } from "svelte"
import { store } from "builderStore" import { store } from "builderStore"
@ -13,7 +13,8 @@
$: store.actions.websocket.selectResource(DEFAULT_BB_DATASOURCE_ID) $: store.actions.websocket.selectResource(DEFAULT_BB_DATASOURCE_ID)
$: internalTablesBySourceId = $tables.list.filter( $: internalTablesBySourceId = $tables.list.filter(
table => table =>
table.type !== "external" && table.sourceId === DEFAULT_BB_DATASOURCE_ID table.sourceType !== DB_TYPE_EXTERNAL &&
table.sourceId === DEFAULT_BB_DATASOURCE_ID
) )
onMount(() => { onMount(() => {

View File

@ -13,12 +13,13 @@ import {
FetchTablesResponse, FetchTablesResponse,
MigrateRequest, MigrateRequest,
MigrateResponse, MigrateResponse,
Row,
SaveTableRequest, SaveTableRequest,
SaveTableResponse, SaveTableResponse,
Table, Table,
TableResponse, TableResponse,
TableSourceType,
UserCtx, UserCtx,
Row,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { jsonFromCsvString } from "../../../utilities/csv" import { jsonFromCsvString } from "../../../utilities/csv"
@ -29,7 +30,7 @@ function pickApi({ tableId, table }: { tableId?: string; table?: Table }) {
if (table && !tableId) { if (table && !tableId) {
tableId = table._id tableId = table._id
} }
if (table && table.type === "external") { if (table && table.sourceType === TableSourceType.EXTERNAL) {
return external return external
} else if (tableId && isExternalTable(tableId)) { } else if (tableId && isExternalTable(tableId)) {
return external return external
@ -48,7 +49,7 @@ export async function fetch(ctx: UserCtx<void, FetchTablesResponse>) {
if (entities) { if (entities) {
return Object.values(entities).map<Table>((entity: Table) => ({ return Object.values(entities).map<Table>((entity: Table) => ({
...entity, ...entity,
type: "external", sourceType: TableSourceType.EXTERNAL,
sourceId: datasource._id!, sourceId: datasource._id!,
sql: isSQL(datasource), sql: isSQL(datasource),
})) }))

View File

@ -7,6 +7,7 @@ import {
SaveTableRequest, SaveTableRequest,
SaveTableResponse, SaveTableResponse,
Table, Table,
TableSourceType,
UserCtx, UserCtx,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../../sdk" import sdk from "../../../sdk"
@ -16,10 +17,11 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
let tableToSave: Table & { let tableToSave: Table & {
_rename?: RenameColumn _rename?: RenameColumn
} = { } = {
type: "table",
_id: generateTableID(), _id: generateTableID(),
views: {},
...rest, ...rest,
type: "table",
sourceType: TableSourceType.INTERNAL,
views: {},
} }
const renaming = tableToSave._rename const renaming = tableToSave._rename
delete tableToSave._rename delete tableToSave._rename

View File

@ -10,6 +10,7 @@ import {
FieldSchema, FieldSchema,
FieldType, FieldType,
FieldTypeSubtypes, FieldTypeSubtypes,
INTERNAL_TABLE_SOURCE_ID,
MonthlyQuotaName, MonthlyQuotaName,
PermissionLevel, PermissionLevel,
QuotaUsageType, QuotaUsageType,
@ -21,7 +22,7 @@ import {
SortType, SortType,
StaticQuotaName, StaticQuotaName,
Table, Table,
INTERNAL_TABLE_SOURCE_ID, TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { import {
expectAnyExternalColsAttributes, expectAnyExternalColsAttributes,
@ -66,6 +67,7 @@ describe.each([
type: "table", type: "table",
primary: ["id"], primary: ["id"],
primaryDisplay: "name", primaryDisplay: "name",
sourceType: TableSourceType.INTERNAL,
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
schema: { schema: {
id: { id: {
@ -441,6 +443,7 @@ describe.each([
describe("view save", () => { describe("view save", () => {
it("views have extra data trimmed", async () => { it("views have extra data trimmed", async () => {
const table = await config.createTable({ const table = await config.createTable({
type: "table",
name: "orders", name: "orders",
primary: ["OrderID"], primary: ["OrderID"],
schema: { schema: {
@ -883,6 +886,7 @@ describe.each([
return { return {
name: `users_${generator.word()}`, name: `users_${generator.word()}`,
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
type: "table", type: "table",
primary: ["id"], primary: ["id"],
schema: { schema: {
@ -1066,6 +1070,7 @@ describe.each([
return { return {
name: `users_${generator.word()}`, name: `users_${generator.word()}`,
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
type: "table", type: "table",
primary: ["id"], primary: ["id"],
schema: { schema: {
@ -1603,7 +1608,7 @@ describe.each([
if (config.datasource) { if (config.datasource) {
tableConfig.sourceId = config.datasource._id! tableConfig.sourceId = config.datasource._id!
if (config.datasource.plus) { if (config.datasource.plus) {
tableConfig.type = "external" tableConfig.sourceType = TableSourceType.EXTERNAL
} }
} }
const table = await config.api.table.create({ const table = await config.api.table.create({

View File

@ -1,21 +1,23 @@
import { events, context } from "@budibase/backend-core" import { context, events } from "@budibase/backend-core"
import { import {
FieldType,
SaveTableRequest,
RelationshipType,
Table,
ViewCalculation,
AutoFieldSubTypes, AutoFieldSubTypes,
InternalTable,
FieldSubtype, FieldSubtype,
Row, FieldType,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
InternalTable,
RelationshipType,
Row,
SaveTableRequest,
Table,
TableSourceType,
ViewCalculation,
} from "@budibase/types" } from "@budibase/types"
import { checkBuilderEndpoint } from "./utilities/TestFunctions" import { checkBuilderEndpoint } from "./utilities/TestFunctions"
import * as setup from "./utilities" import * as setup from "./utilities"
const { basicTable } = setup.structures
import sdk from "../../../sdk" import sdk from "../../../sdk"
const { basicTable } = setup.structures
describe("/tables", () => { describe("/tables", () => {
let request = setup.getRequest() let request = setup.getRequest()
let config = setup.getConfig() let config = setup.getConfig()
@ -434,6 +436,7 @@ describe("/tables", () => {
name: "table", name: "table",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
"user relationship": { "user relationship": {
type: FieldType.LINK, type: FieldType.LINK,
@ -494,6 +497,7 @@ describe("/tables", () => {
name: "table", name: "table",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
"user relationship": { "user relationship": {
type: FieldType.LINK, type: FieldType.LINK,
@ -556,6 +560,7 @@ describe("/tables", () => {
name: "table", name: "table",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
"user relationship": { "user relationship": {
type: FieldType.LINK, type: FieldType.LINK,

View File

@ -3,14 +3,15 @@ import {
CreateViewRequest, CreateViewRequest,
FieldSchema, FieldSchema,
FieldType, FieldType,
INTERNAL_TABLE_SOURCE_ID,
SearchQueryOperators, SearchQueryOperators,
SortOrder, SortOrder,
SortType, SortType,
Table, Table,
TableSourceType,
UIFieldMetadata, UIFieldMetadata,
UpdateViewRequest, UpdateViewRequest,
ViewV2, ViewV2,
INTERNAL_TABLE_SOURCE_ID,
} from "@budibase/types" } from "@budibase/types"
import { generator } from "@budibase/backend-core/tests" import { generator } from "@budibase/backend-core/tests"
import { generateDatasourceID } from "../../../db/utils" import { generateDatasourceID } from "../../../db/utils"
@ -20,6 +21,7 @@ function priceTable(): Table {
name: "table", name: "table",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
Price: { Price: {
type: FieldType.NUMBER, type: FieldType.NUMBER,
@ -59,7 +61,7 @@ describe.each([
return config.createTable({ return config.createTable({
...priceTable(), ...priceTable(),
sourceId: datasource._id, sourceId: datasource._id,
type: "external", sourceType: TableSourceType.EXTERNAL,
}) })
}, },
], ],

View File

@ -1,9 +1,11 @@
import { objectStore, roles, constants } from "@budibase/backend-core" import { constants, objectStore, roles } from "@budibase/backend-core"
import { import {
FieldType as FieldTypes, FieldType as FieldTypes,
Table,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
export { export {
FieldType as FieldTypes, FieldType as FieldTypes,
RelationshipType, RelationshipType,
@ -78,6 +80,7 @@ export const USERS_TABLE_SCHEMA: Table = {
_id: "ta_users", _id: "ta_users",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
views: {}, views: {},
name: "Users", name: "Users",
// TODO: ADMIN PANEL - when implemented this doesn't need to be carried out // TODO: ADMIN PANEL - when implemented this doesn't need to be carried out

View File

@ -1,4 +1,4 @@
import { FieldTypes, AutoFieldSubTypes } from "../../constants" import { AutoFieldSubTypes, FieldTypes } from "../../constants"
import { importToRows } from "../../api/controllers/table/utils" import { importToRows } from "../../api/controllers/table/utils"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import LinkDocument from "../linkedRows/LinkDocument" import LinkDocument from "../linkedRows/LinkDocument"
@ -8,11 +8,12 @@ import { jobsImport } from "./jobsImport"
import { expensesImport } from "./expensesImport" import { expensesImport } from "./expensesImport"
import { db as dbCore } from "@budibase/backend-core" import { db as dbCore } from "@budibase/backend-core"
import { import {
Table,
Row,
RelationshipType,
FieldType, FieldType,
RelationshipType,
Row,
Table,
TableSchema, TableSchema,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
export const DEFAULT_JOBS_TABLE_ID = "ta_bb_jobs" export const DEFAULT_JOBS_TABLE_ID = "ta_bb_jobs"
@ -89,9 +90,10 @@ const AUTO_COLUMNS: TableSchema = {
export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = { export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
_id: DEFAULT_INVENTORY_TABLE_ID, _id: DEFAULT_INVENTORY_TABLE_ID,
type: "internal", type: "table",
views: {}, views: {},
sourceId: DEFAULT_BB_DATASOURCE_ID, sourceId: DEFAULT_BB_DATASOURCE_ID,
sourceType: TableSourceType.INTERNAL,
primaryDisplay: "Item Name", primaryDisplay: "Item Name",
name: "Inventory", name: "Inventory",
schema: { schema: {
@ -198,10 +200,11 @@ export const DEFAULT_INVENTORY_TABLE_SCHEMA: Table = {
export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = { export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
_id: DEFAULT_EMPLOYEE_TABLE_ID, _id: DEFAULT_EMPLOYEE_TABLE_ID,
type: "internal", type: "table",
views: {}, views: {},
name: "Employees", name: "Employees",
sourceId: DEFAULT_BB_DATASOURCE_ID, sourceId: DEFAULT_BB_DATASOURCE_ID,
sourceType: TableSourceType.INTERNAL,
primaryDisplay: "First Name", primaryDisplay: "First Name",
schema: { schema: {
"First Name": { "First Name": {
@ -346,9 +349,10 @@ export const DEFAULT_EMPLOYEE_TABLE_SCHEMA: Table = {
export const DEFAULT_JOBS_TABLE_SCHEMA: Table = { export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
_id: DEFAULT_JOBS_TABLE_ID, _id: DEFAULT_JOBS_TABLE_ID,
type: "internal", type: "table",
name: "Jobs", name: "Jobs",
sourceId: DEFAULT_BB_DATASOURCE_ID, sourceId: DEFAULT_BB_DATASOURCE_ID,
sourceType: TableSourceType.INTERNAL,
primaryDisplay: "Job ID", primaryDisplay: "Job ID",
schema: { schema: {
"Job ID": { "Job ID": {
@ -503,10 +507,11 @@ export const DEFAULT_JOBS_TABLE_SCHEMA: Table = {
export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = { export const DEFAULT_EXPENSES_TABLE_SCHEMA: Table = {
_id: DEFAULT_EXPENSES_TABLE_ID, _id: DEFAULT_EXPENSES_TABLE_ID,
type: "internal", type: "table",
views: {}, views: {},
name: "Expenses", name: "Expenses",
sourceId: DEFAULT_BB_DATASOURCE_ID, sourceId: DEFAULT_BB_DATASOURCE_ID,
sourceType: TableSourceType.INTERNAL,
primaryDisplay: "Expense ID", primaryDisplay: "Expense ID",
schema: { schema: {
"Expense ID": { "Expense ID": {

View File

@ -1,6 +1,4 @@
import fetch from "node-fetch" import fetch from "node-fetch"
// @ts-ignore
fetch.mockSearch()
import { import {
generateMakeRequest, generateMakeRequest,
MakeRequestResponse, MakeRequestResponse,
@ -13,12 +11,15 @@ import {
RelationshipType, RelationshipType,
Row, Row,
Table, Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import _ from "lodash" import _ from "lodash"
import { generator } from "@budibase/backend-core/tests" import { generator } from "@budibase/backend-core/tests"
import { utils } from "@budibase/backend-core" import { utils } from "@budibase/backend-core"
import { databaseTestProviders } from "../integrations/tests/utils" import { databaseTestProviders } from "../integrations/tests/utils"
import { Client } from "pg" import { Client } from "pg"
// @ts-ignore
fetch.mockSearch()
const config = setup.getConfig()! const config = setup.getConfig()!
@ -52,7 +53,7 @@ describe("postgres integrations", () => {
async function createAuxTable(prefix: string) { async function createAuxTable(prefix: string) {
return await config.createTable({ return await config.createTable({
name: `${prefix}_${generator.word({ length: 6 })}`, name: `${prefix}_${generator.word({ length: 6 })}`,
type: "external", type: "table",
primary: ["id"], primary: ["id"],
primaryDisplay: "title", primaryDisplay: "title",
schema: { schema: {
@ -67,6 +68,7 @@ describe("postgres integrations", () => {
}, },
}, },
sourceId: postgresDatasource._id, sourceId: postgresDatasource._id,
sourceType: TableSourceType.EXTERNAL,
}) })
} }
@ -88,7 +90,7 @@ describe("postgres integrations", () => {
primaryPostgresTable = await config.createTable({ primaryPostgresTable = await config.createTable({
name: `p_${generator.word({ length: 6 })}`, name: `p_${generator.word({ length: 6 })}`,
type: "external", type: "table",
primary: ["id"], primary: ["id"],
schema: { schema: {
id: { id: {
@ -143,6 +145,7 @@ describe("postgres integrations", () => {
}, },
}, },
sourceId: postgresDatasource._id, sourceId: postgresDatasource._id,
sourceType: TableSourceType.EXTERNAL,
}) })
}) })
@ -249,7 +252,7 @@ describe("postgres integrations", () => {
async function createDefaultPgTable() { async function createDefaultPgTable() {
return await config.createTable({ return await config.createTable({
name: generator.word({ length: 10 }), name: generator.word({ length: 10 }),
type: "external", type: "table",
primary: ["id"], primary: ["id"],
schema: { schema: {
id: { id: {
@ -259,6 +262,7 @@ describe("postgres integrations", () => {
}, },
}, },
sourceId: postgresDatasource._id, sourceId: postgresDatasource._id,
sourceType: TableSourceType.EXTERNAL,
}) })
} }

View File

@ -10,11 +10,12 @@ import {
QueryJson, QueryJson,
QueryType, QueryType,
Row, Row,
Schema,
SearchFilters, SearchFilters,
SortJson, SortJson,
Table, Table,
TableRequest, TableRequest,
Schema, TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { OAuth2Client } from "google-auth-library" import { OAuth2Client } from "google-auth-library"
import { import {
@ -263,10 +264,12 @@ class GoogleSheetsIntegration implements DatasourcePlus {
) { ) {
// base table // base table
const table: Table = { const table: Table = {
type: "table",
name: title, name: title,
primary: [GOOGLE_SHEETS_PRIMARY_KEY], primary: [GOOGLE_SHEETS_PRIMARY_KEY],
schema: {}, schema: {},
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
} }
if (id) { if (id) {
table._id = id table._id = id

View File

@ -12,6 +12,7 @@ import {
ConnectionInfo, ConnectionInfo,
SourceName, SourceName,
Schema, Schema,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { import {
getSqlQuery, getSqlQuery,
@ -439,7 +440,9 @@ class SqlServerIntegration extends Sql implements DatasourcePlus {
} }
tables[tableName] = { tables[tableName] = {
_id: buildExternalTableId(datasourceId, tableName), _id: buildExternalTableId(datasourceId, tableName),
type: "table",
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
primary: primaryKeys, primary: primaryKeys,
name: tableName, name: tableName,
schema, schema,

View File

@ -11,6 +11,7 @@ import {
ConnectionInfo, ConnectionInfo,
SourceName, SourceName,
Schema, Schema,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { import {
getSqlQuery, getSqlQuery,
@ -317,8 +318,10 @@ class MySQLIntegration extends Sql implements DatasourcePlus {
} }
if (!tables[tableName]) { if (!tables[tableName]) {
tables[tableName] = { tables[tableName] = {
type: "table",
_id: buildExternalTableId(datasourceId, tableName), _id: buildExternalTableId(datasourceId, tableName),
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
primary: primaryKeys, primary: primaryKeys,
name: tableName, name: tableName,
schema, schema,

View File

@ -10,6 +10,7 @@ import {
DatasourceFeature, DatasourceFeature,
ConnectionInfo, ConnectionInfo,
Schema, Schema,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { import {
buildExternalTableId, buildExternalTableId,
@ -277,11 +278,13 @@ class OracleIntegration extends Sql implements DatasourcePlus {
let table = tables[oracleTable.name] let table = tables[oracleTable.name]
if (!table) { if (!table) {
table = { table = {
type: "table",
_id: buildExternalTableId(datasourceId, oracleTable.name), _id: buildExternalTableId(datasourceId, oracleTable.name),
primary: [], primary: [],
name: oracleTable.name, name: oracleTable.name,
schema: {}, schema: {},
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
} }
tables[oracleTable.name] = table tables[oracleTable.name] = table
} }

View File

@ -11,6 +11,7 @@ import {
ConnectionInfo, ConnectionInfo,
SourceName, SourceName,
Schema, Schema,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { import {
getSqlQuery, getSqlQuery,
@ -309,11 +310,13 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
// table key doesn't exist yet // table key doesn't exist yet
if (!tables[tableName] || !tables[tableName].schema) { if (!tables[tableName] || !tables[tableName].schema) {
tables[tableName] = { tables[tableName] = {
type: "table",
_id: buildExternalTableId(datasourceId, tableName), _id: buildExternalTableId(datasourceId, tableName),
primary: tableKeys[tableName] || [], primary: tableKeys[tableName] || [],
name: tableName, name: tableName,
schema: {}, schema: {},
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
} }
} }

View File

@ -30,7 +30,7 @@ GoogleSpreadsheet.mockImplementation(() => mockGoogleIntegration)
import { structures } from "@budibase/backend-core/tests" import { structures } from "@budibase/backend-core/tests"
import TestConfiguration from "../../tests/utilities/TestConfiguration" import TestConfiguration from "../../tests/utilities/TestConfiguration"
import GoogleSheetsIntegration from "../googlesheets" import GoogleSheetsIntegration from "../googlesheets"
import { FieldType, Table, TableSchema } from "@budibase/types" import { FieldType, Table, TableSchema, TableSourceType } from "@budibase/types"
import { generateDatasourceID } from "../../db/utils" import { generateDatasourceID } from "../../db/utils"
describe("Google Sheets Integration", () => { describe("Google Sheets Integration", () => {
@ -61,8 +61,10 @@ describe("Google Sheets Integration", () => {
function createBasicTable(name: string, columns: string[]): Table { function createBasicTable(name: string, columns: string[]): Table {
return { return {
type: "table",
name, name,
sourceId: generateDatasourceID(), sourceId: generateDatasourceID(),
sourceType: TableSourceType.EXTERNAL,
schema: { schema: {
...columns.reduce((p, c) => { ...columns.reduce((p, c) => {
p[c] = { p[c] = {

View File

@ -5,6 +5,7 @@ import {
Row, Row,
Table, Table,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import * as utils from "../../db/utils" import * as utils from "../../db/utils"
import trimViewRowInfoMiddleware from "../trimViewRowInfo" import trimViewRowInfoMiddleware from "../trimViewRowInfo"
@ -80,6 +81,7 @@ describe("trimViewRowInfo middleware", () => {
_id: tableId, _id: tableId,
name: generator.word(), name: generator.word(),
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
type: "table", type: "table",
schema: { schema: {
name: { name: {

View File

@ -1,7 +1,6 @@
import { Ctx, Row } from "@budibase/types" import { Ctx, Row } from "@budibase/types"
import * as utils from "../db/utils" import * as utils from "../db/utils"
import sdk from "../sdk" import sdk from "../sdk"
import { db } from "@budibase/backend-core"
import { Next } from "koa" import { Next } from "koa"
import { getTableId } from "../api/controllers/row/utils" import { getTableId } from "../api/controllers/row/utils"

View File

@ -7,6 +7,7 @@ import {
SourceName, SourceName,
Table, Table,
SearchParams, SearchParams,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import TestConfiguration from "../../../../../tests/utilities/TestConfiguration" import TestConfiguration from "../../../../../tests/utilities/TestConfiguration"
@ -59,9 +60,10 @@ describe.skip("external", () => {
tableData = { tableData = {
name: generator.word(), name: generator.word(),
type: "external", type: "table",
primary: ["id"], primary: ["id"],
sourceId: externalDatasource._id!, sourceId: externalDatasource._id!,
sourceType: TableSourceType.EXTERNAL,
schema: { schema: {
id: { id: {
name: "id", name: "id",

View File

@ -4,6 +4,7 @@ import {
Table, Table,
SearchParams, SearchParams,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import TestConfiguration from "../../../../../tests/utilities/TestConfiguration" import TestConfiguration from "../../../../../tests/utilities/TestConfiguration"
import { search } from "../internal" import { search } from "../internal"
@ -19,6 +20,7 @@ describe("internal", () => {
name: generator.word(), name: generator.word(),
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
name: "name", name: "name",

View File

@ -3,16 +3,19 @@ import { db as dbCore } from "@budibase/backend-core"
import { import {
FieldType, FieldType,
FieldTypeSubtypes, FieldTypeSubtypes,
Table,
SearchParams,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
SearchParams,
Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
const tableId = "ta_a" const tableId = "ta_a"
const tableWithUserCol: Table = { const tableWithUserCol: Table = {
type: "table",
_id: tableId, _id: tableId,
name: "table", name: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
user: { user: {
name: "user", name: "user",
@ -23,9 +26,11 @@ const tableWithUserCol: Table = {
} }
const tableWithUsersCol: Table = { const tableWithUsersCol: Table = {
type: "table",
_id: tableId, _id: tableId,
name: "table", name: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
user: { user: {
name: "user", name: "user",

View File

@ -6,6 +6,7 @@ import {
RelationshipFieldMetadata, RelationshipFieldMetadata,
RelationshipType, RelationshipType,
Table, Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { FieldTypes } from "../../../../constants" import { FieldTypes } from "../../../../constants"
import { import {
@ -78,12 +79,14 @@ export function generateManyLinkSchema(
const jcTblName = generateJunctionTableName(column, table, relatedTable) const jcTblName = generateJunctionTableName(column, table, relatedTable)
const datasourceId = datasource._id! const datasourceId = datasource._id!
// first create the new table // first create the new table
const junctionTable = { const junctionTable: Table = {
type: "table",
_id: buildExternalTableId(datasourceId, jcTblName), _id: buildExternalTableId(datasourceId, jcTblName),
name: jcTblName, name: jcTblName,
primary: [primary, relatedPrimary], primary: [primary, relatedPrimary],
constrained: [primary, relatedPrimary], constrained: [primary, relatedPrimary],
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
schema: { schema: {
[primary]: foreignKeyStructure(primary, { [primary]: foreignKeyStructure(primary, {
toTable: table.name, toTable: table.name,

View File

@ -7,24 +7,41 @@ import {
} from "../../../integrations/utils" } from "../../../integrations/utils"
import { import {
Database, Database,
INTERNAL_TABLE_SOURCE_ID,
Table, Table,
TableResponse, TableResponse,
TableSourceType,
TableViewsResponse, TableViewsResponse,
INTERNAL_TABLE_SOURCE_ID,
} from "@budibase/types" } from "@budibase/types"
import datasources from "../datasources" import datasources from "../datasources"
import sdk from "../../../sdk" import sdk from "../../../sdk"
function processInternalTables(tables: Table[]): Table[] { export function processTable(table: Table): Table {
return tables.map(processInternalTable) if (table._id && isExternalTable(table._id)) {
return {
...table,
type: "table",
sourceType: TableSourceType.EXTERNAL,
}
} else {
return {
...table,
type: "table",
sourceId: table.sourceId || INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
}
}
} }
export function processInternalTable(table: Table): Table { export function processTables(tables: Table[]): Table[] {
return { return tables.map(table => processTable(table))
...table, }
type: "internal",
sourceId: table.sourceId || INTERNAL_TABLE_SOURCE_ID, function processEntities(tables: Record<string, Table>) {
for (let key of Object.keys(tables)) {
tables[key] = processTable(tables[key])
} }
return tables
} }
export async function getAllInternalTables(db?: Database): Promise<Table[]> { export async function getAllInternalTables(db?: Database): Promise<Table[]> {
@ -36,7 +53,7 @@ export async function getAllInternalTables(db?: Database): Promise<Table[]> {
include_docs: true, include_docs: true,
}) })
) )
return processInternalTables(internalTables.rows.map(row => row.doc!)) return processTables(internalTables.rows.map(row => row.doc!))
} }
async function getAllExternalTables(): Promise<Table[]> { async function getAllExternalTables(): Promise<Table[]> {
@ -48,7 +65,7 @@ async function getAllExternalTables(): Promise<Table[]> {
final = final.concat(Object.values(entities)) final = final.concat(Object.values(entities))
} }
} }
return final return processTables(final)
} }
export async function getExternalTable( export async function getExternalTable(
@ -56,19 +73,21 @@ export async function getExternalTable(
tableName: string tableName: string
): Promise<Table> { ): Promise<Table> {
const entities = await getExternalTablesInDatasource(datasourceId) const entities = await getExternalTablesInDatasource(datasourceId)
return entities[tableName] return processTable(entities[tableName])
} }
export async function getTable(tableId: string): Promise<Table> { export async function getTable(tableId: string): Promise<Table> {
const db = context.getAppDB() const db = context.getAppDB()
let output: Table
if (isExternalTable(tableId)) { if (isExternalTable(tableId)) {
let { datasourceId, tableName } = breakExternalTableId(tableId) let { datasourceId, tableName } = breakExternalTableId(tableId)
const datasource = await datasources.get(datasourceId!) const datasource = await datasources.get(datasourceId!)
const table = await getExternalTable(datasourceId!, tableName!) const table = await getExternalTable(datasourceId!, tableName!)
return { ...table, sql: isSQL(datasource) } output = { ...table, sql: isSQL(datasource) }
} else { } else {
return processInternalTable(await db.get<Table>(tableId)) output = await db.get<Table>(tableId)
} }
return processTable(output)
} }
export async function getAllTables() { export async function getAllTables() {
@ -76,7 +95,7 @@ export async function getAllTables() {
getAllInternalTables(), getAllInternalTables(),
getAllExternalTables(), getAllExternalTables(),
]) ])
return [...internal, ...external] return processTables([...internal, ...external])
} }
export async function getExternalTablesInDatasource( export async function getExternalTablesInDatasource(
@ -86,7 +105,7 @@ export async function getExternalTablesInDatasource(
if (!datasource || !datasource.entities) { if (!datasource || !datasource.entities) {
throw new Error("Datasource is not configured fully.") throw new Error("Datasource is not configured fully.")
} }
return datasource.entities return processEntities(datasource.entities)
} }
export async function getTables(tableIds: string[]): Promise<Table[]> { export async function getTables(tableIds: string[]): Promise<Table[]> {
@ -106,11 +125,9 @@ export async function getTables(tableIds: string[]): Promise<Table[]> {
const internalTableDocs = await db.allDocs<Table[]>( const internalTableDocs = await db.allDocs<Table[]>(
getMultiIDParams(internalTableIds) getMultiIDParams(internalTableIds)
) )
tables = tables.concat( tables = tables.concat(internalTableDocs.rows.map(row => row.doc!))
processInternalTables(internalTableDocs.rows.map(row => row.doc!))
)
} }
return tables return processTables(tables)
} }
export function enrichViewSchemas(table: Table): TableResponse { export function enrichViewSchemas(table: Table): TableResponse {

View File

@ -2,6 +2,7 @@ import {
FieldType, FieldType,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
Table, Table,
TableSourceType,
ViewV2, ViewV2,
} from "@budibase/types" } from "@budibase/types"
import { generator } from "@budibase/backend-core/tests" import { generator } from "@budibase/backend-core/tests"
@ -19,6 +20,7 @@ describe("table sdk", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,

View File

@ -7,6 +7,7 @@ import {
RelationshipType, RelationshipType,
SourceName, SourceName,
Table, Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { isEqual } from "lodash" import { isEqual } from "lodash"
import { generateDatasourceID } from "../../../../db/utils" import { generateDatasourceID } from "../../../../db/utils"
@ -19,11 +20,13 @@ const SCHEMA: Datasource = {
_id: datasourceId, _id: datasourceId,
entities: { entities: {
client: { client: {
type: "table",
_id: "tableA", _id: "tableA",
name: "client", name: "client",
primary: ["idC"], primary: ["idC"],
primaryDisplay: "Name", primaryDisplay: "Name",
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
schema: { schema: {
idC: { idC: {
autocolumn: true, autocolumn: true,
@ -49,11 +52,13 @@ const SCHEMA: Datasource = {
}, },
}, },
project: { project: {
type: "table",
_id: "tableB", _id: "tableB",
name: "project", name: "project",
primary: ["idP"], primary: ["idP"],
primaryDisplay: "Name", primaryDisplay: "Name",
sourceId: datasourceId, sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
schema: { schema: {
idC: { idC: {
externalType: "int unsigned", externalType: "int unsigned",
@ -82,7 +87,6 @@ const SCHEMA: Datasource = {
}, },
}, },
sql: true, sql: true,
type: "table",
}, },
}, },
} }

View File

@ -1,8 +1,8 @@
import { Table } from "@budibase/types" import { Table, TableSourceType } from "@budibase/types"
import { isExternalTable } from "../../../integrations/utils" import { isExternalTable } from "../../../integrations/utils"
export function isExternal(opts: { table?: Table; tableId?: string }): boolean { export function isExternal(opts: { table?: Table; tableId?: string }): boolean {
if (opts.table && opts.table.type === "external") { if (opts.table && opts.table.sourceType === TableSourceType.EXTERNAL) {
return true return true
} else if (opts.tableId && isExternalTable(opts.tableId)) { } else if (opts.tableId && isExternalTable(opts.tableId)) {
return true return true

View File

@ -5,6 +5,7 @@ import {
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
Table, Table,
TableSchema, TableSchema,
TableSourceType,
ViewV2, ViewV2,
} from "@budibase/types" } from "@budibase/types"
import { generator } from "@budibase/backend-core/tests" import { generator } from "@budibase/backend-core/tests"
@ -16,6 +17,7 @@ describe("table sdk", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,

View File

@ -2,37 +2,31 @@ import { generator, mocks, structures } from "@budibase/backend-core/tests"
// init the licensing mock // init the licensing mock
import * as pro from "@budibase/pro" import * as pro from "@budibase/pro"
mocks.licenses.init(pro)
// use unlimited license by default
mocks.licenses.useUnlimited()
import { init as dbInit } from "../../db" import { init as dbInit } from "../../db"
dbInit()
import env from "../../environment" import env from "../../environment"
import { import {
basicTable,
basicRow,
basicRole,
basicAutomation, basicAutomation,
basicDatasource,
basicQuery,
basicScreen,
basicLayout,
basicWebhook,
basicAutomationResults, basicAutomationResults,
basicDatasource,
basicLayout,
basicQuery,
basicRole,
basicRow,
basicScreen,
basicTable,
basicWebhook,
} from "./structures" } from "./structures"
import { import {
constants, auth,
tenancy,
sessions,
cache, cache,
constants,
context, context,
db as dbCore, db as dbCore,
encryption, encryption,
auth,
roles,
env as coreEnv, env as coreEnv,
roles,
sessions,
tenancy,
} from "@budibase/backend-core" } from "@budibase/backend-core"
import * as controllers from "./controllers" import * as controllers from "./controllers"
import { cleanup } from "../../utilities/fileSystem" import { cleanup } from "../../utilities/fileSystem"
@ -43,24 +37,32 @@ import supertest from "supertest"
import { import {
App, App,
AuthToken, AuthToken,
Automation,
CreateViewRequest,
Datasource, Datasource,
FieldType,
INTERNAL_TABLE_SOURCE_ID,
RelationshipFieldMetadata,
RelationshipType,
Row, Row,
SearchFilters,
SourceName, SourceName,
Table, Table,
SearchFilters, TableSourceType,
UserRoles,
Automation,
View,
FieldType,
RelationshipType,
CreateViewRequest,
RelationshipFieldMetadata,
User, User,
INTERNAL_TABLE_SOURCE_ID, UserRoles,
View,
} from "@budibase/types" } from "@budibase/types"
import API from "./api" import API from "./api"
mocks.licenses.init(pro)
// use unlimited license by default
mocks.licenses.useUnlimited()
dbInit()
type DefaultUserValues = { type DefaultUserValues = {
globalUserId: string globalUserId: string
email: string email: string
@ -69,8 +71,9 @@ type DefaultUserValues = {
csrfToken: string csrfToken: string
} }
interface TableToBuild extends Omit<Table, "sourceId"> { interface TableToBuild extends Omit<Table, "sourceId" | "sourceType"> {
sourceId?: string sourceId?: string
sourceType?: TableSourceType
} }
class TestConfiguration { class TestConfiguration {
@ -547,9 +550,8 @@ class TestConfiguration {
{ skipReassigning } = { skipReassigning: false } { skipReassigning } = { skipReassigning: false }
): Promise<Table> { ): Promise<Table> {
config = config || basicTable() config = config || basicTable()
if (!config.sourceId) { config.sourceType = config.sourceType || TableSourceType.INTERNAL
config.sourceId = INTERNAL_TABLE_SOURCE_ID config.sourceId = config.sourceId || INTERNAL_TABLE_SOURCE_ID
}
const response = await this._req(config, null, controllers.table.save) const response = await this._req(config, null, controllers.table.save)
if (!skipReassigning) { if (!skipReassigning) {
this.table = response this.table = response
@ -571,7 +573,7 @@ class TestConfiguration {
if (this.datasource && !config.sourceId) { if (this.datasource && !config.sourceId) {
config.sourceId = this.datasource._id || INTERNAL_TABLE_SOURCE_ID config.sourceId = this.datasource._id || INTERNAL_TABLE_SOURCE_ID
if (this.datasource.plus) { if (this.datasource.plus) {
config.type = "external" config.sourceType = TableSourceType.EXTERNAL
} }
} }
@ -609,12 +611,11 @@ class TestConfiguration {
if (this.datasource && !tableConfig.sourceId) { if (this.datasource && !tableConfig.sourceId) {
tableConfig.sourceId = this.datasource._id || INTERNAL_TABLE_SOURCE_ID tableConfig.sourceId = this.datasource._id || INTERNAL_TABLE_SOURCE_ID
if (this.datasource.plus) { if (this.datasource.plus) {
tableConfig.type = "external" tableConfig.sourceType = TableSourceType.EXTERNAL
} }
} }
const linkedTable = await this.createTable(tableConfig) return await this.createTable(tableConfig)
return linkedTable
} }
async createAttachmentTable() { async createAttachmentTable() {

View File

@ -20,6 +20,7 @@ import {
SourceName, SourceName,
Table, Table,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
export function basicTable(): Table { export function basicTable(): Table {
@ -27,6 +28,7 @@ export function basicTable(): Table {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,

View File

@ -5,6 +5,7 @@ import {
FieldTypeSubtypes, FieldTypeSubtypes,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
Table, Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import * as bbReferenceProcessor from "../bbReferenceProcessor" import * as bbReferenceProcessor from "../bbReferenceProcessor"
@ -26,6 +27,7 @@ describe("rowProcessor - inputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,
@ -77,6 +79,7 @@ describe("rowProcessor - inputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,
@ -118,6 +121,7 @@ describe("rowProcessor - inputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,
@ -159,6 +163,7 @@ describe("rowProcessor - inputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,

View File

@ -4,6 +4,7 @@ import {
FieldTypeSubtypes, FieldTypeSubtypes,
INTERNAL_TABLE_SOURCE_ID, INTERNAL_TABLE_SOURCE_ID,
Table, Table,
TableSourceType,
} from "@budibase/types" } from "@budibase/types"
import { outputProcessing } from ".." import { outputProcessing } from ".."
import { generator, structures } from "@budibase/backend-core/tests" import { generator, structures } from "@budibase/backend-core/tests"
@ -28,6 +29,7 @@ describe("rowProcessor - outputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,
@ -74,6 +76,7 @@ describe("rowProcessor - outputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,
@ -112,6 +115,7 @@ describe("rowProcessor - outputProcessing", () => {
name: "TestTable", name: "TestTable",
type: "table", type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID, sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: { schema: {
name: { name: {
type: FieldType.STRING, type: FieldType.STRING,

View File

@ -16,8 +16,7 @@ import { gridSocket } from "./index"
import { clearLock, updateLock } from "../utilities/redis" import { clearLock, updateLock } from "../utilities/redis"
import { Socket } from "socket.io" import { Socket } from "socket.io"
import { BuilderSocketEvent } from "@budibase/shared-core" import { BuilderSocketEvent } from "@budibase/shared-core"
import { processInternalTable } from "../sdk/app/tables/getters" import { processTable } from "../sdk/app/tables/getters"
import { isInternalTable } from "../integrations/utils"
export default class BuilderSocket extends BaseSocket { export default class BuilderSocket extends BaseSocket {
constructor(app: Koa, server: http.Server) { constructor(app: Koa, server: http.Server) {
@ -106,9 +105,7 @@ export default class BuilderSocket extends BaseSocket {
// This was added to make sure that sourceId is always present when // This was added to make sure that sourceId is always present when
// sending this message to clients. Without this, tables without a // sending this message to clients. Without this, tables without a
// sourceId (e.g. ta_users) won't get correctly updated client-side. // sourceId (e.g. ta_users) won't get correctly updated client-side.
if (isInternalTable(table._id!)) { table = processTable(table)
table = processInternalTable(table)
}
this.emitToRoom( this.emitToRoom(
ctx, ctx,

View File

@ -5,8 +5,14 @@ import { TableSchema } from "./schema"
export const INTERNAL_TABLE_SOURCE_ID = "bb_internal" export const INTERNAL_TABLE_SOURCE_ID = "bb_internal"
export enum TableSourceType {
EXTERNAL = "external",
INTERNAL = "internal",
}
export interface Table extends Document { export interface Table extends Document {
type?: string type: "table"
sourceType: TableSourceType
views?: { [key: string]: View | ViewV2 } views?: { [key: string]: View | ViewV2 }
name: string name: string
sourceId: string sourceId: string