Invalidate related tables automatically via client library and fix issue with data source invalidation from modals

This commit is contained in:
Andrew Kingston 2021-10-26 19:12:55 +01:00
parent 54aad2ff1e
commit 262b238388
3 changed files with 48 additions and 35 deletions

View File

@ -20,7 +20,7 @@ export const executeQuery = async ({ queryId, parameters }) => {
notificationStore.actions.error("An error has occurred")
} else if (!query.readable) {
notificationStore.actions.success("Query executed successfully")
dataSourceStore.actions.invalidateDataSource(query.datasourceId)
await dataSourceStore.actions.invalidateDataSource(query.datasourceId)
}
return res
}

View File

@ -31,7 +31,7 @@ export const saveRow = async row => {
: notificationStore.actions.success("Row saved")
// Refresh related datasources
dataSourceStore.actions.invalidateDataSource(row.tableId)
await dataSourceStore.actions.invalidateDataSource(row.tableId)
return res
}
@ -52,7 +52,7 @@ export const updateRow = async row => {
: notificationStore.actions.success("Row updated")
// Refresh related datasources
dataSourceStore.actions.invalidateDataSource(row.tableId)
await dataSourceStore.actions.invalidateDataSource(row.tableId)
return res
}
@ -76,7 +76,7 @@ export const deleteRow = async ({ tableId, rowId, revId }) => {
: notificationStore.actions.success("Row deleted")
// Refresh related datasources
dataSourceStore.actions.invalidateDataSource(tableId)
await dataSourceStore.actions.invalidateDataSource(tableId)
return res
}
@ -99,7 +99,7 @@ export const deleteRows = async ({ tableId, rows }) => {
: notificationStore.actions.success(`${rows.length} row(s) deleted`)
// Refresh related datasources
dataSourceStore.actions.invalidateDataSource(tableId)
await dataSourceStore.actions.invalidateDataSource(tableId)
return res
}

View File

@ -1,4 +1,5 @@
import { writable, get } from "svelte/store"
import { fetchTableDefinition } from "../api"
export const createDataSourceStore = () => {
const store = writable([])
@ -9,43 +10,32 @@ export const createDataSourceStore = () => {
return
}
// Create a list of all relevant dataSource IDs which would require that
// this dataSource is refreshed
let dataSourceIds = []
// Extract the relevant datasource ID for this datasource
let dataSourceId = null
// Extract table ID
if (dataSource.type === "table" || dataSource.type === "view") {
if (dataSource.tableId) {
dataSourceIds.push(dataSource.tableId)
}
dataSourceId = dataSource.tableId
}
// Extract both table IDs from both sides of the relationship
// Only one side of the relationship is required as a trigger, as it will
// automatically invalidate related table IDs
else if (dataSource.type === "link") {
if (dataSource.rowTableId) {
dataSourceIds.push(dataSource.rowTableId)
}
if (dataSource.tableId) {
dataSourceIds.push(dataSource.tableId)
}
dataSourceId = dataSource.tableId || dataSource.rowTableId
}
// Extract the dataSource ID (not the query ID) for queries
else if (dataSource.type === "query") {
if (dataSource.dataSourceId) {
dataSourceIds.push(dataSource.dataSourceId)
}
dataSourceId = dataSource.dataSourceId
}
// Store configs for each relevant dataSource ID
if (dataSourceIds.length) {
if (dataSourceId) {
store.update(state => {
dataSourceIds.forEach(id => {
state.push({
dataSourceId: id,
instanceId,
refresh,
})
state.push({
dataSourceId,
instanceId,
refresh,
})
return state
})
@ -62,13 +52,10 @@ export const createDataSourceStore = () => {
// Invalidates a specific dataSource ID by refreshing all instances
// which depend on data from that dataSource
const invalidateDataSource = dataSourceId => {
const relatedInstances = get(store).filter(instance => {
return instance.dataSourceId === dataSourceId
})
relatedInstances?.forEach(instance => {
instance.refresh()
})
const invalidateDataSource = async dataSourceId => {
if (!dataSourceId) {
return
}
// Emit this as a window event, so parent screens which are iframing us in
// can also invalidate the same datasource
@ -77,6 +64,32 @@ export const createDataSourceStore = () => {
detail: { dataSourceId },
})
)
let invalidations = [dataSourceId]
// Fetch related table IDs from table schema
const definition = await fetchTableDefinition(dataSourceId)
const schema = definition?.schema
if (schema) {
Object.values(schema).forEach(fieldSchema => {
if (fieldSchema.type === "link" && fieldSchema.tableId) {
invalidations.push(fieldSchema.tableId)
}
})
}
// Remove and dupes
invalidations = [...new Set(invalidations)]
// Invalidate all sources
invalidations.forEach(id => {
const relatedInstances = get(store).filter(instance => {
return instance.dataSourceId === id
})
relatedInstances?.forEach(instance => {
instance.refresh()
})
})
}
return {