create or replace PACKAGE CT_MRDS.ENV_MANAGER AUTHID CURRENT_USER AS /** * General comment for package: Please put comments for functions and procedures as shown in below example. * It is a standard. * The structure of comment is used by GET_PACKAGE_DOCUMENTATION function * which returns documentation text for confluence page (to Copy-Paste it). **/ -- Example comment: /** * @name EX_PROCEDURE_NAME * @desc Procedure description * @example select ENV_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual; * @ex_rslt Example Result **/ -- Package Version Information (Semantic Versioning: MAJOR.MINOR.PATCH) PACKAGE_VERSION CONSTANT VARCHAR2(10) := '3.2.0'; PACKAGE_BUILD_DATE CONSTANT VARCHAR2(20) := '2025-12-20 10:00:00'; PACKAGE_AUTHOR CONSTANT VARCHAR2(100) := 'Grzegorz Michalski'; -- Version History (Latest changes first) VERSION_HISTORY CONSTANT VARCHAR2(4000) := '3.2.0 (2025-12-20): Added error codes for parallel execution support (CODE_INVALID_PARALLEL_DEGREE -20110, CODE_PARALLEL_EXECUTION_FAILED -20111)' || CHR(13)||CHR(10) || '3.1.0 (2025-10-22): Added package hash tracking and automatic change detection system (SHA256 hashing)' || CHR(13)||CHR(10) || '3.0.0 (2025-10-22): Added package versioning system with centralized version management functions' || CHR(13)||CHR(10) || '2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function for comprehensive CSV validation analysis' || CHR(13)||CHR(10) || '2.0.0 (2025-10-01): Added LOG_PROCESS_ERROR procedure with enhanced error diagnostics and stack traces' || CHR(13)||CHR(10) || '1.5.0 (2025-09-20): Added console logging support with gvConsoleLoggingEnabled configuration' || CHR(13)||CHR(10) || '1.0.0 (2025-09-01): Initial release with error management and configuration system'; TYPE Error_Record IS RECORD ( code PLS_INTEGER, message VARCHAR2(4000) ); TYPE tErrorList IS TABLE OF Error_Record INDEX BY PLS_INTEGER; Errors tErrorList; guid VARCHAR2(32); gvEnv VARCHAR2(200); gvUsername VARCHAR2(128); gvOsuser VARCHAR2(128); gvMachine VARCHAR2(64); gvModule VARCHAR2(64); gvNameSpace VARCHAR2(200); gvRegion VARCHAR2(200); gvDataBucketName VARCHAR2(200); gvInboxBucketName VARCHAR2(200); gvArchiveBucketName VARCHAR2(200); gvDataBucketUri VARCHAR2(200); gvInboxBucketUri VARCHAR2(200); gvArchiveBucketUri VARCHAR2(200); gvCredentialName VARCHAR2(200); -- Overwritten by variable "LoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table gvLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF' -- Overwritten by variable "MinLogLevel" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table -- Possible values: DEBUG ,INFO ,WARNING ,ERROR gvMinLogLevel VARCHAR2(10) := 'DEBUG'; -- Overwritten by variable "DefaultDateFormat" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table gvDefaultDateFormat VARCHAR2(200) := 'DD/MM/YYYY HH24:MI:SS'; -- Overwritten by variable "ConsoleLoggingEnabled" in A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table gvConsoleLoggingEnabled VARCHAR2(3) := 'ON'; -- 'ON' or 'OFF' cgBL CONSTANT VARCHAR2(2) := CHR(13)||CHR(10); vgSourceFileConfigKey PLS_INTEGER; vgMsgTmp VARCHAR2(32000); --Exceptions ERR_EMPTY_FILEURI_AND_RECKEY EXCEPTION; CODE_EMPTY_FILEURI_AND_RECKEY CONSTANT PLS_INTEGER := -20001; MSG_EMPTY_FILEURI_AND_RECKEY VARCHAR2(4000) := 'Either pFileUri or pSourceFileReceivedKey must be not null'; PRAGMA EXCEPTION_INIT( ERR_EMPTY_FILEURI_AND_RECKEY ,CODE_EMPTY_FILEURI_AND_RECKEY); ERR_NO_CONFIG_MATCH_FOR_FILEURI EXCEPTION; CODE_NO_CONFIG_MATCH_FOR_FILEURI CONSTANT PLS_INTEGER := -20002; MSG_NO_CONFIG_MATCH_FOR_FILEURI VARCHAR2(4000) := 'No match for source file in A_SOURCE_FILE_CONFIG table' ||cgBL||' The file provided in parameter: pFileUri does not have ' ||cgBL||' coresponding configuration in A_SOURCE_FILE_CONFIG table'; PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH_FOR_FILEURI ,CODE_NO_CONFIG_MATCH_FOR_FILEURI); ERR_MULTIPLE_MATCH_FOR_SRCFILE EXCEPTION; CODE_MULTIPLE_MATCH_FOR_SRCFILE CONSTANT PLS_INTEGER := -20003; MSG_MULTIPLE_MATCH_FOR_SRCFILE VARCHAR2(4000) := 'Multiple match for source file in A_SOURCE_FILE_CONFIG table'; PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_MATCH_FOR_SRCFILE ,CODE_MULTIPLE_MATCH_FOR_SRCFILE); ERR_MISSING_COLUMN_DATE_FORMAT EXCEPTION; CODE_MISSING_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20004; MSG_MISSING_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Missing entry in config table: A_COLUMN_DATE_FORMAT primary key(TEMPLATE_TABLE_NAME, COLUMN_NAME)' ||cgBL||' Remember: each column which data_type IN (''DATE'', ''TIMESTAMP'')' ||cgBL||' should have DateFormat specified in A_COLUMN_DATE_FORMAT table ' ||cgBL||' for example: ''YYYY-MM-DD'''; PRAGMA EXCEPTION_INIT( ERR_MISSING_COLUMN_DATE_FORMAT ,CODE_MISSING_COLUMN_DATE_FORMAT); ERR_MULTIPLE_COLUMN_DATE_FORMAT EXCEPTION; CODE_MULTIPLE_COLUMN_DATE_FORMAT CONSTANT PLS_INTEGER := -20005; MSG_MULTIPLE_COLUMN_DATE_FORMAT VARCHAR2(4000) := 'Multiple records for date format in A_COLUMN_DATE_FORMAT table' ||cgBL||' There should be only one format specified for each DAT/TIMESTAMP column'; PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_COLUMN_DATE_FORMAT ,CODE_MULTIPLE_COLUMN_DATE_FORMAT); ERR_DIDNT_GET_LOAD_OPERATION_ID EXCEPTION; CODE_DIDNT_GET_LOAD_OPERATION_ID CONSTANT PLS_INTEGER := -20006; MSG_DIDNT_GET_LOAD_OPERATION_ID VARCHAR2(4000) := 'Didnt get load operation id from external table validation'; PRAGMA EXCEPTION_INIT( ERR_DIDNT_GET_LOAD_OPERATION_ID ,CODE_DIDNT_GET_LOAD_OPERATION_ID); ERR_NO_CONFIG_FOR_RECEIVED_FILE EXCEPTION; CODE_NO_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20007; MSG_NO_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'No match for received source file in A_SOURCE_FILE_CONFIG ' ||cgBL||' or missing data in A_SOURCE_FILE_RECEIVED table for provided pSourceFileReceivedKey parameter'; PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_FOR_RECEIVED_FILE ,CODE_NO_CONFIG_FOR_RECEIVED_FILE); ERR_MULTI_CONFIG_FOR_RECEIVED_FILE EXCEPTION; CODE_MULTI_CONFIG_FOR_RECEIVED_FILE CONSTANT PLS_INTEGER := -20008; MSG_MULTI_CONFIG_FOR_RECEIVED_FILE VARCHAR2(4000) := 'Multiple matchs for received source file in A_SOURCE_FILE_CONFIG'; PRAGMA EXCEPTION_INIT( ERR_MULTI_CONFIG_FOR_RECEIVED_FILE ,CODE_MULTI_CONFIG_FOR_RECEIVED_FILE); ERR_FILE_NOT_FOUND_ON_CLOUD EXCEPTION; CODE_FILE_NOT_FOUND_ON_CLOUD CONSTANT PLS_INTEGER := -20009; MSG_FILE_NOT_FOUND_ON_CLOUD VARCHAR2(4000) := 'File not found on the cloud'; PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_FOUND_ON_CLOUD ,CODE_FILE_NOT_FOUND_ON_CLOUD); ERR_FILE_VALIDATION_FAILED EXCEPTION; CODE_FILE_VALIDATION_FAILED CONSTANT PLS_INTEGER := -20010; MSG_FILE_VALIDATION_FAILED VARCHAR2(4000) := 'File validation failed'; PRAGMA EXCEPTION_INIT( ERR_FILE_VALIDATION_FAILED ,CODE_FILE_VALIDATION_FAILED); ERR_EXCESS_COLUMNS_DETECTED EXCEPTION; CODE_EXCESS_COLUMNS_DETECTED CONSTANT PLS_INTEGER := -20011; MSG_EXCESS_COLUMNS_DETECTED VARCHAR2(4000) := 'CSV file contains more columns than template allows'; PRAGMA EXCEPTION_INIT( ERR_EXCESS_COLUMNS_DETECTED ,CODE_EXCESS_COLUMNS_DETECTED); ERR_NO_CONFIG_MATCH EXCEPTION; CODE_NO_CONFIG_MATCH CONSTANT PLS_INTEGER := -20012; MSG_NO_CONFIG_MATCH VARCHAR2(4000) := 'No match for specified parameters in A_SOURCE_FILE_CONFIG table'; PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH ,CODE_NO_CONFIG_MATCH); ERR_UNKNOWN_PREFIX EXCEPTION; CODE_UNKNOWN_PREFIX CONSTANT PLS_INTEGER := -20013; MSG_UNKNOWN_PREFIX VARCHAR2(4000) := 'Unknown prefix'; PRAGMA EXCEPTION_INIT( ERR_UNKNOWN_PREFIX ,CODE_UNKNOWN_PREFIX); ERR_TABLE_NOT_EXISTS EXCEPTION; CODE_TABLE_NOT_EXISTS CONSTANT PLS_INTEGER := -20014; MSG_TABLE_NOT_EXISTS VARCHAR2(4000) := 'Table does not exist'; PRAGMA EXCEPTION_INIT( ERR_TABLE_NOT_EXISTS ,CODE_TABLE_NOT_EXISTS); ERR_COLUMN_NOT_EXISTS EXCEPTION; CODE_COLUMN_NOT_EXISTS CONSTANT PLS_INTEGER := -20015; MSG_COLUMN_NOT_EXISTS VARCHAR2(4000) := 'Column does not exist in table'; PRAGMA EXCEPTION_INIT( ERR_COLUMN_NOT_EXISTS ,CODE_COLUMN_NOT_EXISTS); ERR_UNSUPPORTED_DATA_TYPE EXCEPTION; CODE_UNSUPPORTED_DATA_TYPE CONSTANT PLS_INTEGER := -20016; MSG_UNSUPPORTED_DATA_TYPE VARCHAR2(4000) := 'Unsupported data type'; PRAGMA EXCEPTION_INIT( ERR_UNSUPPORTED_DATA_TYPE ,CODE_UNSUPPORTED_DATA_TYPE); ERR_MISSING_SOURCE_KEY EXCEPTION; CODE_MISSING_SOURCE_KEY CONSTANT PLS_INTEGER := -20017; MSG_MISSING_SOURCE_KEY VARCHAR2(4000) := 'The Source was not found in parent table A_SOURCE'; PRAGMA EXCEPTION_INIT( ERR_MISSING_SOURCE_KEY ,CODE_MISSING_SOURCE_KEY); ERR_NULL_SOURCE_FILE_CONFIG_KEY EXCEPTION; CODE_NULL_SOURCE_FILE_CONFIG_KEY CONSTANT PLS_INTEGER := -20018; MSG_NULL_SOURCE_FILE_CONFIG_KEY VARCHAR2(4000) := 'No entry in A_SOURCE_FILE_CONFIG table for specified A_SOURCE_FILE_CONFIG_KEY'; PRAGMA EXCEPTION_INIT( ERR_NULL_SOURCE_FILE_CONFIG_KEY ,CODE_NULL_SOURCE_FILE_CONFIG_KEY); ERR_DUPLICATED_SOURCE_KEY EXCEPTION; CODE_DUPLICATED_SOURCE_KEY CONSTANT PLS_INTEGER := -20019; MSG_DUPLICATED_SOURCE_KEY VARCHAR2(4000) := 'The Source already exists in the A_SOURCE table'; PRAGMA EXCEPTION_INIT( ERR_DUPLICATED_SOURCE_KEY ,CODE_DUPLICATED_SOURCE_KEY); ERR_MISSING_CONTAINER_CONFIG EXCEPTION; CODE_MISSING_CONTAINER_CONFIG CONSTANT PLS_INTEGER := -20020; MSG_MISSING_CONTAINER_CONFIG VARCHAR2(4000) := 'No match in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID'; PRAGMA EXCEPTION_INIT( ERR_MISSING_CONTAINER_CONFIG ,CODE_MISSING_CONTAINER_CONFIG); ERR_MULTIPLE_CONTAINER_ENTRIES EXCEPTION; CODE_MULTIPLE_CONTAINER_ENTRIES CONSTANT PLS_INTEGER := -20021; MSG_MULTIPLE_CONTAINER_ENTRIES VARCHAR2(4000) := 'Multiple matches in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID'; PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_CONTAINER_ENTRIES ,CODE_MULTIPLE_CONTAINER_ENTRIES); ERR_WRONG_DESTINATION_PARAM EXCEPTION; CODE_WRONG_DESTINATION_PARAM CONSTANT PLS_INTEGER := -20022; MSG_WRONG_DESTINATION_PARAM VARCHAR2(4000) := 'Wrong destination parameter provided.'; PRAGMA EXCEPTION_INIT( ERR_WRONG_DESTINATION_PARAM ,CODE_WRONG_DESTINATION_PARAM); ERR_FILE_NOT_EXISTS_ON_CLOUD EXCEPTION; CODE_FILE_NOT_EXISTS_ON_CLOUD CONSTANT PLS_INTEGER := -20023; MSG_FILE_NOT_EXISTS_ON_CLOUD VARCHAR2(4000) := 'File not exists on cloud.'; PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_EXISTS_ON_CLOUD ,CODE_FILE_NOT_EXISTS_ON_CLOUD); ERR_FILE_ALREADY_REGISTERED EXCEPTION; CODE_FILE_ALREADY_REGISTERED CONSTANT PLS_INTEGER := -20024; MSG_FILE_ALREADY_REGISTERED VARCHAR2(4000) := 'File already registered in A_SOURCE_FILE_RECEIVED table.'; PRAGMA EXCEPTION_INIT( ERR_FILE_ALREADY_REGISTERED ,CODE_FILE_ALREADY_REGISTERED); ERR_WRONG_DATE_TIMESTAMP_FORMAT EXCEPTION; CODE_WRONG_DATE_TIMESTAMP_FORMAT CONSTANT PLS_INTEGER := -20025; MSG_WRONG_DATE_TIMESTAMP_FORMAT VARCHAR2(4000) := 'Provided DATE or TIMESTAMP format has errors (possible duplicated codes, ex: ''DD'').'; PRAGMA EXCEPTION_INIT( ERR_WRONG_DATE_TIMESTAMP_FORMAT ,CODE_WRONG_DATE_TIMESTAMP_FORMAT); ERR_ENVIRONMENT_NOT_SET EXCEPTION; CODE_ENVIRONMENT_NOT_SET CONSTANT PLS_INTEGER := -20026; MSG_ENVIRONMENT_NOT_SET VARCHAR2(4000) := 'EnvironmentID not set' ||cgBL||' Information about environment is needed to get proper configuration values.' ||cgBL||' It can be set up in two different ways:' ||cgBL||' 1. Set it on session level: execute DBMS_SESSION.SET_IDENTIFIER (client_id => ''dev'')' ||cgBL||' 2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values (''default'',''environment_id'',''dev'')' ||cgBL||' Session level setup (1.) takes precedence over configuration level one (2.)' ; PRAGMA EXCEPTION_INIT( ERR_ENVIRONMENT_NOT_SET ,CODE_ENVIRONMENT_NOT_SET); ERR_CONFIG_VARIABLE_NOT_SET EXCEPTION; CODE_CONFIG_VARIABLE_NOT_SET CONSTANT PLS_INTEGER := -20027; MSG_CONFIG_VARIABLE_NOT_SET VARCHAR2(4000) := 'Missing configuration value in A_FILE_MANAGER_CONFIG'; PRAGMA EXCEPTION_INIT( ERR_CONFIG_VARIABLE_NOT_SET ,CODE_CONFIG_VARIABLE_NOT_SET); ERR_NOT_INPUT_SOURCE_FILE_TYPE EXCEPTION; CODE_NOT_INPUT_SOURCE_FILE_TYPE CONSTANT PLS_INTEGER := -20028; MSG_NOT_INPUT_SOURCE_FILE_TYPE VARCHAR2(4000) := 'Archival can be executed only for A_SOURCE_FILE_CONFIG_KEY where SOURCE_FILE_TYPE=''INPUT'''; PRAGMA EXCEPTION_INIT( ERR_NOT_INPUT_SOURCE_FILE_TYPE ,CODE_NOT_INPUT_SOURCE_FILE_TYPE); ERR_EXP_DATA_FOR_ARCH_FAILED EXCEPTION; CODE_EXP_DATA_FOR_ARCH_FAILED CONSTANT PLS_INTEGER := -20029; MSG_EXP_DATA_FOR_ARCH_FAILED VARCHAR2(4000) := 'Export data for archival failed.'; PRAGMA EXCEPTION_INIT( ERR_EXP_DATA_FOR_ARCH_FAILED ,CODE_EXP_DATA_FOR_ARCH_FAILED); ERR_RESTORE_FILE_FROM_TRASH EXCEPTION; CODE_RESTORE_FILE_FROM_TRASH CONSTANT PLS_INTEGER := -20030; MSG_RESTORE_FILE_FROM_TRASH VARCHAR2(4000) := 'Unexpected issues occured while archival process. Restoration of exported files failed.'; PRAGMA EXCEPTION_INIT( ERR_RESTORE_FILE_FROM_TRASH ,CODE_RESTORE_FILE_FROM_TRASH); ERR_CHANGE_STAT_TO_ARCHIVED_FAILED EXCEPTION; CODE_CHANGE_STAT_TO_ARCHIVED_FAILED CONSTANT PLS_INTEGER := -20031; MSG_CHANGE_STAT_TO_ARCHIVED_FAILED VARCHAR2(4000) := 'Failed to change file status to: ARCHIVED in A_SOURCE_FILE_RECEIVED table.'; PRAGMA EXCEPTION_INIT( ERR_CHANGE_STAT_TO_ARCHIVED_FAILED ,CODE_CHANGE_STAT_TO_ARCHIVED_FAILED); ERR_MOVE_FILE_TO_TRASH_FAILED EXCEPTION; CODE_MOVE_FILE_TO_TRASH_FAILED CONSTANT PLS_INTEGER := -20032; MSG_MOVE_FILE_TO_TRASH_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.'; PRAGMA EXCEPTION_INIT( ERR_MOVE_FILE_TO_TRASH_FAILED ,CODE_MOVE_FILE_TO_TRASH_FAILED); ERR_DROP_EXPORTED_FILES_FAILED EXCEPTION; CODE_DROP_EXPORTED_FILES_FAILED CONSTANT PLS_INTEGER := -20033; MSG_DROP_EXPORTED_FILES_FAILED VARCHAR2(4000) := 'FAILED to move file to TRASH before DROPPING it.'; PRAGMA EXCEPTION_INIT( ERR_DROP_EXPORTED_FILES_FAILED ,CODE_DROP_EXPORTED_FILES_FAILED); ERR_INVALID_BUCKET_AREA EXCEPTION; CODE_INVALID_BUCKET_AREA CONSTANT PLS_INTEGER := -20034; MSG_INVALID_BUCKET_AREA VARCHAR2(4000) := 'Invalid bucket area specified. Valid values: INBOX, ODS, DATA, ARCHIVE'; PRAGMA EXCEPTION_INIT( ERR_INVALID_BUCKET_AREA ,CODE_INVALID_BUCKET_AREA); ERR_INVALID_PARALLEL_DEGREE EXCEPTION; CODE_INVALID_PARALLEL_DEGREE CONSTANT PLS_INTEGER := -20110; MSG_INVALID_PARALLEL_DEGREE VARCHAR2(4000) := 'Invalid parallel degree parameter. Must be between 1 and 16'; PRAGMA EXCEPTION_INIT( ERR_INVALID_PARALLEL_DEGREE ,CODE_INVALID_PARALLEL_DEGREE); ERR_PARALLEL_EXECUTION_FAILED EXCEPTION; CODE_PARALLEL_EXECUTION_FAILED CONSTANT PLS_INTEGER := -20111; MSG_PARALLEL_EXECUTION_FAILED VARCHAR2(4000) := 'Parallel execution failed'; PRAGMA EXCEPTION_INIT( ERR_PARALLEL_EXECUTION_FAILED ,CODE_PARALLEL_EXECUTION_FAILED); ERR_UNKNOWN EXCEPTION; CODE_UNKNOWN CONSTANT PLS_INTEGER := -20999; MSG_UNKNOWN VARCHAR2(4000) := 'Unknown Error Occured'; PRAGMA EXCEPTION_INIT( ERR_UNKNOWN ,CODE_UNKNOWN); --------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------- /** * @name LOG_PROCESS_EVENT * @desc Insert a new log record into A_PROCESS_LOG table. * Also outputs to console if gvConsoleLoggingEnabled = 'ON'. * Respects logging level configuration (gvMinLogLevel). * @example ENV_MANAGER.LOG_PROCESS_EVENT('Process completed successfully', 'INFO', 'pParam1=value1'); * @ex_rslt Record inserted into A_PROCESS_LOG table and optionally displayed in console output **/ PROCEDURE LOG_PROCESS_EVENT ( pLogMessage VARCHAR2 ,pLogLevel VARCHAR2 DEFAULT 'ERROR' ,pParameters VARCHAR2 DEFAULT NULL ,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER' ); /** * @name LOG_PROCESS_ERROR * @desc Insert a detailed error record into A_PROCESS_LOG table with full stack trace, backtrace, and call stack. * This procedure captures comprehensive error information for debugging purposes while * allowing clean user-facing error messages to be raised separately. * @param pLogMessage - Base error message description * @param pParameters - Procedure parameters for context * @param pProcessName - Name of the calling process/package * @ex_rslt Record inserted into A_PROCESS_LOG table with complete error stack information */ PROCEDURE LOG_PROCESS_ERROR ( pLogMessage VARCHAR2 ,pParameters VARCHAR2 DEFAULT NULL ,pProcessName VARCHAR2 DEFAULT 'FILE_MANAGER' ); /** * @name INIT_ERRORS * @desc Loads data into Errors array. * Errors array is a list of Record(Error_Code, Error_Message) index by Error_Code. * Called automatically during package initialization. * @example Called automatically when package is first referenced * @ex_rslt Errors array populated with all error codes and messages **/ PROCEDURE INIT_ERRORS; /** * @name GET_DEFAULT_ENV * @desc It returns string with name of default environment. * Return string is A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID value. * @example select ENV_MANAGER.GET_DEFAULT_ENV() from dual; * @ex_rslt dev **/ FUNCTION GET_DEFAULT_ENV RETURN VARCHAR2; /** * @name INIT_VARIABLES * @desc For specified pEnv parameter (A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID) * Assign values to following global package variables: * - gvNameSpace * - gvRegion * - gvCredentialName * - gvInboxBucketName * - gvDataBucketName * - gvArchiveBucketName * - gvInboxBucketUri * - gvDataBucketUri * - gvArchiveBucketUri * - gvLoggingEnabled * - gvMinLogLevel * - gvDefaultDateFormat * - gvConsoleLoggingEnabled **/ PROCEDURE INIT_VARIABLES( pEnv VARCHAR2 ); /** * @name GET_ERROR_MESSAGE * @desc It returns string with error message for specified pCode (Error_Code). * Error message is take from Errors Array loaded by INIT_ERRORS procedure * @example select ENV_MANAGER.GET_ERROR_MESSAGE(pCode => -20009) from dual; * @ex_rslt File not found on the cloud **/ FUNCTION GET_ERROR_MESSAGE( pCode PLS_INTEGER ) RETURN VARCHAR2; /** * @name GET_ERROR_STACK * @desc It returns string with all possible error stack info. * Error message is take from Errors Array loaded by INIT_ERRORS procedure * @example * select ENV_MANAGER.GET_ERROR_STACK( * pFormat => 'OUTPUT' * ,pCode => -20009 * ,pSourceFileReceivedKey => NULL) * from dual * @ex_rslt * ------------------------------------------------------+ * Error Message: * ORA-0000: normal, successful completion * ------------------------------------------------------- * Error Stack: * ------------------------------------------------------- * Error Backtrace: * ------------------------------------------------------+ **/ FUNCTION GET_ERROR_STACK( pFormat VARCHAR2 ,pCode PLS_INTEGER ,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL ) RETURN VARCHAR2; /** * @name FORMAT_PARAMETERS * @desc Formats parameter list for logging purposes. * Converts SYS.ODCIVARCHAR2LIST to formatted string with proper NULL handling. * @example select ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('param1=value1', 'param2=NULL')) from dual; * @ex_rslt param1=value1 , * param2=NULL **/ FUNCTION FORMAT_PARAMETERS( pParameterList SYS.ODCIVARCHAR2LIST ) RETURN VARCHAR2; /** * @name ANALYZE_VALIDATION_ERRORS * @desc Analyzes CSV validation errors and generates detailed diagnostic report. * Compares CSV structure with template table and provides specific error analysis. * Includes suggested solutions for common validation issues. * @param pValidationLogTable - Name of validation log table (e.g., VALIDATE$242_LOG) * @param pTemplateSchema - Schema of template table (e.g., CT_ET_TEMPLATES) * @param pTemplateTable - Name of template table (e.g., MOCK_PROC_TABLE) * @param pCsvFileUri - URI of CSV file being validated * @example SELECT ENV_MANAGER.ANALYZE_VALIDATION_ERRORS('VALIDATE$242_LOG', 'CT_ET_TEMPLATES', 'MOCK_PROC_TABLE', 'https://...') FROM DUAL; * @ex_rslt Detailed validation analysis report with column mismatches and solutions **/ FUNCTION ANALYZE_VALIDATION_ERRORS( pValidationLogTable VARCHAR2, pTemplateSchema VARCHAR2, pTemplateTable VARCHAR2, pCsvFileUri VARCHAR2 ) RETURN VARCHAR2; --------------------------------------------------------------------------------------------------------------------------- -- PACKAGE VERSION MANAGEMENT FUNCTIONS --------------------------------------------------------------------------------------------------------------------------- /** * @name GET_VERSION * @desc Returns the current version number of the ENV_MANAGER package. * Uses semantic versioning format (MAJOR.MINOR.PATCH). * @example SELECT ENV_MANAGER.GET_VERSION() FROM DUAL; * @ex_rslt 3.0.0 **/ FUNCTION GET_VERSION RETURN VARCHAR2; /** * @name GET_BUILD_INFO * @desc Returns comprehensive build information including version, build date, and author. * Formatted for display in logs or monitoring systems. * @example SELECT ENV_MANAGER.GET_BUILD_INFO() FROM DUAL; * @ex_rslt Package: ENV_MANAGER * Version: 3.0.0 * Build Date: 2025-10-22 16:00:00 * Author: Grzegorz Michalski **/ FUNCTION GET_BUILD_INFO RETURN VARCHAR2; /** * @name GET_VERSION_HISTORY * @desc Returns complete version history with all releases and changes. * Shows evolution of package features over time. * @example SELECT ENV_MANAGER.GET_VERSION_HISTORY() FROM DUAL; * @ex_rslt ENV_MANAGER Version History: * 3.0.0 (2025-10-22): Added package versioning system... * 2.1.0 (2025-10-15): Added ANALYZE_VALIDATION_ERRORS function... **/ FUNCTION GET_VERSION_HISTORY RETURN VARCHAR2; /** * @name GET_PACKAGE_VERSION_INFO * @desc Universal function to get formatted version information for any package. * This centralized function is used by all packages in the system. * @param pPackageName - Name of the package * @param pVersion - Version string (MAJOR.MINOR.PATCH format) * @param pBuildDate - Build date timestamp * @param pAuthor - Package author name * @example SELECT ENV_MANAGER.GET_PACKAGE_VERSION_INFO('FILE_MANAGER', '2.1.0', '2025-10-22 15:00:00', 'Grzegorz Michalski') FROM DUAL; * @ex_rslt Package: FILE_MANAGER * Version: 2.1.0 * Build Date: 2025-10-22 15:00:00 * Author: Grzegorz Michalski **/ FUNCTION GET_PACKAGE_VERSION_INFO( pPackageName VARCHAR2, pVersion VARCHAR2, pBuildDate VARCHAR2, pAuthor VARCHAR2 ) RETURN VARCHAR2; /** * @name FORMAT_VERSION_HISTORY * @desc Universal function to format version history for any package. * Adds package name header and proper formatting. * @param pPackageName - Name of the package * @param pVersionHistory - Complete version history text * @example SELECT ENV_MANAGER.FORMAT_VERSION_HISTORY('FILE_MANAGER', '2.1.0 (2025-10-22): Export procedures...') FROM DUAL; * @ex_rslt FILE_MANAGER Version History: * 2.1.0 (2025-10-22): Export procedures... **/ FUNCTION FORMAT_VERSION_HISTORY( pPackageName VARCHAR2, pVersionHistory VARCHAR2 ) RETURN VARCHAR2; --------------------------------------------------------------------------------------------------------------------------- -- PACKAGE HASH + CHANGE DETECTION FUNCTIONS --------------------------------------------------------------------------------------------------------------------------- /** * @name CALCULATE_PACKAGE_HASH * @desc Calculates SHA256 hash of package source code from ALL_SOURCE. * Returns hash for both SPEC and BODY (if exists). * Used for automatic change detection. * @param pPackageOwner - Schema owner of the package * @param pPackageName - Name of the package * @param pPackageType - Type of package code ('PACKAGE' for SPEC, 'PACKAGE BODY' for BODY) * @example SELECT ENV_MANAGER.CALCULATE_PACKAGE_HASH('CT_MRDS', 'FILE_MANAGER', 'PACKAGE') FROM DUAL; * @ex_rslt A7B3C5D9E8F1234567890ABCDEF... (64-character SHA256 hash) **/ FUNCTION CALCULATE_PACKAGE_HASH( pPackageOwner VARCHAR2, pPackageName VARCHAR2, pPackageType VARCHAR2 -- 'PACKAGE' or 'PACKAGE BODY' ) RETURN VARCHAR2; /** * @name TRACK_PACKAGE_VERSION * @desc Records package version and source code hash in A_PACKAGE_VERSION_TRACKING table. * Automatically detects if source code changed without version update. * Should be called after every package deployment. * @param pPackageOwner - Schema owner of the package * @param pPackageName - Name of the package * @param pPackageVersion - Current version from PACKAGE_VERSION constant * @param pPackageBuildDate - Build date from PACKAGE_BUILD_DATE constant * @param pPackageAuthor - Author from PACKAGE_AUTHOR constant * @example EXEC ENV_MANAGER.TRACK_PACKAGE_VERSION('CT_MRDS', 'FILE_MANAGER', '3.2.0', '2025-10-22 16:30:00', 'Grzegorz Michalski'); * @ex_rslt Record inserted into A_PACKAGE_VERSION_TRACKING with change detection status **/ PROCEDURE TRACK_PACKAGE_VERSION( pPackageOwner VARCHAR2, pPackageName VARCHAR2, pPackageVersion VARCHAR2, pPackageBuildDate VARCHAR2, pPackageAuthor VARCHAR2 ); /** * @name CHECK_PACKAGE_CHANGES * @desc Checks if package source code has changed since last tracking. * Compares current hash with last recorded hash in A_PACKAGE_VERSION_TRACKING. * Returns detailed change detection report. * @param pPackageOwner - Schema owner of the package * @param pPackageName - Name of the package * @example SELECT ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL; * @ex_rslt WARNING: Package changed without version update! * Last Version: 3.2.0 * Current Hash (SPEC): A7B3C5D9... * Last Hash (SPEC): B8C4D6E0... * RECOMMENDATION: Update PACKAGE_VERSION and PACKAGE_BUILD_DATE **/ FUNCTION CHECK_PACKAGE_CHANGES( pPackageOwner VARCHAR2, pPackageName VARCHAR2 ) RETURN VARCHAR2; /** * @name GET_PACKAGE_HASH_INFO * @desc Returns formatted information about package hash and tracking history. * Includes current hash, last tracked hash, and change detection status. * @param pPackageOwner - Schema owner of the package * @param pPackageName - Name of the package * @example SELECT ENV_MANAGER.GET_PACKAGE_HASH_INFO('CT_MRDS', 'FILE_MANAGER') FROM DUAL; * @ex_rslt Package: CT_MRDS.FILE_MANAGER * Current Version: 3.2.0 * Current Hash (SPEC): A7B3C5D9... * Last Tracked: 2025-10-22 16:30:00 * Status: OK - No changes detected **/ FUNCTION GET_PACKAGE_HASH_INFO( pPackageOwner VARCHAR2, pPackageName VARCHAR2 ) RETURN VARCHAR2; END ENV_MANAGER; /