diff --git a/apps/desktop/src/components/objects/ObjectSourceDialog.vue b/apps/desktop/src/components/objects/ObjectSourceDialog.vue index 9d79d23f5..c871deb6d 100644 --- a/apps/desktop/src/components/objects/ObjectSourceDialog.vue +++ b/apps/desktop/src/components/objects/ObjectSourceDialog.vue @@ -9,9 +9,11 @@ import { copyToClipboard } from "@/lib/common/clipboard"; import { formatSqlForDisplay, type SqlFormatDialect } from "@/lib/sql/sqlFormatter"; import { buildEditableObjectSource, buildExecutableObjectSourceStatements, executeObjectSourceSave, formatObjectSourceSaveError } from "@/lib/table/objectSourceEditor"; import { loadObjectSourceWithRoutineFallback } from "@/lib/table/objectSourceLoad"; +import { xuguRoutineMetadataFromDefinition, type XuguRoutineMetadata } from "@/lib/table/routineParameters"; import { executeWithProductionSqlGuard } from "@/lib/database/productionExecutionGuard"; import * as api from "@/lib/backend/api"; import QueryEditor from "@/components/editor/QueryEditor.vue"; +import RoutineMetadataPanel from "@/components/objects/RoutineMetadataPanel.vue"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import type { DatabaseType, ObjectSourceKind } from "@/types/database"; @@ -55,12 +57,14 @@ const editing = ref(false); const sourceEditable = ref(true); const error = ref(""); const saveError = ref(""); +const routineMetadata = ref(null); /** May differ from props.objectType after PROCEDURE/FUNCTION/PACKAGE fallback resolution. */ const resolvedObjectType = ref(props.objectType); let loadSerial = 0; const canEdit = computed(() => sourceEditable.value && props.objectType !== "SEQUENCE"); const title = computed(() => `${editing.value ? t("contextMenu.editView") : t("contextMenu.viewSource")} - ${props.name}`); +const hasRoutineMetadata = computed(() => !!routineMetadata.value && (routineMetadata.value.parameters.length > 0 || !!routineMetadata.value.returnType)); watch( () => [props.open, props.connectionId, props.database, props.schema, props.name, props.relationName, props.signature, props.objectType, props.initialEditing] as const, @@ -77,6 +81,7 @@ async function loadSource(nextEditing = props.initialEditing && canEdit.value) { draft.value = ""; error.value = ""; saveError.value = ""; + routineMetadata.value = null; sourceEditable.value = true; editing.value = false; loading.value = true; @@ -94,6 +99,7 @@ async function loadSource(nextEditing = props.initialEditing && canEdit.value) { }); if (serial !== loadSerial) return; resolvedObjectType.value = resolvedType; + routineMetadata.value = props.databaseType === "xugu" && (resolvedType === "PROCEDURE" || resolvedType === "FUNCTION") ? xuguRoutineMetadataFromDefinition(result.source) : null; sourceEditable.value = editableAllowed; const formatted = await formatSqlForDisplay(editable, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter); editableText.value = editable; @@ -221,22 +227,24 @@ function closeDialog() { {{ saveError }} - +
+ + +
diff --git a/apps/desktop/src/components/objects/ProcedureExecutionDialog.vue b/apps/desktop/src/components/objects/ProcedureExecutionDialog.vue index fae74751e..d2c5ab0ef 100644 --- a/apps/desktop/src/components/objects/ProcedureExecutionDialog.vue +++ b/apps/desktop/src/components/objects/ProcedureExecutionDialog.vue @@ -52,7 +52,8 @@ const generatedSql = computed(() => { }); const inputParameterCount = computed(() => parameters.value.filter(acceptsRoutineInput).length); -const outputParameterCount = computed(() => parameters.value.filter((parameter) => parameter.mode === "OUT").length); +const outputParameterCount = computed(() => parameters.value.filter((parameter) => parameter.mode === "OUT" || (props.databaseType === "xugu" && parameter.mode === "INOUT")).length); +const isXugu = computed(() => props.databaseType === "xugu"); watch( () => [open.value, props.connectionId, props.database, props.databaseType, props.schema, props.routineName] as const, @@ -134,6 +135,11 @@ function execute() { function canEditParameter(parameter: RoutineParameterValue): boolean { return acceptsRoutineInput(parameter); } + +function displayParameterDefault(parameter: RoutineParameterValue): string { + if (!parameter.hasDefault) return "-"; + return parameter.defaultValue?.trim() || "DEFAULT"; +}