@@ -12,7 +12,9 @@ import { get } from 'lodash';
1212import { setMetadataHash } from '../state/settings/reducer' ;
1313import { getState } from '../state/store' ;
1414import { dispatch } from '../state/dispatch' ;
15- import { getAllCards , getDatabaseTablesAndModelsWithoutFields } from '../../../apps/src/metabase/helpers/metabaseAPIHelpers' ;
15+ import { getAllCards , getAllCardsLegacy , getDatabaseTablesAndModelsWithoutFields , getAllFields } from '../../../apps/src/metabase/helpers/metabaseAPIHelpers' ;
16+ import { fetchDatabaseFields } from '../../../apps/src/metabase/helpers/metabaseAPI' ;
17+ import { getSelectedDbId } from '../../../apps/src/metabase/helpers/metabaseStateAPI' ;
1618
1719export interface MetadataItem {
1820 metadata_type : string ;
@@ -149,11 +151,93 @@ async function processMetadataWithCaching(
149151 return currentHash
150152}
151153
152- export async function processCards ( ) {
153- return await processMetadataWithCaching ( 'cards' , getAllCards )
154- }
155-
156- export async function processDBSchema ( ) {
157- return await processMetadataWithCaching ( 'dbSchema' , getDatabaseTablesAndModelsWithoutFields )
154+ export async function processAllMetadata ( ) {
155+ console . log ( '[minusx] Starting coordinated metadata processing with parallel API calls...' )
156+
157+ // Step 1: Start all expensive API calls in parallel
158+ console . log ( '[minusx] Initiating parallel API calls...' )
159+ const selectedDbId = await getSelectedDbId ( )
160+
161+ if ( ! selectedDbId ) {
162+ throw new Error ( 'No database selected for metadata processing' )
163+ }
164+
165+ const [ dbSchema , { cards, tables : referencedTables } , allFields ] = await Promise . all ( [
166+ getDatabaseTablesAndModelsWithoutFields ( ) ,
167+ getAllCards ( ) ,
168+ fetchDatabaseFields ( { db_id : selectedDbId } )
169+ ] )
170+
171+ console . log ( '[minusx] All API calls completed. Processing data...' )
172+
173+ // Step 2: Create sets for efficient lookup of existing tables
174+ const existingTableNames = new Set < string > ( )
175+
176+ // Add tables from dbSchema
177+ if ( dbSchema . tables ) {
178+ dbSchema . tables . forEach ( ( table : any ) => {
179+ const tableName = table . name
180+ const schemaName = table . schema || dbSchema . default_schema
181+ const fullName = schemaName ? `${ schemaName } .${ tableName } ` : tableName
182+
183+ existingTableNames . add ( tableName )
184+ existingTableNames . add ( fullName )
185+ } )
186+ }
187+
188+ // Add models from dbSchema
189+ if ( dbSchema . models ) {
190+ dbSchema . models . forEach ( ( model : any ) => {
191+ existingTableNames . add ( model . name )
192+ } )
193+ }
194+
195+ console . log ( '[minusx] Found existing tables/models:' , existingTableNames . size )
196+
197+ // Step 3: Find intersection of referenced tables that actually exist
198+ const validReferencedTables = referencedTables . filter ( ( table : any ) => {
199+ const tableName = table . name
200+ const schemaName = table . schema
201+ const fullName = schemaName ? `${ schemaName } .${ tableName } ` : tableName
202+
203+ return existingTableNames . has ( tableName ) || existingTableNames . has ( fullName )
204+ } )
205+
206+ console . log ( '[minusx] Valid referenced tables:' , validReferencedTables . length , 'out of' , referencedTables . length )
207+
208+ // Step 4: Filter fields in-memory using table names
209+ const validTableNames = new Set ( validReferencedTables . map ( ( table : any ) => {
210+ const schemaName = table . schema
211+ return schemaName ? `${ schemaName } .${ table . name } ` : table . name
212+ } ) )
213+
214+ console . log ( '[minusx] Filtering fields for' , validTableNames . size , 'valid tables...' )
215+
216+ const filteredFields = allFields . filter ( ( field : any ) => {
217+ const tableName = get ( field , 'table_name' )
218+ const tableSchema = get ( field , 'schema' )
219+ const fullTableName = tableSchema ? `${ tableSchema } .${ tableName } ` : tableName
220+
221+ return validTableNames . has ( tableName ) || validTableNames . has ( fullTableName )
222+ } )
223+
224+ console . log ( '[minusx] Fields after filtering:' , filteredFields . length , 'out of' , allFields . length )
225+
226+ // Step 5: Process metadata for all three with filtered data
227+ console . log ( '[minusx] Processing metadata with filtered data...' )
228+
229+ const [ cardsHash , dbSchemaHash , fieldsHash ] = await Promise . all ( [
230+ processMetadataWithCaching ( 'cards' , async ( ) => cards ) ,
231+ processMetadataWithCaching ( 'dbSchema' , async ( ) => dbSchema ) ,
232+ processMetadataWithCaching ( 'fields' , async ( ) => filteredFields )
233+ ] )
234+
235+ console . log ( '[minusx] Coordinated metadata processing complete' )
236+
237+ return {
238+ cardsHash,
239+ dbSchemaHash,
240+ fieldsHash
241+ }
158242}
159243
0 commit comments