mirror of
https://github.com/t8y2/dbx.git
synced 2026-11-01 08:26:35 +00:00
fix(oracle): 修复表数据加载与编辑
This commit is contained in:
@@ -3,6 +3,7 @@ import { useI18n } from "vue-i18n";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { buildTableSelectSql, quoteTableIdentifier } from "@/lib/tableSelectSql";
|
||||
import { editablePrimaryKeys, usesSyntheticRowIdKey } from "@/lib/tableEditing";
|
||||
import { buildSortedQuerySql } from "@/lib/queryResultSort";
|
||||
import type { QueryTab } from "@/types/database";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
@@ -23,16 +24,22 @@ export function useDataGridActions(activeTab: ComputedRef<QueryTab | undefined>)
|
||||
options: { orderBy?: string; limit?: number; offset?: number; whereInput?: string } = {},
|
||||
): string {
|
||||
const config = connectionStore.getConfig(tab.connectionId);
|
||||
const primaryKeys = tab.tableMeta ? editablePrimaryKeys(config?.db_type, tab.tableMeta.columns) : [];
|
||||
if (tab.tableMeta && primaryKeys.join("\0") !== tab.tableMeta.primaryKeys.join("\0")) {
|
||||
tab.tableMeta.primaryKeys = primaryKeys;
|
||||
}
|
||||
const fallbackOrderColumns =
|
||||
config?.db_type === "sqlserver" && !tab.tableMeta?.primaryKeys?.length
|
||||
config?.db_type === "sqlserver" && !primaryKeys.length
|
||||
? tab.tableMeta?.columns.slice(0, 1).map((column) => column.name)
|
||||
: undefined;
|
||||
const useRowId = usesSyntheticRowIdKey(config?.db_type, primaryKeys);
|
||||
return buildTableSelectSql({
|
||||
databaseType: config?.db_type,
|
||||
schema: tab.tableMeta?.schema,
|
||||
tableName: tab.tableMeta?.tableName ?? "",
|
||||
primaryKeys: tab.tableMeta?.primaryKeys,
|
||||
primaryKeys,
|
||||
fallbackOrderColumns,
|
||||
includeRowId: useRowId,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { ref, computed, nextTick, type ComputedRef, type Ref } from "vue";
|
||||
import * as api from "@/lib/api";
|
||||
import { buildDataGridRollbackStatements, buildDataGridSaveStatements } from "@/lib/dataGridSql";
|
||||
import {
|
||||
buildDataGridRollbackStatements,
|
||||
buildDataGridSaveStatements,
|
||||
dataGridSaveExecutionSchema,
|
||||
validateDataGridSave,
|
||||
} from "@/lib/dataGridSql";
|
||||
import { rowStatusFilterAfterAddingRow, type RowStatusFilter } from "@/lib/gridRowStatus";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useHistoryStore } from "@/stores/historyStore";
|
||||
@@ -59,6 +64,7 @@ export interface UseDataGridEditorOptions {
|
||||
whereFilterInput: Ref<string>;
|
||||
orderByInput: Ref<string>;
|
||||
rowStatusFilter: Ref<RowStatusFilter>;
|
||||
initialEditColumn?: ComputedRef<number>;
|
||||
getRowItem: (rowId: number) => RowItem | undefined;
|
||||
emit: {
|
||||
(event: "reload", sql?: string, searchText?: string, whereInput?: string, orderBy?: string): void;
|
||||
@@ -83,6 +89,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
whereFilterInput,
|
||||
orderByInput,
|
||||
rowStatusFilter,
|
||||
initialEditColumn,
|
||||
getRowItem,
|
||||
emit,
|
||||
} = options;
|
||||
@@ -342,7 +349,7 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
nextTick(() => {
|
||||
const el = getScrollerElement();
|
||||
if (el) el.scrollTop = el.scrollHeight;
|
||||
startEdit(rowId, 0);
|
||||
startEdit(rowId, initialEditColumn?.value ?? 0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -484,6 +491,21 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
}
|
||||
|
||||
const stmtOptions = saveStatementOptions();
|
||||
const validationError = stmtOptions
|
||||
? validateDataGridSave({
|
||||
databaseType: databaseType.value,
|
||||
columns: stmtOptions.columns,
|
||||
columnInfo: tableMeta.value?.columns,
|
||||
dirtyRows: stmtOptions.dirtyRows,
|
||||
newRows: stmtOptions.newRows,
|
||||
})
|
||||
: undefined;
|
||||
if (validationError) {
|
||||
saveError.value = validationError;
|
||||
isSaving.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const stmts = stmtOptions ? buildDataGridSaveStatements(stmtOptions) : [];
|
||||
if (stmts.length === 0) {
|
||||
isSaving.value = false;
|
||||
@@ -492,10 +514,23 @@ export function useDataGridEditor(options: UseDataGridEditorOptions) {
|
||||
const rollbackStmts = stmtOptions ? buildDataGridRollbackStatements(stmtOptions) : [];
|
||||
const start = Date.now();
|
||||
let apiResult: { affected_rows?: number } | undefined;
|
||||
console.info("[DBX][dataGrid:save-statements]", {
|
||||
databaseType: databaseType.value,
|
||||
table: tableMeta.value
|
||||
? [tableMeta.value.schema, tableMeta.value.tableName].filter(Boolean).join(".")
|
||||
: undefined,
|
||||
statements: stmts,
|
||||
rollbackStatements: rollbackStmts,
|
||||
});
|
||||
|
||||
if (useTransaction.value && connectionId.value && database.value) {
|
||||
try {
|
||||
apiResult = await api.executeInTransaction(connectionId.value, database.value, stmts, tableMeta.value?.schema);
|
||||
apiResult = await api.executeInTransaction(
|
||||
connectionId.value,
|
||||
database.value,
|
||||
stmts,
|
||||
dataGridSaveExecutionSchema(databaseType.value, tableMeta.value),
|
||||
);
|
||||
} catch (e: any) {
|
||||
saveError.value = String(e.message || e);
|
||||
isSaving.value = false;
|
||||
|
||||
@@ -32,7 +32,9 @@ export interface UseDataGridExportOptions {
|
||||
databaseType: ComputedRef<string | undefined>;
|
||||
hasCellSelection: ComputedRef<boolean>;
|
||||
selectedCells: ComputedRef<SelectionData>;
|
||||
contextCell: Ref<{ rowId: number; rowIndex: number; col: number } | null>;
|
||||
contextCell:
|
||||
| Ref<{ rowId: number; rowIndex: number; col: number } | null>
|
||||
| ComputedRef<{ rowId: number; rowIndex: number; col: number } | null>;
|
||||
getRowItem: (rowId: number) => RowItem | undefined;
|
||||
formatCell: (value: CellValue) => string;
|
||||
quoteIdent: (name: string) => string;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as api from "@/lib/api";
|
||||
import { buildTableSelectSql } from "@/lib/tableSelectSql";
|
||||
import { editablePrimaryKeys, usesSyntheticRowIdKey } from "@/lib/tableEditing";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
|
||||
@@ -44,12 +45,26 @@ async function openTableTarget(target: NavigationTarget) {
|
||||
const [columnsResult, dataResult] = await Promise.allSettled([columnsPromise, dataPromise]);
|
||||
if (columnsResult.status === "fulfilled") {
|
||||
const columns = columnsResult.value;
|
||||
const primaryKeys = editablePrimaryKeys(config.db_type, columns);
|
||||
const useRowId = usesSyntheticRowIdKey(config.db_type, primaryKeys);
|
||||
queryStore.setTableMeta(tabId, {
|
||||
schema: target.schema,
|
||||
tableName: target.tableName,
|
||||
columns,
|
||||
primaryKeys: columns.filter((c) => c.is_primary_key).map((c) => c.name),
|
||||
primaryKeys,
|
||||
});
|
||||
if (useRowId) {
|
||||
const newSql = buildTableSelectSql({
|
||||
databaseType: config.db_type,
|
||||
schema: target.schema,
|
||||
tableName: target.tableName,
|
||||
whereInput: target.whereInput,
|
||||
primaryKeys,
|
||||
includeRowId: true,
|
||||
});
|
||||
queryStore.updateSql(tabId, newSql);
|
||||
await queryStore.executeTabSql(tabId, newSql);
|
||||
}
|
||||
}
|
||||
if (dataResult.status === "rejected") throw dataResult.reason;
|
||||
if (columnsResult.status === "rejected")
|
||||
@@ -107,7 +122,7 @@ export function useNavigationTargets(dialogs: {
|
||||
queryStore.setTableMeta(activeTab.id, {
|
||||
...activeTab.tableMeta,
|
||||
columns,
|
||||
primaryKeys: columns.filter((c) => c.is_primary_key).map((c) => c.name),
|
||||
primaryKeys: editablePrimaryKeys(connectionStore.getConfig(activeTab.connectionId)?.db_type, columns),
|
||||
});
|
||||
await reloadData();
|
||||
} catch (e: any) {
|
||||
|
||||
Reference in New Issue
Block a user