diff --git a/src/store/app.ts b/src/store/app.ts index a3484bd..76ad263 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -16,6 +16,7 @@ export const useAppStore = defineStore('app', { carton_map: {}, db_info: {}, flat_db: {}, + dbkey_lookup: {}, theme: '', aladin: null, result_targs: [] @@ -80,13 +81,56 @@ export const useAppStore = defineStore('app', { return this.logged_in || (!this.logged_in && this.release.startsWith("DR")) }, - get_field_from_db(column: string, field: string) { - // looks up a db column description from the flattened db metadata + get_obj_from_db(column: string, context: Object = {}) { + // lookup the db metadata object for a column + + // get all possible keys for the column name + const default_val = {} + const possibleKeys = this.dbkey_lookup[column] + + if (!possibleKeys || possibleKeys.length === 0) { + // Column name not found in metadata + return default_val + } else if (possibleKeys.length === 1) { + // Unique column name, retrieve metadata directly + const fullKey = possibleKeys[0] + return this.flat_db[fullKey] || default_val + } else { + // Ambiguous column name + // Use context to resolve ambiguity + const { schema, table } = context; + + let filteredKeys = possibleKeys; + + if (schema) { + filteredKeys = filteredKeys.filter(key => key.startsWith(`${schema}.`)); + } + + if (table) { + filteredKeys = filteredKeys.filter(key => key.includes(`.${table}.`)); + } + + if (filteredKeys.length === 1) { + const fullKey = filteredKeys[0]; + return this.flat_db[fullKey] || default_val; + } else if (filteredKeys.length > 1) { + // Still ambiguous after applying context + // return first match + return this.flat_db[filteredKeys[0]] || default_val; + } else { + // No matching keys after applying context + return default_val; + } + } + }, - // set default value to the column name if the field is display_name, otherwise null - let default_val = (this.flat_db[column] === undefined && field === 'display_name') ? column : null + get_field_from_db(column: string, field: string, context: Object = {}) { + // looks up a db column field from the flattened db metadata object - return this.flat_db[column] ? this.flat_db[column][field] : default_val; + // set default value to the column name if the field is display_name, otherwise null + const default_val = field === 'display_name' ? column : null; + const mapping = this.get_obj_from_db(column, context); + return mapping[field] || default_val; }, set_result_data(data: any) { @@ -107,9 +151,27 @@ export const useAppStore = defineStore('app', { .then((response) => { // store the db metadata this.db_info = response.data - - // flatten the db_info object - this.flat_db = Object.fromEntries(Object.entries(this.db_info).flatMap(([schema, table])=>Object.entries(table))) + console.log('db info loaded', this.db_info) + + // flatten the db_info object, prefix schema to table.colum keys + this.flat_db = Object.fromEntries( + Object.entries(this.db_info).flatMap(([schema, table]) => + Object.entries(table).map(([key, value]) => [`${schema}.${key}`, value]) + ) + ) + + // preprocess the flattened metadata to create an index + // of column names to any resolved schema.table.column key names + this.dbkey_lookup = {}; + + for (const fullKey in this.flat_db) { + const parts = fullKey.split('.'); + const columnName = parts[2]; + if (!this.dbkey_lookup[columnName]) { + this.dbkey_lookup[columnName] = []; + } + this.dbkey_lookup[columnName].push(fullKey); + } }) .catch((error) => { diff --git a/src/views/Results.vue b/src/views/Results.vue index e08199a..3603db7 100644 --- a/src/views/Results.vue +++ b/src/views/Results.vue @@ -327,7 +327,7 @@ onMounted(() => { msg.value = 'No search results returned' } else { data.value = results - headers.value = Object.entries(data.value[0]).map((item)=> ({title: store.get_field_from_db(item[0], 'display_name'), key: item[0], type: typeof item[1], description: store.get_field_from_db(item[0], 'description')})) + headers.value = Object.entries(data.value[0]).map((item)=> ({title: store.get_field_from_db(item[0], 'display_name', {'schema': 'vizdb'}), key: item[0], type: typeof item[1], description: store.get_field_from_db(item[0], 'description', {'schema': 'vizdb'})})) console.log('data', data.value) console.log('headers', headers.value) diff --git a/src/views/Target.vue b/src/views/Target.vue index fbec04e..2ffb066 100644 --- a/src/views/Target.vue +++ b/src/views/Target.vue @@ -243,16 +243,13 @@ function convert_object( metadata) { function convert_to_table(dataObject, name) { // convert target data to v-data-table items with db metadata - let mappingObject = store.db_info[name] return Object.entries(dataObject).map(([key, value]) => { - //const mapping = Object.values(mappingObject).find(db => db[key])?.[key]; - const mapping = mappingObject[key] + const mapping = store.get_obj_from_db(key, {'schema': name}) return { display_name: mapping?.display_name || '', column_name: mapping?.column_name || key, value: value, description: mapping?.description || '' - } }) }