2021-03-16 14:54:34 +01:00
|
|
|
import { writable, get } from "svelte/store"
|
2021-10-26 20:12:55 +02:00
|
|
|
import { fetchTableDefinition } from "../api"
|
2021-11-08 18:25:05 +01:00
|
|
|
import { FieldTypes } from "../constants"
|
2021-03-16 14:54:34 +01:00
|
|
|
|
|
|
|
export const createDataSourceStore = () => {
|
|
|
|
const store = writable([])
|
|
|
|
|
|
|
|
// Registers a new dataSource instance
|
|
|
|
const registerDataSource = (dataSource, instanceId, refresh) => {
|
|
|
|
if (!dataSource || !instanceId || !refresh) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-10-26 20:12:55 +02:00
|
|
|
// Extract the relevant datasource ID for this datasource
|
|
|
|
let dataSourceId = null
|
2021-03-16 14:54:34 +01:00
|
|
|
|
|
|
|
// Extract table ID
|
|
|
|
if (dataSource.type === "table" || dataSource.type === "view") {
|
2021-10-26 20:12:55 +02:00
|
|
|
dataSourceId = dataSource.tableId
|
2021-03-16 14:54:34 +01:00
|
|
|
}
|
|
|
|
|
2021-10-26 20:12:55 +02:00
|
|
|
// Only one side of the relationship is required as a trigger, as it will
|
|
|
|
// automatically invalidate related table IDs
|
2021-11-08 18:25:05 +01:00
|
|
|
else if (dataSource.type === FieldTypes.LINK) {
|
2021-10-26 20:12:55 +02:00
|
|
|
dataSourceId = dataSource.tableId || dataSource.rowTableId
|
2021-03-16 14:54:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Extract the dataSource ID (not the query ID) for queries
|
|
|
|
else if (dataSource.type === "query") {
|
2021-10-26 20:12:55 +02:00
|
|
|
dataSourceId = dataSource.dataSourceId
|
2021-03-16 14:54:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Store configs for each relevant dataSource ID
|
2021-10-26 20:12:55 +02:00
|
|
|
if (dataSourceId) {
|
2021-05-04 12:32:22 +02:00
|
|
|
store.update(state => {
|
2021-10-26 20:12:55 +02:00
|
|
|
state.push({
|
|
|
|
dataSourceId,
|
|
|
|
instanceId,
|
|
|
|
refresh,
|
2021-03-16 14:54:34 +01:00
|
|
|
})
|
|
|
|
return state
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Removes all registered dataSource instances belonging to a particular
|
|
|
|
// instance ID
|
2021-05-04 12:32:22 +02:00
|
|
|
const unregisterInstance = instanceId => {
|
|
|
|
store.update(state => {
|
|
|
|
return state.filter(instance => instance.instanceId !== instanceId)
|
2021-03-16 14:54:34 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invalidates a specific dataSource ID by refreshing all instances
|
|
|
|
// which depend on data from that dataSource
|
2021-10-26 20:12:55 +02:00
|
|
|
const invalidateDataSource = async dataSourceId => {
|
|
|
|
if (!dataSourceId) {
|
|
|
|
return
|
|
|
|
}
|
2021-07-30 15:01:01 +02:00
|
|
|
|
|
|
|
// Emit this as a window event, so parent screens which are iframing us in
|
|
|
|
// can also invalidate the same datasource
|
2021-11-04 17:28:07 +01:00
|
|
|
window.parent.postMessage({
|
|
|
|
type: "close-screen-modal",
|
|
|
|
detail: { dataSourceId },
|
|
|
|
})
|
2021-10-26 20:12:55 +02:00
|
|
|
|
|
|
|
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 => {
|
2021-10-27 09:37:51 +02:00
|
|
|
if (
|
2021-11-08 18:25:05 +01:00
|
|
|
fieldSchema.type === FieldTypes.LINK &&
|
2021-10-27 09:37:51 +02:00
|
|
|
fieldSchema.tableId &&
|
|
|
|
!fieldSchema.autocolumn
|
|
|
|
) {
|
2021-10-26 20:12:55 +02:00
|
|
|
invalidations.push(fieldSchema.tableId)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-10-27 09:37:51 +02:00
|
|
|
// Remove any dupes
|
2021-10-26 20:12:55 +02:00
|
|
|
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()
|
|
|
|
})
|
|
|
|
})
|
2021-03-16 14:54:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
subscribe: store.subscribe,
|
|
|
|
actions: { registerDataSource, unregisterInstance, invalidateDataSource },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const dataSourceStore = createDataSourceStore()
|