diff --git a/apps/desktop/src/components/sidebar/TreeItem.vue b/apps/desktop/src/components/sidebar/TreeItem.vue index 122a4bbefd..2a63780cb0 100644 --- a/apps/desktop/src/components/sidebar/TreeItem.vue +++ b/apps/desktop/src/components/sidebar/TreeItem.vue @@ -63,7 +63,7 @@ import { resolveDefaultDatabase } from "@/lib/defaultDatabase"; import { canTreeNodeShowExpander, treeItemPaddingLeft, usesFullWidthTreeLabel } from "@/lib/sidebarTreeItemLayout"; import { buildTableSelectSql } from "@/lib/tableSelectSql"; import { clearActiveTableReferencePayload, createTableReferencePayload, createTableReferenceDropEvent, setActiveTableReferencePayload, type QueryEditorTableReferencePayload } from "@/lib/queryEditorTableDrop"; -import { editablePrimaryKeys } from "@/lib/tableEditing"; +import { editablePrimaryKeys, usesSyntheticRowIdKey } from "@/lib/tableEditing"; import { supportsDatabaseCreation, supportsDatabaseSearch, supportsFieldLineage, supportsObjectBrowserTreeNode, supportsSchemaDiagram, supportsSqlFileExecution, supportsTableImport, supportsTableTruncate, supportsTableStructureEditing, usesTreeSchemaMode } from "@/lib/databaseCapabilities"; import { copyNameForTreeNode, objectSourceKindForTreeNode, sidebarSelectionCopyAction, treeNodeRowAction, treeNodeRowDoubleClickAction } from "@/lib/treeNodeClick"; import { formatSqlInsert } from "@/lib/exportFormats"; @@ -700,56 +700,58 @@ async function openData() { const querySchema = connectionObjectTreeQuerySchema(config, node.database, tableSchema); const effectiveDbType = effectiveDatabaseTypeForConnection(config); const limit = settingsStore.editorSettings.pageSize; + let columns: ColumnInfo[] = []; + let primaryKeys: string[] = []; + try { + console.info("[DBX][openData:get-columns:start]", { + traceId, + database: node.database, + schema: querySchema, + table: node.label, + elapsed: elapsed(), + }); + columns = await api.getColumns(node.connectionId, node.database, querySchema, node.label); + primaryKeys = editablePrimaryKeys(effectiveDbType, columns); + console.info("[DBX][openData:get-columns:done]", { + traceId, + columnCount: columns.length, + primaryKeys, + elapsed: elapsed(), + }); + queryStore.setTableMeta(tabId, { + schema: tableSchema, + tableName: node.label, + columns, + primaryKeys, + }); + } catch (error) { + console.warn("[DBX][openData:get-columns:error]", { traceId, elapsed: elapsed(), error }); + } + + const includeRowId = usesSyntheticRowIdKey(effectiveDbType, primaryKeys); + const fallbackOrderColumns = effectiveDbType === "sqlserver" && !primaryKeys.length ? columns.slice(0, 1).map((column) => column.name) : undefined; const sql = await buildTableSelectSql({ databaseType: effectiveDbType, schema: tableSchema, tableName: node.label, - columns: [], - primaryKeys: [], + columns: columns.map((column) => column.name), + primaryKeys, + fallbackOrderColumns, limit, - includeRowId: false, + includeRowId, }); console.info("[DBX][openData:sql-built]", { traceId, - primaryKeys: [], - includeRowId: false, + primaryKeys, + includeRowId, sql, elapsed: elapsed(), }); queryStore.updateSql(tabId, sql); - const loadTableMeta = async () => { - try { - console.info("[DBX][openData:get-columns:start]", { - traceId, - database: node.database, - schema: querySchema, - table: node.label, - elapsed: elapsed(), - }); - const columns = await api.getColumns(node.connectionId, node.database, querySchema, node.label); - console.info("[DBX][openData:get-columns:done]", { - traceId, - columnCount: columns.length, - primaryKeys: columns.filter((column) => column.is_primary_key).map((column) => column.name), - elapsed: elapsed(), - }); - const pks = editablePrimaryKeys(effectiveDbType, columns); - queryStore.setTableMeta(tabId, { - schema: tableSchema, - tableName: node.label, - columns, - primaryKeys: pks, - }); - } catch (error) { - console.warn("[DBX][openData:get-columns:error]", { traceId, elapsed: elapsed(), error }); - } - }; - console.info("[DBX][openData:execute:start]", { traceId, tabId, elapsed: elapsed() }); await queryStore.executeTabSql(tabId, sql); console.info("[DBX][openData:execute:done]", { traceId, tabId, elapsed: elapsed() }); - void loadTableMeta(); } catch (e: any) { console.error("[DBX][openData:error]", { traceId, elapsed: elapsed(), error: e }); queryStore.setErrorResult(tabId, e); diff --git a/crates/dbx-core/src/db/mysql.rs b/crates/dbx-core/src/db/mysql.rs index 9bcaf6871b..5e55319152 100644 --- a/crates/dbx-core/src/db/mysql.rs +++ b/crates/dbx-core/src/db/mysql.rs @@ -1325,7 +1325,7 @@ fn fix_potential_double_encoding(s: &str) -> String { pub async fn get_columns(pool: &MySqlPool, database: &str, table: &str) -> Result, String> { let sql = columns_sql(database, table); - let mut conn = pool.get_conn().await.map_err(|e| e.to_string())?; + let mut conn = get_conn_with_health_check(pool).await?; let result = match conn.query_iter(&sql).await { Ok(result) => result, Err(err) => { @@ -1375,7 +1375,7 @@ pub async fn get_columns(pool: &MySqlPool, database: &str, table: &str) -> Resul pub async fn get_columns_show(pool: &MySqlPool, database: &str, table: &str) -> Result, String> { let sql = show_columns_sql(database, table, true); - let mut conn = pool.get_conn().await.map_err(|e| e.to_string())?; + let mut conn = get_conn_with_health_check(pool).await?; let rows: Vec = match conn.query_iter(&sql).await { Ok(result) => result.collect_and_drop().await.map_err(|e| e.to_string())?, Err(_) => {