Merge pull request #6043 from Budibase/fix/json-schema

Enrich data fetch subscriptions with additional JSON schema fields
This commit is contained in:
Martin McKeaveney 2022-05-27 14:34:28 +01:00 committed by GitHub
commit a0a7537e1d
2 changed files with 55 additions and 36 deletions

View File

@ -1,5 +1,4 @@
import { API } from "api" import { API } from "api"
import { JSONUtils } from "@budibase/frontend-core"
import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch.js" import TableFetch from "@budibase/frontend-core/src/fetch/TableFetch.js"
import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch.js" import ViewFetch from "@budibase/frontend-core/src/fetch/ViewFetch.js"
import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch.js" import QueryFetch from "@budibase/frontend-core/src/fetch/QueryFetch.js"
@ -40,44 +39,41 @@ export const fetchDatasourceSchema = async (
return null return null
} }
// Check for any JSON fields so we can add any top level properties // Enrich schema with relationships if required
let jsonAdditions = {} if (definition?.sql && options?.enrichRelationships) {
Object.keys(schema).forEach(fieldKey => { const relationshipAdditions = await getRelationshipSchemaAdditions(schema)
schema = {
...schema,
...relationshipAdditions,
}
}
// Ensure schema is in the correct structure
return instance.enrichSchema(schema)
}
/**
* Fetches the schema of relationship fields for a SQL table schema
* @param schema the schema to enrich
*/
export const getRelationshipSchemaAdditions = async schema => {
if (!schema) {
return null
}
let relationshipAdditions = {}
for (let fieldKey of Object.keys(schema)) {
const fieldSchema = schema[fieldKey] const fieldSchema = schema[fieldKey]
if (fieldSchema?.type === "json") { if (fieldSchema?.type === "link") {
const jsonSchema = JSONUtils.convertJSONSchemaToTableSchema(fieldSchema, { const linkSchema = await fetchDatasourceSchema({
squashObjects: true, type: "table",
tableId: fieldSchema?.tableId,
}) })
Object.keys(jsonSchema).forEach(jsonKey => { Object.keys(linkSchema || {}).forEach(linkKey => {
jsonAdditions[`${fieldKey}.${jsonKey}`] = { relationshipAdditions[`${fieldKey}.${linkKey}`] = {
type: jsonSchema[jsonKey].type, type: linkSchema[linkKey].type,
nestedJSON: true,
} }
}) })
} }
})
schema = { ...schema, ...jsonAdditions }
// Check for any relationship fields if required
if (options?.enrichRelationships && definition.sql) {
let relationshipAdditions = {}
for (let fieldKey of Object.keys(schema)) {
const fieldSchema = schema[fieldKey]
if (fieldSchema?.type === "link") {
const linkSchema = await fetchDatasourceSchema({
type: "table",
tableId: fieldSchema?.tableId,
})
Object.keys(linkSchema || {}).forEach(linkKey => {
relationshipAdditions[`${fieldKey}.${linkKey}`] = {
type: linkSchema[linkKey].type,
}
})
}
}
schema = { ...schema, ...relationshipAdditions }
} }
return relationshipAdditions
// Ensure schema structure is correct
return instance.enrichSchema(schema)
} }

View File

@ -6,6 +6,7 @@ import {
runLuceneQuery, runLuceneQuery,
luceneSort, luceneSort,
} from "../utils/lucene" } from "../utils/lucene"
import { convertJSONSchemaToTableSchema } from "../utils/json"
/** /**
* Parent class which handles the implementation of fetching data from an * Parent class which handles the implementation of fetching data from an
@ -248,7 +249,8 @@ export default class DataFetch {
} }
/** /**
* Enriches the schema and ensures that entries are objects with names * Enriches a datasource schema with nested fields and ensures the structure
* is correct.
* @param schema the datasource schema * @param schema the datasource schema
* @return {object} the enriched datasource schema * @return {object} the enriched datasource schema
*/ */
@ -256,6 +258,26 @@ export default class DataFetch {
if (schema == null) { if (schema == null) {
return null return null
} }
// Check for any JSON fields so we can add any top level properties
let jsonAdditions = {}
Object.keys(schema).forEach(fieldKey => {
const fieldSchema = schema[fieldKey]
if (fieldSchema?.type === "json") {
const jsonSchema = convertJSONSchemaToTableSchema(fieldSchema, {
squashObjects: true,
})
Object.keys(jsonSchema).forEach(jsonKey => {
jsonAdditions[`${fieldKey}.${jsonKey}`] = {
type: jsonSchema[jsonKey].type,
nestedJSON: true,
}
})
}
})
schema = { ...schema, ...jsonAdditions }
// Ensure schema is in the correct structure
let enrichedSchema = {} let enrichedSchema = {}
Object.entries(schema).forEach(([fieldName, fieldSchema]) => { Object.entries(schema).forEach(([fieldName, fieldSchema]) => {
if (typeof fieldSchema === "string") { if (typeof fieldSchema === "string") {
@ -270,6 +292,7 @@ export default class DataFetch {
} }
} }
}) })
return enrichedSchema return enrichedSchema
} }