diff --git a/frontend/src/components/SqlEditor.tsx b/frontend/src/components/SqlEditor.tsx index c6ab8e8..21ee80d 100644 --- a/frontend/src/components/SqlEditor.tsx +++ b/frontend/src/components/SqlEditor.tsx @@ -13,6 +13,39 @@ interface SqlEditorProps { height?: string; } +// Cache for table names with 5-minute expiration +interface TableCache { + tables: string[]; + timestamp: number; +} + +const tablesCache = new Map(); +const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds + +const getCachedTables = async (databaseId: string): Promise => { + const cached = tablesCache.get(databaseId); + const now = Date.now(); + + // Return cached data if it exists and is not expired + if (cached && (now - cached.timestamp) < CACHE_DURATION) { + return cached.tables; + } + + // Fetch fresh data + try { + const { data } = await databasesApi.getTables(databaseId); + tablesCache.set(databaseId, { + tables: data.tables, + timestamp: now, + }); + return data.tables; + } catch (error) { + console.error('Failed to fetch table names:', error); + // Return cached data if available, even if expired, as fallback + return cached?.tables || []; + } +}; + export default function SqlEditor({ value, onChange, databaseId, height = '400px' }: SqlEditorProps) { const editorRef = useRef(null); const monacoRef = useRef(null); @@ -57,21 +90,17 @@ export default function SqlEditor({ value, onChange, databaseId, height = '400px { label: 'MIN', kind: monaco.languages.CompletionItemKind.Function, insertText: 'MIN()', range }, ]; - // Fetch table names from database if databaseId is provided + // Fetch table names from database if databaseId is provided (with caching) if (databaseId) { - try { - const { data } = await databasesApi.getTables(databaseId); - const tableSuggestions = data.tables.map(table => ({ - label: table, - kind: monaco.languages.CompletionItemKind.Class, - insertText: table, - detail: 'Table', - range, - })); - suggestions = [...suggestions, ...tableSuggestions]; - } catch (error) { - console.error('Failed to fetch table names:', error); - } + const tables = await getCachedTables(databaseId); + const tableSuggestions = tables.map(table => ({ + label: table, + kind: monaco.languages.CompletionItemKind.Class, + insertText: table, + detail: 'Table', + range, + })); + suggestions = [...suggestions, ...tableSuggestions]; } return { suggestions };