From e5d1acbdcafc6e1d37c7985ac06d29bb52fb6b63 Mon Sep 17 00:00:00 2001 From: "Simon C. Kessler" Date: Fri, 10 Apr 2026 16:25:09 +0200 Subject: [PATCH] Delete folder getestet --- database/packages/pck_net_storage.pkb | 94 ++++++++++++++++++--------- database/packages/pck_net_storage.pkh | 2 +- 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/database/packages/pck_net_storage.pkb b/database/packages/pck_net_storage.pkb index 390f43f..7ce8f7d 100644 --- a/database/packages/pck_net_storage.pkb +++ b/database/packages/pck_net_storage.pkb @@ -115,18 +115,35 @@ create or replace package body pck_net_storage as -- SCK 2026-04-08 Funktion erstellt ------------------------------------------------------------------------------------------------Kopf*/ is - l_response clob; - l_status number; - l_header_index number := 1; + l_response clob; + l_status number; + l_header_index number := 1; + l_content_length number; begin if i_content_type is not null then - apex_web_service.g_request_headers(l_header_index).name := 'Content-Type'; - apex_web_service.g_request_headers(l_header_index).value := i_content_type; + apex_web_service.g_request_headers(l_header_index).name := 'Content-Type'; + apex_web_service.g_request_headers(l_header_index).value := i_content_type; l_header_index := l_header_index + 1; end if; + -- Content-Length immer mitsenden (OCI-Signing erfordert es bei PUT/POST, + -- 0 bei bodylosem Request ist valide) + if i_body_blob is not null and dbms_lob.getlength(i_body_blob) > 0 + then + l_content_length := dbms_lob.getlength(i_body_blob); + elsif i_body_clob is not null and dbms_lob.getlength(i_body_clob) > 0 + then + l_content_length := dbms_lob.getlength(i_body_clob); + else + l_content_length := 0; + end if; + + apex_web_service.g_request_headers(l_header_index).name := 'Content-Length'; + apex_web_service.g_request_headers(l_header_index).value := l_content_length; + l_header_index := l_header_index + 1; + apex_debug.info('url: ' || i_url); l_response := apex_web_service.make_rest_request( @@ -158,7 +175,7 @@ create or replace package body pck_net_storage as return l_response; end f_make_request; - -- Interne Implementierung ohne Rechteprüfung — wird von f_list_objects und p_delete_folder genutzt + -- Interne Implementierung ohne Rechteprüfung — wird von f_list_objects und p_delete_folder (Leerprüfung) genutzt function f_list_objects_internal ( i_parent_folder in varchar2 ,i_include_subfolders in varchar2 @@ -168,7 +185,7 @@ create or replace package body pck_net_storage as /*Kopf------------------------------------------------------------------------------------------------ -- Beschreibung: Listet Objekte und Unterordner im Bucket ohne Rechte- oder Scope-Prüfung. -- Paginiert automatisch über nextStartWith bis alle Ergebnisse geladen sind. - -- Wird von f_list_objects (öffentlich) und p_delete_folder intern genutzt. + -- Wird von f_list_objects (öffentlich) und p_delete_folder (Leerprüfung) intern genutzt. ------------------------------------------------------------------------------------------------------ -- Parameter: i_parent_folder Ordnerpfad im Bucket (z.B. eingang/) -- i_include_subfolders 'Y' = alle Dateien rekursiv, 'N' = nur direkte Kinder des Ordners @@ -538,50 +555,65 @@ create or replace package body pck_net_storage as ); end p_delete_object; - procedure p_delete_folder (i_parent_folder in varchar2) + procedure p_delete_folder (i_folder_key in varchar2) /*Kopf------------------------------------------------------------------------------------------------ - -- Beschreibung: Löscht rekursiv alle Objekte unterhalb eines Präfixes im OCI Bucket. - -- Pseudo-Ordner (is_folder = Y) werden übersprungen. + -- Beschreibung: Löscht einen leeren Ordner im OCI Bucket. + -- Schlägt fehl, wenn noch Objekte oder Unterordner vorhanden sind. ------------------------------------------------------------------------------------------------------ - -- Parameter: i_parent_folder Ordnerpräfix (z.B. eingang/batch-001/) + -- Parameter: i_folder_key Kompletter Ordner name inkl. Pfad (z.B. eingang/batch-001/) ------------------------------------------------------------------------------------------------------ -- MA Datum Änderung -- SCK 2026-04-08 Prozedur erstellt + -- SCK 2026-04-10 Rekursives Löschen entfernt — Ordner muss leer sein ------------------------------------------------------------------------------------------------Kopf*/ is l_objects t_net_storage_tab; l_response clob; l_obj_path t_object_path; - l_prefix varchar2(1024) := f_normalize_prefix(i_parent_folder); + l_prefix varchar2(1024) := f_normalize_prefix(i_folder_key); + l_count number; begin pck_mitarbeiterrecht.p_hat_recht('ADMIN'); p_assert_allowed(l_prefix); - -- Alle Objekte im Ordner auflisten (rekursiv, alle Tiefen) - --l_objects := f_list_objects_internal( - -- i_parent_folder => l_prefix - -- ,i_include_subfolders => 'Y' - -- ,i_start_with => null - -- ,i_limit => 0 - --); + -- Direkte Kinder prüfen (Dateien und Unterordner) + l_objects := f_list_objects_internal( + i_parent_folder => l_prefix + ,i_include_subfolders => 'N' + ,i_start_with => null + ,i_limit => 0 + ); - -- Nur echte Objekte löschen, keine Pseudo-Ordner - --for rec in (select object_name, is_folder from table(l_objects)) - --loop - -- if rec.is_folder = 'N' - -- then - -- l_response := f_make_request( - -- i_method => 'DELETE' - -- ,i_url => f_build_url(rec.object_name) - -- ); - -- end if; - --end loop; + /* + apex_debug.info('p_delete_folder: prefix=%s, Anzahl gefundene Einträge=%s', l_prefix, l_objects.count); + for i in 1 .. l_objects.count + loop + apex_debug.info(' [%s] key=%s | is_folder=%s', i, l_objects(i).object_key, l_objects(i).is_folder); + end loop; + */ + + -- Den Ordner selbst (object_key = l_prefix) aus der Zählung ausschließen + select count(*) + into l_count + from table(l_objects) + where object_key != l_prefix; + + if l_count > 0 + then + raise_application_error(-20017, 'Ordner ist nicht leer und kann nicht gelöscht werden'); + end if; + + -- Ordner-Objekt selbst löschen + l_response := f_make_request( + i_method => 'DELETE' + ,i_url => f_build_url(l_prefix) + ); l_obj_path := f_split_object_key(l_prefix); pck_log.p_info( i_module => c_log_module ,i_action => 'DELETE_FOLDER' - ,i_message => 'Ordner "' || l_obj_path.filename || '" rekursiv gelöscht | Pfad: ' || l_obj_path.path + ,i_message => 'Ordner "' || l_obj_path.filename || '" gelöscht | Pfad: ' || l_obj_path.path ,i_object_ref => l_prefix ); end p_delete_folder; diff --git a/database/packages/pck_net_storage.pkh b/database/packages/pck_net_storage.pkh index a516343..27fa4d1 100644 --- a/database/packages/pck_net_storage.pkh +++ b/database/packages/pck_net_storage.pkh @@ -41,7 +41,7 @@ create or replace package pck_net_storage as ); procedure p_delete_folder ( - i_parent_folder in varchar2 + i_folder_key in varchar2 ); procedure p_rename_object (