import { context } from "@budibase/backend-core" import { getMultiIDParams, getTableParams } from "../../../db/utils" import { breakExternalTableId, isExternalTable, isSQL, } from "../../../integrations/utils" import { Database, Table, TableResponse, TableViewsResponse, INTERNAL_TABLE_SOURCE_ID, } from "@budibase/types" import datasources from "../datasources" import sdk from "../../../sdk" function processInternalTables(tables: Table[]): Table[] { return tables.map(processInternalTable) } export function processInternalTable(table: Table): Table { return { ...table, type: "internal", sourceId: table.sourceId || INTERNAL_TABLE_SOURCE_ID, } } export async function getAllInternalTables(db?: Database): Promise { if (!db) { db = context.getAppDB() } const internalTables = await db.allDocs( getTableParams(null, { include_docs: true, }) ) return processInternalTables(internalTables.rows.map(row => row.doc!)) } async function getAllExternalTables(): Promise { const datasources = await sdk.datasources.fetch({ enriched: true }) const allEntities = datasources.map(datasource => datasource.entities) let final: Table[] = [] for (let entities of allEntities) { if (entities) { final = final.concat(Object.values(entities)) } } return final } export async function getExternalTable( datasourceId: string, tableName: string ): Promise { const entities = await getExternalTablesInDatasource(datasourceId) return entities[tableName] } export async function getTable(tableId: string): Promise
{ const db = context.getAppDB() if (isExternalTable(tableId)) { let { datasourceId, tableName } = breakExternalTableId(tableId) const datasource = await datasources.get(datasourceId!) const table = await getExternalTable(datasourceId!, tableName!) return { ...table, sql: isSQL(datasource) } } else { return processInternalTable(await db.get
(tableId)) } } export async function getAllTables() { const [internal, external] = await Promise.all([ getAllInternalTables(), getAllExternalTables(), ]) return [...internal, ...external] } export async function getExternalTablesInDatasource( datasourceId: string ): Promise> { const datasource = await datasources.get(datasourceId, { enriched: true }) if (!datasource || !datasource.entities) { throw new Error("Datasource is not configured fully.") } return datasource.entities } export async function getTables(tableIds: string[]): Promise { const externalTableIds = tableIds.filter(tableId => isExternalTable(tableId)), internalTableIds = tableIds.filter(tableId => !isExternalTable(tableId)) let tables: Table[] = [] if (externalTableIds.length) { const externalTables = await getAllExternalTables() tables = tables.concat( externalTables.filter( table => externalTableIds.indexOf(table._id!) !== -1 ) ) } if (internalTableIds.length) { const db = context.getAppDB() const internalTableDocs = await db.allDocs( getMultiIDParams(internalTableIds) ) tables = tables.concat( processInternalTables(internalTableDocs.rows.map(row => row.doc!)) ) } return tables } export function enrichViewSchemas(table: Table): TableResponse { return { ...table, views: Object.values(table.views ?? []) .map(v => sdk.views.enrichSchema(v, table.schema)) .reduce((p, v) => { p[v.name!] = v return p }, {} as TableViewsResponse), } }