import { useCallback, useEffect, useState } from 'react' import { Database, Loader2, Play, Zap } from 'lucide-react' import type { SourceEngine } from '../../lib/dataSourceCatalog' import { cn } from '../../lib/utils' import { subTabActive, subTabIdle } from '../../lib/tabActive' type Sample = { id: string; label: string; sql: string } type SqlResult = { ok: boolean columns?: string[] rows?: unknown[][] row_count?: number elapsed_ms?: number error?: string sql?: string } type Engine = SourceEngine | 'trino' type Props = { engine: Engine compact?: boolean } const ENGINE_META: Record = { postgres: { title: 'PostgreSQL SQL Console', sub: 'DB Vault · 10.0.21.51:5432 · user mo', accent: 'text-sky-400', queryLabel: 'SQL', }, mysql: { title: 'MySQL SQL Console', sub: 'DB Vault · 10.0.21.51:3306 · database hr · user mo', accent: 'text-amber-400', queryLabel: 'SQL', }, mongodb: { title: 'MongoDB Query Console', sub: 'DB Vault · 10.0.21.51:27017 · supplychain', accent: 'text-emerald-400', queryLabel: 'Command', }, cassandra: { title: 'Cassandra CQL Console', sub: 'DB Vault · 10.0.21.51:9042 · keyspace telemetry', accent: 'text-cyan-400', queryLabel: 'CQL', }, neo4j: { title: 'Neo4j Cypher Console', sub: 'DB Vault · 10.0.21.51:7687 · graph database', accent: 'text-pink-400', queryLabel: 'Cypher', }, trino: { title: 'Trino SQL Console', sub: 'Lakehouse · 10.0.21.50:8089 · federated queries', accent: 'text-violet-400', queryLabel: 'SQL', }, } export function SqlWorkbench({ engine, compact }: Props) { const meta = ENGINE_META[engine] const [samples, setSamples] = useState([]) const [sql, setSql] = useState('') const [result, setResult] = useState(null) const [benchmark, setBenchmark] = useState<{ comparison?: { postgres_ms?: number; trino_ms?: number; faster?: string; speedup_factor?: number } } | null>(null) const [loading, setLoading] = useState(false) const [benchLoading, setBenchLoading] = useState(false) const [error, setError] = useState(null) const loadSamples = useCallback(async () => { const r = await fetch(`/api/sql/samples/${engine}`) if (r.ok) { const j = await r.json() setSamples(j.samples || []) if (j.samples?.[0]) setSql(j.samples[0].sql) } }, [engine]) useEffect(() => { loadSamples() setResult(null) setBenchmark(null) setError(null) }, [engine, loadSamples]) const run = async (query?: string) => { const q = (query ?? sql).trim() if (!q) return setLoading(true) setError(null) try { const r = await fetch('/api/sql/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ engine, sql: q }), }) const j = await r.json() if (!r.ok || !j.ok) { setError(j.error || 'Query failed') setResult(null) return } setSql(q) setResult(j) } catch { setError('SQL API unavailable') } finally { setLoading(false) } } const runBenchmark = async () => { setBenchLoading(true) setError(null) try { const r = await fetch('/api/sql/benchmark', { method: 'POST' }) const j = await r.json() if (!r.ok) { setError(j.error || 'Benchmark failed') return } setBenchmark(j) } catch { setError('Benchmark failed') } finally { setBenchLoading(false) } } return (

{meta.title}

{meta.sub}

{(engine === 'postgres' || engine === 'trino') && ( )}