diff --git a/apex/f770/application/deployment/definition.sql b/apex/f770/application/deployment/definition.sql index 385f67b..39b1049 100644 --- a/apex/f770/application/deployment/definition.sql +++ b/apex/f770/application/deployment/definition.sql @@ -13,6 +13,8 @@ wwv_flow_api.component_begin ( ); wwv_flow_api.create_install( p_id=>wwv_flow_api.id(12958699824624058) +,p_required_free_kb=>1000 +,p_required_sys_privs=>'CREATE PROCEDURE:CREATE SEQUENCE:CREATE TABLE:CREATE TRIGGER:CREATE VIEW' ); wwv_flow_api.component_end; end; diff --git a/apex/f770/application/deployment/install/install_install_data.sql b/apex/f770/application/deployment/install/install_install_data.sql new file mode 100644 index 0000000..8d59b09 --- /dev/null +++ b/apex/f770/application/deployment/install/install_install_data.sql @@ -0,0 +1,70 @@ +prompt --application/deployment/install/install_install_data +begin +-- Manifest +-- INSTALL: INSTALL-INSTALL_DATA +-- Manifest End +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.create_install_script( + p_id=>wwv_flow_api.id(20452605375414152) +,p_install_id=>wwv_flow_api.id(12958699824624058) +,p_name=>'INSTALL_DATA' +,p_sequence=>80 +,p_script_type=>'INSTALL' +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'--', +'-- SEED DATA', +'--', +'INSERT INTO apps (app_id, app_name, is_active, updated_by, updated_at)', +'VALUES (', +' 770,', +' ''CORE'',', +' ''Y'',', +' USER,', +' SYSDATE', +');', +'', +'INSERT INTO roles (app_id, role_id, role_name, is_active)', +'VALUES (', +' 770,', +' ''IS_ADMINISTRATOR'',', +' ''Administrator'',', +' ''Y''', +');', +'', +'--', +'-- NAVIGATION', +'--', +'DELETE FROM navigation;', +'--', +'INSERT INTO navigation (app_id, page_id, parent_id, order#)', +'SELECT 770, 0, NULL, 599 FROM DUAL UNION ALL', +'SELECT 770, 100, NULL, 100 FROM DUAL UNION ALL', +'SELECT 770, 990, NULL, 990 FROM DUAL UNION ALL', +'SELECT 770, 9999, NULL, 999 FROM DUAL UNION ALL', +'SELECT 770, 900, NULL, 900 FROM DUAL UNION ALL', +'SELECT 770, 901, 900, 10 FROM DUAL UNION ALL', +'SELECT 770, 915, 900, 15 FROM DUAL UNION ALL', +'SELECT 770, 920, 900, 20 FROM DUAL UNION ALL', +'SELECT 770, 922, 900, 25 FROM DUAL UNION ALL', +'SELECT 770, 905, 900, 30 FROM DUAL UNION ALL', +'SELECT 770, 940, 900, 35 FROM DUAL UNION ALL', +'SELECT 770, 925, 900, 40 FROM DUAL UNION ALL', +'SELECT 770, 910, 900, 45 FROM DUAL UNION ALL', +'SELECT 770, 970, 900, 50 FROM DUAL;', +'--', +'UPDATE navigation n', +'SET n.is_reset = CASE WHEN n.page_id > 0 THEN ''Y'' END,', +' n.is_shared = CASE WHEN n.page_id >= 900 AND n.page_id < 9999 THEN ''Y'' END;', +'', +'')) +); +wwv_flow_api.component_end; +end; +/ diff --git a/apex/f770/application/deployment/install/install_install_packages.sql b/apex/f770/application/deployment/install/install_install_packages.sql new file mode 100644 index 0000000..0653c5b --- /dev/null +++ b/apex/f770/application/deployment/install/install_install_packages.sql @@ -0,0 +1,6223 @@ +prompt --application/deployment/install/install_install_packages +begin +-- Manifest +-- INSTALL: INSTALL-INSTALL_PACKAGES +-- Manifest End +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.create_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_install_id=>wwv_flow_api.id(12958699824624058) +,p_name=>'INSTALL_PACKAGES' +,p_sequence=>40 +,p_script_type=>'INSTALL' +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'CREATE OR REPLACE PACKAGE "A770" AS', +'', +' /**', +' * If you have an app with id 100 you should rename this package to a100.', +' *', +' * You should put auth roles specific to your app here.', +' * And you can override some procedures from app package here.', +' *', +' */', +'', +'', +'', +' --', +' -- Authorization roles for this app', +' --', +' FUNCTION is_mod_a_user', +' RETURN CHAR;', +' --', +' FUNCTION is_administrator', +' RETURN CHAR;', +'', +'', +'', +' --', +' -- Create user (or not) on first login', +' --', +' PROCEDURE create_user (', +' in_user_login users.user_login%TYPE,', +' in_user_id users.user_id%TYPE', +' );', +'', +'', +'', +' --', +' -- Override ffor app.create_session', +' --', +' PROCEDURE create_session (', +' in_user_login users.user_login%TYPE,', +' in_user_id users.user_id%TYPE', +' );', +'', +'', +'', +' --', +' -- Override for app.exit_session', +' --', +' PROCEDURE exit_session;', +'', +'END;', +'/', +'', +'', +'CREATE OR REPLACE PACKAGE BODY "A770" AS', +'', +' FUNCTION is_mod_a_user', +' RETURN CHAR AS', +' is_valid CHAR;', +' BEGIN', +' --is_valid := SUBSTR(sett.get_test_a(), 1, 1);', +'', +' IF app.is_developer() THEN', +' RETURN ''Y'';', +' END IF;', +' --', +' SELECT ''Y'' INTO is_valid', +' FROM user_roles u', +' JOIN roles r', +' ON r.app_id = u.app_id', +' AND r.role_id = u.role_id', +' WHERE u.app_id = app.get_app_id()', +' AND u.user_id = app.get_user_id()', +' AND u.role_id = app.get_caller_name()', +' AND r.is_active = ''Y'';', +' --', +' RETURN is_valid;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN ''N'';', +' END;', +'', +'', +'', +' FUNCTION is_administrator', +' RETURN CHAR AS', +' is_valid CHAR;', +' BEGIN', +' IF app.is_developer() THEN', +' RETURN ''Y'';', +' END IF;', +' --', +' SELECT ''Y'' INTO is_valid', +' FROM user_roles u', +' JOIN roles r', +' ON r.app_id = u.app_id', +' AND r.role_id = u.role_id', +' WHERE u.app_id = app.get_app_id()', +' AND u.user_id = app.get_user_id()', +' AND u.role_id = app.get_caller_name()', +' AND r.is_active = ''Y'';', +' --', +' RETURN is_valid;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN ''N'';', +' END;', +'', +'', +'', +' PROCEDURE create_user (', +' in_user_login users.user_login%TYPE,', +' in_user_id users.user_id%TYPE', +' ) AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' rec users%ROWTYPE;', +' BEGIN', +' app.log_module_json (', +' ''user_login'', in_user_login,', +' ''user_id'', in_user_id', +' );', +' --', +' -- @TODO: app.create_user(rec)', +' --', +' rec.user_id := in_user_id;', +' rec.user_login := in_user_login;', +' rec.user_name := NULL;', +' rec.is_active := ''Y'';', +' rec.updated_by := app.get_user_id();', +' rec.updated_at := SYSDATE;', +' --', +' BEGIN', +' INSERT INTO users VALUES rec;', +' EXCEPTION', +' WHEN DUP_VAL_ON_INDEX THEN', +' NULL;', +' END;', +' --', +' /*', +' BEGIN', +' INSERT INTO user_roles (user_id, role_id, is_active, updated_by, updated_at)', +' VALUES (', +' in_user_id,', +' ''USER'',', +' ''Y'',', +' in_user_name,', +' SYSDATE', +' );', +' EXCEPTION', +' WHEN DUP_VAL_ON_INDEX THEN', +' NULL;', +' END;', +' */', +' --', +' COMMIT;', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE create_session (', +' in_user_login users.user_login%TYPE,', +' in_user_id users.user_id%TYPE', +' )', +' AS', +' BEGIN', +' --app.log_module();', +' --', +' IF app.get_page_id() IN (9999, 100) THEN -- only for login page and home page -- @TODO: remove hardcoded numbers', +' a770.create_user (', +' in_user_login => in_user_login,', +' in_user_id => in_user_id', +' );', +' END IF;', +' --', +' --app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE exit_session', +' AS', +' BEGIN', +' --app.log_module();', +' --', +' NULL;', +' --', +' --app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'END;', +'/', +'', +'CREATE OR REPLACE PACKAGE "APP" AS', +'', +' /**', +' * This package is part of the APP CORE project under MIT licence.', +' * https://github.com/jkvetina/#core', +' *', +' * Copyright (c) Jan Kvetina, 2021', +' *', +' * (R)', +' * --- ---', +' * #@@@@@@ &@@@@@@', +' * @@@@@@@@ .@ @@@@@@@@', +' * ----- @@@@@@ @@@@@@, @@@@@@@ -----', +' * &@@@@@@@@@@@ @@@ &@@@@@@@@@. @@@@ .@@@@@@@@@@@#', +' * @@@@@@@@@@@ @ @@@@@@@@@@@@@ @ @@@@@@@@@@@', +' * \@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@@@@@', +' * @@@@@@@@@ @@@@@@@@@@@@@@@ &@@@@@@@@', +' * @@@@@@@( @@@@@@@@@@@@@@@ @@@@@@@@', +' * @@@@@@( @@@@@@@@@@@@@@, @@@@@@@', +' * .@@@@@, @@@@@@@@@@@@@ @@@@@@', +' * @@@@@@ *@@@@@@@@@@@@@ @@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * .@@@@@@@@@@@@@@@@@@@@@@@@@', +' * .@@@@@@@@@@@@@@@@@@@@@', +' * jankvetina.cz', +' * -------', +' *', +' */', +'', +' schema_owner CONSTANT VARCHAR2(30) := ''CORE'';', +' schema_apex CONSTANT VARCHAR2(30) := ''APEX_210100'';', +' --', +' core_app_id CONSTANT sessions.app_id%TYPE := 770; -- for sharing pages between apps', +'', +' -- code for app exception', +' app_exception_code CONSTANT PLS_INTEGER := -20000;', +' app_exception EXCEPTION;', +' --', +' PRAGMA EXCEPTION_INIT(app_exception, app_exception_code); -- as a side effect this will disable listing constants in tree on the left', +'', +' -- internal date formats', +' format_date CONSTANT VARCHAR2(30) := ''YYYY-MM-DD'';', +' format_date_time CONSTANT VARCHAR2(30) := ''YYYY-MM-DD HH24:MI:SS'';', +' format_date_short CONSTANT VARCHAR2(30) := ''YYYY-MM-DD HH24:MI'';', +'', +' -- anonymous user used on login pages in APEX', +' anonymous_user CONSTANT VARCHAR2(30) := ''NOBODY''; -- ORDS_PUBLIC_USER, APEX_APP.G_PUBLIC', +'', +' -- flags', +' flag_request CONSTANT logs.flag%TYPE := ''P''; -- APEX request (page rendering, form processing)', +' flag_module CONSTANT logs.flag%TYPE := ''M''; -- start of any module (procedure/function)', +' flag_action CONSTANT logs.flag%TYPE := ''A''; -- start of any APEX action', +' flag_debug CONSTANT logs.flag%TYPE := ''D''; -- debug', +' flag_result CONSTANT logs.flag%TYPE := ''R''; -- result of procedure for debugging purposes', +' flag_warning CONSTANT logs.flag%TYPE := ''W''; -- warning', +' flag_error CONSTANT logs.flag%TYPE := ''E''; -- error', +' flag_longops CONSTANT logs.flag%TYPE := ''L''; -- longops operation', +' flag_scheduler CONSTANT logs.flag%TYPE := ''S''; -- scheduler planned', +' flag_trigger CONSTANT logs.flag%TYPE := ''G''; -- called from trigger', +'', +' -- specify maximum length for trim', +' length_user CONSTANT PLS_INTEGER := 30; -- logs.user_id%TYPE', +' length_action CONSTANT PLS_INTEGER := 32; -- logs.action_name%TYPE', +' length_module CONSTANT PLS_INTEGER := 48; -- logs.module_name%TYPE', +' length_arguments CONSTANT PLS_INTEGER := 2000; -- logs.arguments%TYPE', +' length_payload CONSTANT PLS_INTEGER := 4000; -- logs.payload%TYPE', +'', +' -- append callstack for these flags', +' track_callstack CONSTANT VARCHAR2(30) := flag_error || flag_warning || flag_module || flag_request || flag_trigger;', +'', +' -- transform $NAME to P500_NAME if current page_id = 500', +' page_item_wild CONSTANT VARCHAR2(4) := ''$'';', +' page_item_prefix CONSTANT VARCHAR2(4) := ''P'';', +'', +' -- name of AUTH package', +' auth_package CONSTANT VARCHAR2(30) := ''AUTH'';', +' auth_page_id_arg CONSTANT VARCHAR2(30) := ''IN_PAGE_ID'';', +'', +' -- error log table name and max age fo records', +' logs_table_name CONSTANT VARCHAR2(30) := ''LOGS''; -- used in purge_old', +' logs_max_age CONSTANT PLS_INTEGER := 7; -- max logs age in days', +'', +' -- arrays to specify adhoc requests', +' TYPE arr_log_setup IS VARRAY(100) OF logs_blacklist%ROWTYPE;', +'', +' -- list/array of log_id', +' TYPE arr_logs_log_id IS', +' TABLE OF logs.log_id%TYPE', +' INDEX BY PLS_INTEGER;', +'', +' -- array to hold recent log_id based on callstack_hash', +' TYPE arr_map_tree IS', +' TABLE OF logs.log_id%TYPE', +' INDEX BY VARCHAR2(40);', +'', +'', +'', +'', +'', +'', +'', +' -- ### User section', +' --', +'', +' --', +' -- Returns APEX application id (for proxy app)', +' --', +' FUNCTION get_app_id', +' RETURN sessions.app_id%TYPE;', +'', +'', +'', +' --', +' -- When using multiple apps in same workspace/schema return the real application id', +' --', +' FUNCTION get_real_app_id', +' RETURN sessions.app_id%TYPE;', +'', +'', +'', +' --', +' --', +' --', +' FUNCTION get_core_app_id', +' RETURN sessions.app_id%TYPE;', +'', +'', +'', +' --', +' -- Returns current user id (APEX, SYS_CONTEXT, DB...)', +' --', +' FUNCTION get_user_id', +' RETURN users.user_id%TYPE;', +'', +'', +'', +' --', +' -- Convert user_login to user_id', +' --', +' FUNCTION get_user_id (', +' in_user_login users.user_login%TYPE', +' )', +' RETURN users.user_id%TYPE;', +'', +'', +'', +' --', +' -- Set (shorten) user_id after authentification', +' --', +' PROCEDURE set_user_id', +' ACCESSIBLE BY (', +' PACKAGE app,', +' PACKAGE app_ut', +' );', +'', +'', +'', +' --', +' -- Get user name', +' --', +' FUNCTION get_user_name (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN users.user_name%TYPE;', +'', +'', +'', +' --', +' -- Get user login', +' --', +' FUNCTION get_user_login (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN users.user_login%TYPE;', +'', +'', +'', +' --', +' -- Get user language', +' --', +' FUNCTION get_user_lang', +' RETURN users.lang_id%TYPE;', +'', +'', +'', +' --', +' --', +' --', +' FUNCTION is_active_user (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN BOOLEAN;', +'', +'', +'', +' --', +' --', +' --', +' FUNCTION is_active_user_y (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN CHAR;', +'', +'', +'', +' --', +' -- Check if current/requested user is APEX developer', +' --', +' FUNCTION is_developer (', +' in_user users.user_login%TYPE := NULL', +' )', +' RETURN BOOLEAN;', +'', +'', +'', +' --', +' -- Same but usable in SQL', +' --', +' FUNCTION is_developer_y (', +' in_user users.user_login%TYPE := NULL', +' )', +' RETURN CHAR;', +'', +'', +'', +' --', +' -- Check if DEBUG is on', +' --', +' FUNCTION is_debug_on', +' RETURN BOOLEAN;', +'', +'', +'', +' --', +' -- Return current owner (because APEX dont like using USER)', +' --', +' FUNCTION get_owner (', +' in_app_id apps.app_id%TYPE := NULL', +' )', +' RETURN apex_applications.owner%TYPE;', +'', +'', +'', +'', +'', +'', +'', +' -- ### Session management', +' --', +'', +' --', +' -- Create session from APEX', +' --', +' PROCEDURE create_session;', +'', +'', +'', +' --', +' -- Create session outside of APEX (from console, trigger, job...)', +' --', +' PROCEDURE create_session (', +' in_user_id sessions.user_id%TYPE,', +' in_app_id sessions.app_id%TYPE,', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_session_id sessions.session_id%TYPE := NULL,', +' in_items VARCHAR2 := NULL', +' );', +'', +'', +'', +' --', +' -- Clear session at the end', +' --', +' PROCEDURE exit_session;', +'', +'', +'', +' --', +' -- Delete logs for requested session', +' --', +' PROCEDURE delete_session (', +' in_session_id sessions.session_id%TYPE', +' );', +'', +'', +'', +' --', +' -- Update DBMS_SESSION and DBMS_APPLICATION_INFO with current module and action', +' --', +' PROCEDURE set_session (', +' in_module_name logs.module_name%TYPE,', +' in_action_name logs.action_name%TYPE,', +' in_log_id logs.log_id%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Returns APEX session id', +' --', +' FUNCTION get_session_id', +' RETURN sessions.session_id%TYPE;', +'', +'', +'', +' --', +' -- Returns client_id for DBMS_SESSION', +' --', +' FUNCTION get_client_id (', +' in_user_id sessions.user_id%TYPE := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get env name', +' --', +' FUNCTION get_env_name', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get role name', +' --', +' FUNCTION get_role_name (', +' in_role_id roles.role_id%TYPE', +' )', +' RETURN roles.role_name%TYPE;', +'', +'', +'', +'', +'', +'', +'', +' -- ### Pages and requests', +' --', +'', +' --', +' -- Returns APEX page id', +' --', +' FUNCTION get_page_id', +' RETURN navigation.page_id%TYPE;', +'', +'', +'', +' --', +' -- Returns APEX page group name for requested or current page', +' --', +' FUNCTION get_page_group (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN apex_application_pages.page_group%TYPE;', +'', +'', +'', +' --', +' -- Returns root page ID for requested or current page', +' --', +' FUNCTION get_page_root (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN navigation.page_id%TYPE;', +'', +'', +'', +' --', +' -- Returns parent page ID for requested or current page', +' --', +' FUNCTION get_page_parent (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN navigation.page_id%TYPE;', +'', +'', +'', +' --', +' -- Get page name from APEX dictionary', +' --', +' FUNCTION get_page_name (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL,', +' in_name VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get link to page with items', +' --', +' FUNCTION get_page_link (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL,', +' in_names VARCHAR2 := NULL,', +' in_values VARCHAR2 := NULL,', +' in_overload VARCHAR2 := NULL, -- JSON object to overload passed items/values', +' in_transform BOOLEAN := FALSE, -- to pass all page items to new page', +' in_reset BOOLEAN := TRUE, -- reset page items', +' in_session_id sessions.session_id%TYPE := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Returns requested URL', +' --', +' FUNCTION get_request_url (', +' in_arguments_only BOOLEAN := FALSE', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Returns request (APEX button) name', +' --', +' FUNCTION get_request', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get icon as a ', +' --', +' FUNCTION get_icon (', +' in_name VARCHAR2,', +' in_title VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +'', +'', +'', +'', +' -- ### Navigation', +' --', +'', +' --', +' -- Check if user have permissions to access the page', +' --', +' FUNCTION is_page_available (', +' in_page_id navigation.page_id%TYPE,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN CHAR;', +'', +'', +'', +' --', +' -- Check if page should be visible in navigation', +' --', +' FUNCTION is_page_visible (', +' in_page_id navigation.page_id%TYPE,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN CHAR;', +'', +'', +'', +' --', +' -- Redirect to page and set items if needed', +' --', +' PROCEDURE redirect (', +' in_page_id NUMBER := NULL,', +' in_names VARCHAR2 := NULL,', +' in_values VARCHAR2 := NULL,', +' in_overload VARCHAR2 := NULL, -- JSON object to overload passed items/values', +' in_transform BOOLEAN := FALSE, -- to pass all page items to new page', +' in_reset BOOLEAN := TRUE -- reset page items', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### Functions to work with APEX items', +' --', +'', +' --', +' -- Get name of item and check if it is valid', +' --', +' FUNCTION get_item_name (', +' in_name VARCHAR2', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get (global and page) item', +' --', +' FUNCTION get_item (', +' in_name VARCHAR2,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get item as NUMBER type', +' --', +' FUNCTION get_number_item (', +' in_name VARCHAR2,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN NUMBER;', +'', +'', +'', +' --', +' -- Get item as DATE type', +' --', +' FUNCTION get_date_item (', +' in_name VARCHAR2,', +' in_format VARCHAR2 := NULL,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN DATE;', +'', +'', +'', +' --', +' -- Convert various date formats passed by APEX when submitting forms', +' --', +' FUNCTION get_date (', +' in_value VARCHAR2,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN DATE;', +'', +'', +'', +' --', +' --', +' --', +' FUNCTION get_date (', +' in_date DATE := NULL,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' --', +' --', +' FUNCTION get_date_time (', +' in_date DATE := NULL,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Convert date or timestamp into time bucket', +' --', +' FUNCTION get_time_bucket (', +' in_date DATE,', +' in_interval NUMBER', +' )', +' RETURN NUMBER', +' RESULT_CACHE;', +'', +'', +'', +' --', +' -- Convert interval to human readable form', +' --', +' FUNCTION get_duration (', +' in_interval INTERVAL DAY TO SECOND', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Convert interval to human readable form', +' --', +' FUNCTION get_duration (', +' in_interval NUMBER', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Calculate human readable difference within two timestamps', +' --', +' FUNCTION get_duration (', +' in_start TIMESTAMP,', +' in_end TIMESTAMP := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Set item', +' --', +' PROCEDURE set_item (', +' in_name VARCHAR2,', +' in_value VARCHAR2 := NULL,', +' in_raise BOOLEAN := TRUE', +' );', +'', +'', +'', +' --', +' -- Set item from DATE type', +' --', +' PROCEDURE set_date_item (', +' in_name VARCHAR2,', +' in_value DATE,', +' in_raise BOOLEAN := TRUE', +' );', +'', +'', +'', +' --', +' -- Clear page items except items passed in url', +' --', +' PROCEDURE clear_items;', +'', +'', +'', +' --', +' -- Get items for selected/current page as JSON object', +' --', +' FUNCTION get_page_items (', +' in_page_id logs.page_id%TYPE := NULL,', +' in_filter logs.arguments%TYPE := ''%''', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Get global (app) items as JSON object', +' --', +' FUNCTION get_global_items (', +' in_filter logs.arguments%TYPE := ''%''', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Apply values from JSON object keys to items', +' --', +' PROCEDURE apply_items (', +' in_items VARCHAR2', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### Logging', +' --', +'', +' --', +' -- Convert passed arguments to JSON list/array', +' --', +' FUNCTION get_json_list (', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL,', +' in_arg5 VARCHAR2 := NULL,', +' in_arg6 VARCHAR2 := NULL,', +' in_arg7 VARCHAR2 := NULL,', +' in_arg8 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Convert passed arguments to JSON object as key/value pairs', +' --', +' FUNCTION get_json_object (', +' in_name1 VARCHAR2 := NULL,', +' in_value1 VARCHAR2 := NULL,', +' in_name2 VARCHAR2 := NULL,', +' in_value2 VARCHAR2 := NULL,', +' in_name3 VARCHAR2 := NULL,', +' in_value3 VARCHAR2 := NULL,', +' in_name4 VARCHAR2 := NULL,', +' in_value4 VARCHAR2 := NULL,', +' in_name5 VARCHAR2 := NULL,', +' in_value5 VARCHAR2 := NULL,', +' in_name6 VARCHAR2 := NULL,', +' in_value6 VARCHAR2 := NULL,', +' in_name7 VARCHAR2 := NULL,', +' in_value7 VARCHAR2 := NULL,', +' in_name8 VARCHAR2 := NULL,', +' in_value8 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Main function called from APEX VPD init to track page requests', +' -- Returned log_id is used as a parent for all subsequent calls', +' --', +' FUNCTION log_request', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Function called at the very start of every procedure or function', +' --', +' FUNCTION log_module (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- ^', +' --', +' PROCEDURE log_module (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Same as log_module function but args are stored as JSON object', +' --', +' FUNCTION log_module_json (', +' in_name1 logs.arguments%TYPE := NULL, in_value1 logs.arguments%TYPE := NULL,', +' in_name2 logs.arguments%TYPE := NULL, in_value2 logs.arguments%TYPE := NULL,', +' in_name3 logs.arguments%TYPE := NULL, in_value3 logs.arguments%TYPE := NULL,', +' in_name4 logs.arguments%TYPE := NULL, in_value4 logs.arguments%TYPE := NULL,', +' in_name5 logs.arguments%TYPE := NULL, in_value5 logs.arguments%TYPE := NULL,', +' in_name6 logs.arguments%TYPE := NULL, in_value6 logs.arguments%TYPE := NULL,', +' in_name7 logs.arguments%TYPE := NULL, in_value7 logs.arguments%TYPE := NULL,', +' in_name8 logs.arguments%TYPE := NULL, in_value8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- ^', +' --', +' PROCEDURE log_module_json (', +' in_name1 logs.arguments%TYPE := NULL, in_value1 logs.arguments%TYPE := NULL,', +' in_name2 logs.arguments%TYPE := NULL, in_value2 logs.arguments%TYPE := NULL,', +' in_name3 logs.arguments%TYPE := NULL, in_value3 logs.arguments%TYPE := NULL,', +' in_name4 logs.arguments%TYPE := NULL, in_value4 logs.arguments%TYPE := NULL,', +' in_name5 logs.arguments%TYPE := NULL, in_value5 logs.arguments%TYPE := NULL,', +' in_name6 logs.arguments%TYPE := NULL, in_value6 logs.arguments%TYPE := NULL,', +' in_name7 logs.arguments%TYPE := NULL, in_value7 logs.arguments%TYPE := NULL,', +' in_name8 logs.arguments%TYPE := NULL, in_value8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Same as log_module but with action_name, designated for APEX calls', +' --', +' FUNCTION log_action (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- ^', +' --', +' PROCEDURE log_action (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Store record in log with D flag', +' --', +' PROCEDURE log_debug (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload')) +); +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Store record in log with R flag', +' --', +' PROCEDURE log_result (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Store record in log with W flag; pass action_name', +' --', +' PROCEDURE log_warning (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Store record in log with E flag; pass action_name', +' --', +' FUNCTION log_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- ^', +' --', +' PROCEDURE log_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Update logs.timer for current/requested record', +' --', +' PROCEDURE log_success (', +' in_log_id logs.log_id%TYPE := NULL,', +' in_action_name logs.action_name%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Update logs.arguments for triggers so we can have module line with results', +' --', +' PROCEDURE log_success (', +' in_log_id logs.log_id%TYPE,', +' in_rows_inserted NUMBER,', +' in_rows_updated NUMBER,', +' in_rows_deleted NUMBER,', +' in_last_rowid VARCHAR2 := NULL,', +' in_payload logs.payload%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Same as log_module but designated for triggers', +' --', +' FUNCTION log_trigger (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Update/track progress for LONGOPS', +' --', +' PROCEDURE log_progress (', +' in_action_name logs.action_name%TYPE := NULL,', +' in_progress NUMBER := NULL, -- percentage (1 = 100%)', +' in_note VARCHAR2 := NULL,', +' in_parent_id logs.log_id%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Log business event', +' --', +' FUNCTION log_event (', +' in_event_id log_events.event_id%TYPE,', +' in_event_value log_events.event_value%TYPE := NULL,', +' in_parent_id logs.log_parent%TYPE := NULL', +' )', +' RETURN log_events.log_id%TYPE;', +'', +'', +'', +' --', +' -- Log business event', +' --', +' PROCEDURE log_event (', +' in_event_id log_events.event_id%TYPE,', +' in_event_value log_events.event_value%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Link one time scheduled jobs to specific log record (user)', +' --', +' PROCEDURE log_scheduler (', +' in_log_id logs.log_id%TYPE,', +' in_job_name VARCHAR2', +' );', +'', +'', +'', +' --', +' -- Proper way how to schedule one time jobs', +' --', +' PROCEDURE create_one_time_job (', +' in_job_name VARCHAR2,', +' in_statement VARCHAR2 := NULL,', +' in_comments VARCHAR2 := NULL,', +' in_priority PLS_INTEGER := NULL', +' );', +'', +'', +'', +' --', +' -- Internal function which creates records in logs table; returns assigned log_id', +' --', +' FUNCTION log__ (', +' in_flag logs.flag%TYPE,', +' in_module_name logs.module_name%TYPE := NULL,', +' in_module_line logs.module_line%TYPE := NULL,', +' in_action_name logs.action_name%TYPE := NULL,', +' in_arguments logs.arguments%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL,', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_app_id logs.app_id%TYPE := NULL,', +' in_page_id logs.page_id%TYPE := NULL,', +' in_user_id logs.user_id%TYPE := NULL,', +' in_session_id logs.session_id%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Check if we log current record or not', +' --', +' FUNCTION is_blacklisted (', +' in_row logs%ROWTYPE', +' )', +' RETURN BOOLEAN;', +'', +'', +'', +' --', +' -- Log error and RAISE app exception action_name|log_id; pass error_name for user in action', +' --', +' PROCEDURE raise_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_payload logs.payload%TYPE := NULL,', +' in_rollback BOOLEAN := FALSE', +' );', +'', +'', +'', +' --', +' -- Handling errors from/in APEX', +' --', +' FUNCTION handle_apex_error (', +' p_error APEX_ERROR.T_ERROR', +' )', +' RETURN APEX_ERROR.T_ERROR_RESULT;', +'', +'', +'', +' --', +' -- Purge old records from logs table', +' --', +' PROCEDURE purge_logs (', +' in_age PLS_INTEGER := NULL', +' );', +'', +'', +'', +' --', +' -- Purge specific log with all children', +' --', +' PROCEDURE purge_logs (', +' in_log_id logs.log_id%TYPE', +' );', +'', +'', +'', +' --', +' -- Purge specific day', +' --', +' PROCEDURE purge_logs (', +' in_date DATE', +' );', +'', +'', +'', +' --', +' -- Returns procedure name which called this function with possible offset', +' --', +' FUNCTION get_caller_name (', +' in_offset PLS_INTEGER := NULL', +' )', +' RETURN logs.module_name%TYPE;', +'', +'', +'', +' --', +' -- Returns procedure line which called this function with possible offset', +' --', +' FUNCTION get_caller_line (', +' in_offset PLS_INTEGER := NULL', +' )', +' RETURN logs.module_line%TYPE;', +'', +'', +'', +' --', +' -- Hashing function (internal use)', +' --', +' FUNCTION get_hash (', +' in_payload VARCHAR2', +' )', +' RETURN VARCHAR2', +' RESULT_CACHE;', +'', +'', +'', +' --', +' -- Returns clean call stack', +' --', +' FUNCTION get_call_stack (', +' in_offset PLS_INTEGER := NULL,', +' in_skip_others BOOLEAN := FALSE,', +' in_line_numbers BOOLEAN := TRUE,', +' in_splitter VARCHAR2 := CHR(10)', +' )', +' RETURN logs.payload%TYPE;', +'', +'', +'', +' --', +' -- Returns error stack', +' --', +' FUNCTION get_error_stack', +' RETURN logs.payload%TYPE;', +'', +'', +'', +' --', +' -- Remove some not interesting calls from call/error stacks', +' --', +' FUNCTION get_shorter_stack (', +' in_stack VARCHAR2', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Finds and returns root log_id for passed log_id', +' --', +' FUNCTION get_log_root (', +' in_log_id logs.log_id%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Returns log_id generated by current page request', +' --', +' FUNCTION get_log_request_id', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Returns log_id used by LOGS_TREE view', +' --', +' FUNCTION get_log_tree_id', +' RETURN logs.log_id%TYPE;', +'', +'', +'', +' --', +' -- Set log_id for LOGS_TREE view', +' --', +' PROCEDURE set_log_tree_id (', +' in_log_id logs.log_id%TYPE', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### DML Error Handling', +' --', +'', +' --', +' -- Creates MERGE query for selected _E$ table and row', +' --', +' FUNCTION get_dml_query (', +' in_log_id logs.log_id%TYPE,', +' in_table_name logs.module_name%TYPE,', +' in_table_rowid VARCHAR2,', +' in_operation CHAR -- [I|U|D]', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +' --', +' -- Maps existing DML errors to proper row in logs table', +' --', +' PROCEDURE process_dml_error (', +' in_log_id logs.log_id%TYPE,', +' in_error_table VARCHAR2, -- remove references to logs_dml_errors view', +' in_table_name VARCHAR2, -- because it can get invalidated too often', +' in_table_rowid VARCHAR2,', +' in_action_name VARCHAR2', +' );', +'', +'', +'', +' --', +' -- Drop DML error tables matching filter', +' --', +' PROCEDURE drop_dml_tables (', +' in_table_like logs.module_name%TYPE', +' );', +'', +'', +'', +' --', +' -- Recreates DML error tables matching filter', +' --', +' PROCEDURE create_dml_tables (', +' in_table_like logs.module_name%TYPE', +' );', +'', +'', +'', +' --', +' -- Merge all DML error tables (_E$) into single view', +' --', +' PROCEDURE create_dml_errors_view;', +'', +'', +'', +'', +'', +'', +'', +' -- ### Custom wrappers', +' --', +'', +' --', +' -- Call custom procedures to keep app specific changes out of this package', +' --', +' PROCEDURE call_custom_procedure (', +' in_name VARCHAR2 := NULL,', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL', +' );', +'', +'', +'', +' --', +' -- Call custom function to keep app specific changes out of this package', +' --', +' FUNCTION call_custom_function (', +' in_name VARCHAR2 := NULL,', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2;', +'', +'', +'', +'', +'', +'', +'', +' -- ### INIT', +' --', +'', +' --', +' -- Reload settings and clear callstack maps', +' --', +' PROCEDURE init;', +'', +'END;', +'/', +'', +'', +'CREATE OR REPLACE PACKAGE BODY "APP" AS', +'', +' recent_log_id logs.log_id%TYPE; -- for events', +' recent_request_id logs.log_id%TYPE; -- for tracking APEX requests', +' recent_tree_id logs.log_id%TYPE; -- for logs_tree view', +' --', +' map_tree app.arr_map_tree;', +' log_blacklist app.arr_log_setup := app.arr_log_setup();', +'', +' -- possible exception when parsing call stack', +' BAD_DEPTH EXCEPTION;', +' PRAGMA EXCEPTION_INIT(BAD_DEPTH, -64610);', +'', +' --', +' raise_error_procedure CONSTANT logs.module_name%TYPE := ''APP.RAISE_ERROR'';', +'', +'', +'', +'', +'', +' FUNCTION get_app_id', +' RETURN sessions.app_id%TYPE', +' AS', +' out_app_id sessions.app_id%TYPE;', +' BEGIN', +' IF APEX_APPLICATION.G_FLOW_ID = app.get_core_app_id() THEN', +' SELECT MIN(s.app_id) KEEP (DENSE_RANK FIRST ORDER BY s.updated_at DESC) INTO out_app_id', +' FROM sessions s', +' WHERE s.session_id = app.get_session_id()', +' AND s.app_id != app.get_core_app_id();', +' END IF;', +' --', +' RETURN COALESCE(out_app_id, APEX_APPLICATION.G_FLOW_ID, 0);', +' END;', +'', +'', +'', +' FUNCTION get_real_app_id', +' RETURN sessions.app_id%TYPE', +' AS', +' BEGIN', +' RETURN COALESCE(APEX_APPLICATION.G_FLOW_ID, 0);', +' END;', +'', +'', +'', +' FUNCTION get_core_app_id', +' RETURN sessions.app_id%TYPE', +' AS', +' BEGIN', +' RETURN COALESCE(app.core_app_id, 0);', +' END;', +'', +'', +'', +' FUNCTION get_user_id', +' RETURN users.user_id%TYPE', +' AS', +' BEGIN', +' RETURN COALESCE (', +' APEX_APPLICATION.G_USER,', +' SYS_CONTEXT(''USERENV'', ''SESSION_USER''),', +' USER', +' );', +' END;', +'', +'', +'', +' FUNCTION get_user_id (', +' in_user_login users.user_login%TYPE', +' )', +' RETURN users.user_id%TYPE', +' AS', +' out_user_id users.user_id%TYPE;', +' is_valid CHAR;', +' BEGIN', +' -- find existing record based on user_login', +' SELECT u.user_id INTO out_user_id', +' FROM users u', +' WHERE (u.user_login = in_user_login OR u.user_id = in_user_login);', +' --', +' RETURN out_user_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' -- try to shorten login if possible', +' out_user_id := LTRIM(RTRIM(', +' CONVERT(', +' CASE WHEN NVL(INSTR(in_user_login, ''@''), 0) > 0', +' THEN LOWER(in_user_login) -- emails lowercased', +' ELSE UPPER(in_user_login) END, -- otherwise uppercased', +' ''US7ASCII'') -- strip special chars', +' ));', +'', +' -- recheck for possible conflict', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM users u', +' WHERE u.user_id = out_user_id;', +' --', +' RETURN NULL; -- login not available', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN out_user_id;', +' END;', +' END;', +'', +'', +'', +' PROCEDURE set_user_id', +' ACCESSIBLE BY (', +' PACKAGE app,', +' PACKAGE app_ut', +' )', +' AS', +' v_user_id users.user_id%TYPE;', +' BEGIN', +' v_user_id := app.get_user_id(in_user_login => app.get_user_id()); -- convert user_login to user_id', +'', +' -- set session things', +' DBMS_SESSION.SET_IDENTIFIER(v_user_id); -- USERENV.CLIENT_IDENTIFIER', +' DBMS_APPLICATION_INFO.SET_CLIENT_INFO(v_user_id); -- CLIENT_INFO, v$', +'', +' -- overwrite current user in APEX', +' APEX_CUSTOM_AUTH.SET_USER (', +' p_user => v_user_id', +' );', +'', +' -- set session language', +' APEX_UTIL.SET_SESSION_LANG(app.get_user_lang());', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION get_user_name (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN users.user_name%TYPE', +' AS', +' out_name users.user_name%TYPE;', +' BEGIN', +' SELECT u.user_name INTO out_name', +' FROM users u', +' WHERE u.user_id = COALESCE(in_user_id, app.get_user_id());', +' --', +' RETURN out_name;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_user_login (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN users.user_login%TYPE', +' AS', +' out_user_login users.user_login%TYPE;', +' BEGIN', +' SELECT u.user_login INTO out_user_login', +' FROM users u', +' WHERE u.user_id = COALESCE(in_user_id, app.get_user_id());', +' --', +' RETURN out_user_login;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_user_lang', +' RETURN users.lang_id%TYPE', +' AS', +' out_lang users.lang_id%TYPE;', +' BEGIN', +' SELECT u.lang_id INTO out_lang', +' FROM users u', +' WHERE u.user_id = app.get_user_id();', +' --', +' RETURN out_lang;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION is_active_user (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN BOOLEAN', +' AS', +' is_valid CHAR;', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM users u', +' WHERE u.user_id = COALESCE(in_user_id, app.get_user_id())', +' AND u.is_active = ''Y'';', +' --', +' RETURN TRUE;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN FALSE;', +' END;', +'', +'', +'', +' FUNCTION is_active_user_y (', +' in_user_id users.user_id%TYPE := NULL', +' )', +' RETURN CHAR', +' AS', +' BEGIN', +' RETURN CASE WHEN app.is_active_user(in_user_id) THEN ''Y'' END;', +' END;', +'', +'', +'', +' FUNCTION is_developer (', +' in_user users.user_login%TYPE := NULL', +' )', +' RETURN BOOLEAN', +' AS', +' is_valid CHAR;', +' BEGIN', +' WITH u AS (', +' SELECT app.get_user_id() AS user_id FROM DUAL UNION ALL', +' SELECT app.get_user_login() FROM DUAL UNION ALL', +' SELECT in_user FROM DUAL', +' )', +' SELECT ''Y'' INTO is_valid', +' FROM apex_workspace_developers d', +' JOIN apex_applications a', +' ON a.workspace = d.workspace_name', +' JOIN u', +' ON UPPER(u.user_id) IN (UPPER(d.user_name), UPPER(d.email))', +' WHERE a.application_id = app.get_app_id()', +' AND d.is_application_developer = ''Yes''', +' AND d.account_locked = ''No''', +' AND ROWNUM = 1;', +' --', +' RETURN TRUE;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN FALSE;', +' END;', +'', +'', +'', +' FUNCTION is_developer_y (', +' in_user users.user_login%TYPE := NULL', +' )', +' RETURN CHAR', +' AS', +' BEGIN', +' RETURN CASE WHEN app.is_developer(in_user) THEN ''Y'' END;', +' END;', +'', +'', +'', +' FUNCTION is_debug_on', +' RETURN BOOLEAN', +' AS', +' BEGIN', +' RETURN APEX_APPLICATION.G_DEBUG;', +' END;', +'', +'', +'', +' FUNCTION get_owner (', +' in_app_id apps.app_id%TYPE := NULL', +' )', +' RETURN apex_applications.owner%TYPE', +' AS', +' out_owner apex_applications.owner%TYPE;', +' BEGIN', +' SELECT a.owner INTO out_owner', +' FROM apex_applications a', +' WHERE a.application_id = COALESCE(in_app_id, app.get_app_id());', +' --', +' RETURN out_owner;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN app.schema_owner;', +' END;', +'', +'', +'', +' PROCEDURE create_session', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' v_is_active users.is_active%TYPE;', +' v_user_login users.user_login%TYPE;', +' rec sessions%ROWTYPE;', +' BEGIN', +' --app.log_module();', +' --', +' v_user_login := app.get_user_id();', +' --', +' rec.app_id := app.get_app_id();', +' rec.user_id := v_user_login;', +' rec.session_id := app.get_session_id();', +' rec.created_at := SYSDATE;', +' rec.updated_at := rec.created_at;', +'', +' -- this procedure is starting point in APEX after successful authentication', +' -- prevent sessions for anonymous (unlogged) users', +' IF (UPPER(rec.user_id) IN (USER, app.anonymous_user, ''ORDS_PUBLIC_USER'', ''APEX_PUBLIC_USER'') OR NVL(rec.app_id, 0) = 0) THEN', +' RETURN;', +' END IF;', +'', +' -- check app availability', +' IF NOT app.is_developer() THEN', +' BEGIN', +' SELECT a.is_active INTO v_is_active', +' FROM apps a', +' WHERE a.app_id = rec.app_id', +' AND a.is_active = ''Y'';', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' app.raise_error(''APPLICATION_OFFLINE'');', +' END;', +' ELSE', +' -- create app record if developers login', +' BEGIN', +' SELECT a.is_active INTO v_is_active', +' FROM apps a', +' WHERE a.app_id = rec.app_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' app.log_warning(''CREATING_APP'', rec.app_id);', +' --', +' INSERT INTO apps (app_id, app_name, is_active, updated_by, updated_at)', +' SELECT', +' a.application_id,', +' a.application_name,', +' ''Y'',', +' rec.user_id,', +' rec.updated_at', +' FROM apex_applications a', +' WHERE a.application_id = rec.app_id;', +'', +' -- also add first pages into Navigation table', +' app_actions.nav_autoupdate();', +' --', +' UPDATE navigation n', +' SET n.order# = CASE', +' WHEN n.page_id = 0 THEN 599', +' ELSE TO_NUMBER(SUBSTR(TO_CHAR(n.page_id), 1, 3))', +' END', +' WHERE n.app_id = rec.app_id;', +' END;', +' END IF;', +'', +' -- adjust user_id in APEX, init session', +' DBMS_SESSION.CLEAR_IDENTIFIER();', +' DBMS_APPLICATION_INFO.SET_MODULE (', +' module_name => NULL,', +' action_name => NULL', +' );', +' --', +' app.init(); -- init setup, maps...', +' app.set_user_id(); -- convert user_login to user_id', +' rec.user_id := app.get_user_id(); -- update needed', +'', +' -- store log_id of the request for further reuse', +' recent_request_id := app.log_request();', +'', +' -- call app specific code (to create new user for example)', +' app.call_custom_procedure (', +' in_arg1 => v_user_login,', +' in_arg2 => rec.user_id', +' );', +'', +' -- check user', +' BEGIN', +' SELECT u.user_id, u.is_active INTO rec.user_id, v_is_active', +' FROM users u', +' WHERE u.user_id = app.get_user_id();', +' --', +' IF v_is_active IS NULL THEN', +' app.raise_error(''ACCOUNT_DISABLED'');', +' END IF;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' app.raise_error(''INVALID_USER'');', +' END;', +'', +' -- update session record, prevent app_id and user_id hijacking', +' UPDATE sessions s', +' SET s.updated_at = SYSDATE', +' WHERE s.app_id = rec.app_id', +' AND s.session_id = rec.session_id', +' AND s.user_id = rec.user_id', +' RETURNING s.created_at INTO rec.created_at;', +' --', +' IF SQL%ROWCOUNT = 0 THEN', +' BEGIN', +' INSERT INTO sessions VALUES rec;', +' EXCEPTION', +' WHEN DUP_VAL_ON_INDEX THEN', +' app.raise_error(''DUPE_SESSION''); -- redirect to logout/login page', +' END;', +' ELSIF TRUNC(rec.created_at) < TRUNC(rec.updated_at) THEN', +' -- avoid sessions spanning thru multiple days', +' FOR c IN (', +' SELECT s.session_id', +' FROM sessions s', +' WHERE s.app_id = rec.app_id', +' AND s.session_id = rec.session_id', +' ) LOOP', +' app.log_warning(''FORCED_SESSION'');', +' --', +' COMMIT;', +' --', +' APEX_UTIL.REDIRECT_URL(APEX_PAGE.GET_URL(p_session => 0)); -- force new login', +' END LOOP;', +' END IF;', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' ROLLBACK;', +' RAISE;', +' WHEN APEX_APPLICATION.E_STOP_APEX_ENGINE THEN', +' COMMIT;', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE create_session (', +' in_user_id sessions.user_id%TYPE,', +' in_app_id sessions.app_id%TYPE,', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_session_id sessions.session_id%TYPE := NULL,', +' in_items VARCHAR2 := NULL', +' ) AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' v_workspace_id apex_applications.workspace%TYPE;', +' v_user_name apex_workspace_sessions.user_name%TYPE;', +' BEGIN', +' app.log_module_json (', +' ''user_id'', in_user_id,', +' ''app_id'', in_app_id,', +' ''page_id'', in_page_id,', +' ''session_id'', in_session_id,', +' ''items'', in_items', +' );', +' --', +' v_user_name := in_user_id;', +'', +' -- create session from SQL Developer (not from APEX)', +' SELECT MAX(s.user_name) INTO v_user_name', +' FROM apex_workspace_sessions s', +' WHERE s.apex_session_id = COALESCE(in_session_id, app.get_session_id());', +' --', +' IF ((v_user_name = app.get_user_id() AND in_app_id = app.get_app_id()) OR in_session_id != app.get_session_id()) THEN', +' -- use existing session if possible', +' IF (in_session_id > 0 OR in_session_id IS NULL) THEN', +' BEGIN', +' APEX_SESSION.ATTACH (', +' p_app_id => app.get_app_id(),', +' p_page_id => NVL(in_page_id, 0),', +' p_session_id => COALESCE(in_session_id, app.get_session_id())', +' );', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''ATTACH_SESSION_FAILED'', in_app_id, v_user_name, COALESCE(in_session_id, app.get_session_id()));', +' END;', +' END IF;', +' ELSE', +' -- find and setup workspace', +' BEGIN', +' SELECT a.workspace INTO v_workspace_id', +' FROM apex_applications a', +' WHERE a.application_id = in_app_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' app.raise_error(''INVALID_APP'', in_app_id);', +' END;', +' --', +' APEX_UTIL.SET_WORKSPACE (', +' p_workspace => v_workspace_id', +' );', +' APEX_UTIL.SET_SECURITY_GROUP_ID (', +' p_security_group_id => APEX_UTIL.FIND_SECURITY_GROUP_ID(p_workspace => v_workspace_id)', +' );', +' END IF;', +'', +' -- set username', +' APEX_UTIL.SET_USERNAME (', +' p_userid => APEX_UTIL.GET_USER_ID(v_user_name),', +' p_username => v_user_name', +' );', +' --', +' IF in_user_id != v_user_name THEN', +' app.log_result(v_user_name);', +' END IF;', +'', +' -- create new APEX session', +' IF (app.get_session_id() IS NULL OR in_session_id = 0) THEN', +' BEGIN', +' APEX_SESSION.CREATE_SESSION (', +' p_app_id => in_app_id,', +' p_page_id => NVL(in_page_id, 0),', +' p_username => in_user_id', +' );', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''CREATE_SESSION_FAILED'', in_app_id, in_user_id);', +' END;', +' END IF;', +'', +' -- continue with standard process as from APEX', +' app.create_session();', +' --', +' IF in_items IS NOT NULL THEN', +' app.apply_items(in_items);', +' END IF;', +' --', +' app.log_success(recent_r')) +); +null; +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'equest_id);', +' --', +' DBMS_OUTPUT.PUT_LINE(''--'');', +' DBMS_OUTPUT.PUT_LINE(''SESSION: '' || app.get_app_id() || '' | '' || app.get_page_id() || '' | '' || app.get_session_id() || '' | '' || app.get_user_id());', +' DBMS_OUTPUT.PUT_LINE(''--'');', +'', +' -- print app and page items', +' FOR c IN (', +' SELECT', +' i.item_name,', +' app.get_item(i.item_name) AS item_value', +' FROM apex_application_items i', +' WHERE i.application_id = in_app_id', +' UNION ALL', +' SELECT', +' i.item_name,', +' app.get_item(i.item_name) AS item_value', +' FROM apex_application_page_items i', +' WHERE i.application_id = in_app_id', +' AND i.page_id = in_page_id', +' ORDER BY 1', +' ) LOOP', +' IF c.item_value IS NOT NULL THEN', +' DBMS_OUTPUT.PUT_LINE('' '' || RPAD(c.item_name, 30) || '' = '' || c.item_value);', +' END IF;', +' END LOOP;', +' DBMS_OUTPUT.PUT_LINE(''--'');', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' ROLLBACK;', +' RAISE;', +' WHEN APEX_APPLICATION.E_STOP_APEX_ENGINE THEN', +' COMMIT;', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE exit_session', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' -- call app specific code', +' app.call_custom_procedure();', +'', +' DBMS_SESSION.CLEAR_IDENTIFIER();', +' --DBMS_SESSION.CLEAR_ALL_CONTEXT(namespace);', +' --DBMS_SESSION.RESET_PACKAGE; -- avoid ORA-04068 exception', +' --', +' DBMS_APPLICATION_INFO.SET_MODULE (', +' module_name => NULL,', +' action_name => NULL', +' );', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' ROLLBACK;', +' RAISE;', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE delete_session (', +' in_session_id sessions.session_id%TYPE', +' ) AS', +' v_log_id logs.log_id%TYPE;', +' v_rows_to_delete app.arr_logs_log_id;', +' BEGIN', +' v_log_id := app.log_module();', +' --', +' SELECT l.log_id', +' BULK COLLECT INTO v_rows_to_delete', +' FROM logs l', +' WHERE l.session_id = in_session_id;', +' --', +' IF v_rows_to_delete.FIRST IS NOT NULL THEN', +' FOR i IN v_rows_to_delete.FIRST .. v_rows_to_delete.LAST LOOP', +' CONTINUE WHEN v_rows_to_delete(i) = v_log_id;', +' --', +' DELETE FROM log_events WHERE log_parent = v_rows_to_delete(i);', +' DELETE FROM logs WHERE log_id = v_rows_to_delete(i);', +' END LOOP;', +' END IF;', +' --', +' IF in_session_id != app.get_session_id() THEN', +' DELETE FROM sessions s', +' WHERE s.session_id = in_session_id;', +' --', +' -- may throw ORA-20987: APEX - Your session has ended', +' -- not even others handler can capture this', +' --APEX_SESSION.DELETE_SESSION(in_session_id);', +' --', +' -- @TODO: maybe schedule/dettach this as a job', +' --', +' END IF;', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE set_session (', +' in_module_name logs.module_name%TYPE,', +' in_action_name logs.action_name%TYPE,', +' in_log_id logs.log_id%TYPE := NULL', +' ) AS', +' v_action_name logs.action_name%TYPE;', +' BEGIN', +' v_action_name := SUBSTR(TO_CHAR(NVL(recent_request_id, 0)) || ''|'' || TO_CHAR(in_log_id) || ''|'' || in_action_name, 1, app.length_action);', +' --', +' IF in_module_name IS NOT NULL THEN', +' DBMS_APPLICATION_INFO.SET_MODULE(in_module_name, v_action_name); -- USERENV.MODULE, USERENV.ACTION', +' END IF;', +' --', +' IF in_action_name IS NOT NULL THEN', +' DBMS_APPLICATION_INFO.SET_ACTION(v_action_name); -- USERENV.ACTION', +' END IF;', +' END;', +'', +'', +'', +' FUNCTION get_session_id', +' RETURN sessions.session_id%TYPE', +' AS', +' BEGIN', +' RETURN SYS_CONTEXT(''APEX$SESSION'', ''APP_SESSION''); -- APEX_APPLICATION.G_INSTANCE', +' END;', +'', +'', +'', +' FUNCTION get_client_id (', +' in_user_id sessions.user_id%TYPE := NULL', +' )', +' RETURN VARCHAR2 AS -- mimic APEX client_id', +' BEGIN', +' RETURN', +' COALESCE(in_user_id, app.get_user_id()) || '':'' ||', +' COALESCE(app.get_session_id(), SYS_CONTEXT(''USERENV'', ''SESSIONID'')', +' );', +' END;', +'', +'', +'', +' FUNCTION get_env_name', +' RETURN VARCHAR2', +' AS', +' out_name VARCHAR2(4000);', +' BEGIN', +' out_name := out_name || ''Environment: '' || SYS_CONTEXT(''USERENV'', ''SERVER_HOST'') || CHR(10);', +' out_name := out_name || ''Instance: '' || SYS_CONTEXT(''USERENV'', ''INSTANCE_NAME'') || CHR(10);', +' --', +' IF app.is_developer() THEN', +' -- details for developers', +' SELECT', +' out_name ||', +' ''Oracle APEX: '' || a.version_no || CHR(10) ||', +' ''Oracle DB: '' || p.version_full', +' INTO out_name', +' FROM apex_release a', +' CROSS JOIN product_component_version p;', +' END IF;', +' --', +' RETURN app.get_icon(''fa-window-bookmark'', out_name);', +' END;', +'', +'', +'', +' FUNCTION get_role_name (', +' in_role_id roles.role_id%TYPE', +' )', +' RETURN roles.role_name%TYPE', +' AS', +' out_name roles.role_name%TYPE;', +' BEGIN', +' SELECT NVL(r.role_name, r.role_id) INTO out_name', +' FROM roles r', +' WHERE r.app_id = app.get_app_id()', +' AND r.role_id = in_role_id;', +' --', +' RETURN out_name;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN in_role_id;', +' END;', +'', +'', +'', +' FUNCTION get_page_id', +' RETURN navigation.page_id%TYPE', +' AS', +' BEGIN', +' RETURN APEX_APPLICATION.G_FLOW_STEP_ID;', +' END;', +'', +'', +'', +' FUNCTION get_page_group (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN apex_application_pages.page_group%TYPE', +' AS', +' out_name apex_application_pages.page_group%TYPE;', +' BEGIN', +' SELECT p.page_group INTO out_name', +' FROM apex_application_pages p', +' WHERE p.application_id = COALESCE(in_app_id, app.get_app_id())', +' AND p.page_id = COALESCE(in_page_id, app.get_page_id());', +' --', +' RETURN out_name;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_page_root (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN navigation.page_id%TYPE', +' AS', +' out_id apex_application_pages.page_id%TYPE;', +' BEGIN', +' SELECT REGEXP_SUBSTR(MAX(SYS_CONNECT_BY_PATH(n.page_id, ''/'')), ''[0-9]+$'') INTO out_id', +' FROM navigation n', +' WHERE n.app_id = COALESCE(in_app_id, app.get_app_id())', +' CONNECT BY n.app_id = PRIOR n.app_id', +' AND n.page_id = PRIOR n.parent_id', +' START WITH n.page_id = COALESCE(in_page_id, app.get_page_id());', +' --', +' RETURN out_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_page_parent (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN navigation.page_id%TYPE', +' AS', +' out_id apex_application_pages.page_id%TYPE;', +' BEGIN', +' SELECT n.parent_id INTO out_id', +' FROM navigation n', +' WHERE n.app_id = COALESCE(in_app_id, app.get_app_id())', +' AND n.page_id = COALESCE(in_page_id, app.get_page_id());', +' --', +' RETURN out_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_page_name (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL,', +' in_name VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' out_name apex_application_pages.page_name%TYPE := in_name;', +' out_search apex_application_pages.page_name%TYPE;', +' BEGIN', +' IF in_name IS NULL THEN', +' SELECT p.page_name INTO out_name', +' FROM apex_application_pages p', +' WHERE p.application_id = COALESCE(in_app_id, app.get_app_id())', +' AND p.page_id = COALESCE(in_page_id, app.get_page_id());', +' END IF;', +'', +' -- transform icons', +' FOR i IN 1 .. NVL(REGEXP_COUNT(out_name, ''(#fa-)''), 0) LOOP', +' out_search := REGEXP_SUBSTR(out_name, ''(#fa-[[:alnum:]+_-]+\s*)+'');', +' out_name := REPLACE(', +' out_name,', +' out_search,', +' '' &'' || ''nbsp; &'' || ''nbsp; ''', +' );', +' END LOOP;', +'', +' -- custom name conversion', +' out_name := NVL(app.call_custom_function(NULL, out_name), out_name);', +' --', +' RETURN REGEXP_REPLACE(out_name, ''((^\s*&'' || ''nbsp;\s*)|(\s*&'' || ''nbsp;\s*$))'', ''''); -- trim hard spaces', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_page_link (', +' in_page_id navigation.page_id%TYPE := NULL,', +' in_app_id navigation.app_id%TYPE := NULL,', +' in_names VARCHAR2 := NULL,', +' in_values VARCHAR2 := NULL,', +' in_overload VARCHAR2 := NULL, -- JSON object to overload passed items/values', +' in_transform BOOLEAN := FALSE, -- to pass all page items to new page', +' in_reset BOOLEAN := TRUE, -- reset page items', +' in_session_id sessions.session_id%TYPE := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' out_page_id navigation.page_id%TYPE := COALESCE(in_page_id, app.get_page_id());', +' out_names VARCHAR2(32767) := in_names;', +' out_values VARCHAR2(32767) := in_values;', +' BEGIN', +' -- autofill missing values', +' IF in_names IS NOT NULL AND in_values IS NULL THEN', +' FOR c IN (', +' SELECT item_name', +' FROM (', +' SELECT DISTINCT REGEXP_SUBSTR(in_names, ''[^,]+'', 1, LEVEL) AS item_name, LEVEL AS order#', +' FROM DUAL', +' CONNECT BY LEVEL <= REGEXP_COUNT(in_names, '','') + 1', +' )', +' ORDER BY order# DESC', +' ) LOOP', +' out_values := app.get_item(c.item_name) || '','' || out_values;', +' END LOOP;', +' END IF;', +'', +'/*', +' -- get page items with not null values', +' FOR c IN (', +' SELECT', +' p.item_name,', +' app.get_item(p.item_name) AS item_value', +' FROM apex_application_page_items p', +' WHERE p.application_id = app.get_app_id()', +' AND p.page_id = COALESCE(in_page_id, app.get_page_id())', +' AND app.get_item(p.item_name) IS NOT NULL', +' ) LOOP', +' out_names := out_names || c.item_name || '','';', +' out_values := out_values || c.item_value || '','';', +' END LOOP;', +'', +'', +' -- check existance of reset item on target page', +' SELECT MAX(i.item_name) INTO reset_item', +' FROM apex_application_page_items i', +' WHERE i.application_id = app.get_app_id()', +' AND i.page_id = out_page_id', +' AND i.item_name = ''P'' || out_page_id || ''_RESET'';', +'', +' -- auto add reset item to args if not passed already', +' IF reset_item IS NOT NULL AND NVL(INSTR(out_names, reset_item), 0) = 0 THEN', +' out_names := reset_item || '','' || out_names;', +' out_values := ''Y,'' || out_values;', +' END IF;', +'', +'*/', +'', +' -- generate url', +' RETURN APEX_PAGE.GET_URL (', +' p_application => in_app_id,', +' p_session => COALESCE(in_session_id, app.get_session_id()),', +' p_page => out_page_id,', +' p_clear_cache => CASE WHEN in_reset THEN out_page_id END,', +' p_items => out_names,', +' p_values => out_values', +' /*', +' p_session IN NUMBER DEFAULT APEX.G_INSTANCE,', +' p_request IN VARCHAR2 DEFAULT NULL,', +' p_debug IN VARCHAR2 DEFAULT NULL,', +' p_clear_cache IN VARCHAR2 DEFAULT NULL,', +' p_items IN VARCHAR2 DEFAULT NULL,', +' p_values IN VARCHAR2 DEFAULT NULL,', +' p_printer_friendly IN VARCHAR2 DEFAULT NULL,', +' p_trace IN VARCHAR2 DEFAULT NULL, ', +' p_triggering_element IN VARCHAR2 DEFAULT ''this'',', +' p_plain_url IN BOOLEAN DEFAULT FALSE )', +' */', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION get_request_url (', +' in_arguments_only BOOLEAN := FALSE', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN CASE WHEN NOT in_arguments_only', +' THEN UTL_URL.UNESCAPE (', +' OWA_UTIL.GET_CGI_ENV(''SCRIPT_NAME'') ||', +' OWA_UTIL.GET_CGI_ENV(''PATH_INFO'') || ''?''', +' ) END ||', +' UTL_URL.UNESCAPE(OWA_UTIL.GET_CGI_ENV(''QUERY_STRING''));', +' EXCEPTION', +' WHEN OTHERS THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_request', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN APEX_APPLICATION.G_REQUEST;', +' END;', +'', +'', +'', +' FUNCTION get_icon (', +' in_name VARCHAR2,', +' in_title VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN '''';', +' END;', +'', +'', +'', +' FUNCTION is_page_available (', +' in_page_id navigation.page_id%TYPE,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN CHAR', +' AS', +' v_auth_name apex_application_pages.authorization_scheme%TYPE;', +' v_proc_name user_procedures.procedure_name%TYPE;', +' v_arg_name user_arguments.argument_name%TYPE;', +' --', +' out_result CHAR;', +' --', +' PRAGMA UDF; -- SQL only', +' BEGIN', +' BEGIN', +' SELECT', +' p.authorization_scheme,', +' s.procedure_name,', +' a.argument_name', +' INTO v_auth_name, v_proc_name, v_arg_name', +' FROM apex_application_pages p', +' LEFT JOIN user_procedures s', +' ON s.object_name = app.auth_package', +' AND s.procedure_name = p.authorization_scheme', +' LEFT JOIN user_arguments a', +' ON a.object_name = s.procedure_name', +' AND a.package_name = s.object_name', +' AND a.overload IS NULL', +' AND a.position = 1', +' AND a.argument_name = app.auth_page_id_arg', +' AND a.data_type = ''NUMBER''', +' AND a.in_out = ''IN''', +' WHERE p.application_id = COALESCE(in_app_id, app.get_app_id())', +' AND p.page_id = in_page_id', +' AND REGEXP_LIKE(p.authorization_scheme_id, ''^(\d+)$''); -- user auth schemes only', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN ''Y''; -- show, page has no authorization set', +' END;', +' --', +' IF v_proc_name IS NULL THEN', +' app.log_warning(''AUTH_PROCEDURE_MISSING'', v_auth_name);', +' RETURN ''N''; -- hide, auth function is set on page but missing in AUTH package', +' END IF;', +'', +' -- call function to evaluate access', +' IF v_arg_name IS NOT NULL THEN', +' -- pass page_id when neeeded', +' EXECUTE IMMEDIATE', +' ''BEGIN :r := '' || app.auth_package || ''.'' || v_proc_name || ''(:page_id); END;''', +' USING IN in_page_id, OUT out_result;', +' ELSE', +' EXECUTE IMMEDIATE', +' ''BEGIN :r := '' || app.auth_package || ''.'' || v_proc_name || ''; END;''', +' USING OUT out_result;', +' END IF;', +' --', +' RETURN NVL(out_result, ''N'');', +' END;', +'', +'', +'', +' FUNCTION is_page_visible (', +' in_page_id navigation.page_id%TYPE,', +' in_app_id navigation.app_id%TYPE := NULL', +' )', +' RETURN CHAR', +' AS', +' is_valid CHAR;', +' --', +' PRAGMA UDF; -- SQL only', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM navigation n', +' WHERE n.app_id = COALESCE(in_app_id, app.get_app_id())', +' AND n.page_id = COALESCE(in_page_id, app.get_page_id())', +' AND n.is_hidden IS NULL;', +' --', +' RETURN is_valid;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN ''N'';', +' END;', +'', +'', +'', +' PROCEDURE redirect (', +' in_page_id NUMBER := NULL,', +' in_names VARCHAR2 := NULL,', +' in_values VARCHAR2 := NULL,', +' in_overload VARCHAR2 := NULL, -- JSON object to overload passed items/values', +' in_transform BOOLEAN := FALSE, -- to pass all page items to new page', +' in_reset BOOLEAN := TRUE -- reset page items', +' ) AS', +' out_target VARCHAR2(32767);', +' BEGIN', +' -- commit otherwise anything before redirect will be rolled back', +' COMMIT;', +'', +' -- check if we are in APEX or not', +' HTP.INIT;', +' out_target := app.get_page_link (', +' in_page_id => in_page_id,', +' in_names => in_names,', +' in_values => in_values,', +' in_overload => in_overload,', +' in_transform => in_transform,', +' in_reset => in_reset', +' );', +' --', +' app.log_debug(''REDIRECT'', app.get_json_list(in_page_id, in_names, in_values, out_target));', +' --', +' APEX_UTIL.REDIRECT_URL(out_target); -- OWA_UTIL not working on Cloud', +' --', +' APEX_APPLICATION.STOP_APEX_ENGINE;', +' --', +' -- EXCEPTION', +' -- WHEN APEX_APPLICATION.E_STOP_APEX_ENGINE THEN', +' --', +' END;', +'', +'', +'', +' FUNCTION get_item_name (', +' in_name VARCHAR2', +' )', +' RETURN VARCHAR2', +' AS', +' v_item_name apex_application_page_items.item_name%TYPE;', +' is_valid CHAR;', +' BEGIN', +' v_item_name := REPLACE(in_name, app.page_item_wild, app.page_item_prefix || app.get_page_id() || ''_'');', +'', +' -- check if item exists', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM apex_application_page_items p', +' WHERE p.application_id = app.get_real_app_id()', +' AND p.page_id = app.get_page_id()', +' AND p.item_name = v_item_name;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM apex_application_items g', +' WHERE g.application_id = app.get_real_app_id()', +' AND g.item_name = in_name;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +' END;', +' --', +' RETURN v_item_name;', +' END;', +'', +'', +'', +' FUNCTION get_item (', +' in_name VARCHAR2,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN VARCHAR2', +' AS', +' v_item_name apex_application_page_items.item_name%TYPE;', +' BEGIN', +' v_item_name := app.get_item_name(in_name);', +'', +' -- check item existence to avoid hidden errors', +' IF v_item_name IS NOT NULL THEN', +' RETURN APEX_UTIL.GET_SESSION_STATE(v_item_name);', +' ELSIF in_raise THEN', +' app.raise_error(''ITEM_MISSING'', v_item_name);', +' END IF;', +' --', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_number_item (', +' in_name VARCHAR2,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN NUMBER', +' AS', +' BEGIN', +' RETURN TO_NUMBER(app.get_item(in_name, in_raise));', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''INVALID_NUMBER'', in_name, app.get_item(in_name, in_raise));', +' END;', +'', +'', +'', +' FUNCTION get_date_item (', +' in_name VARCHAR2,', +' in_format VARCHAR2 := NULL,', +' in_raise BOOLEAN := FALSE', +' )', +' RETURN DATE', +' AS', +' BEGIN', +' RETURN app.get_date(app.get_item(in_name, in_raise), in_format);', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''INVALID_DATE'', in_name, app.get_item(in_name, in_raise), in_format);', +' END;', +'', +'', +'', +' FUNCTION get_date (', +' in_value VARCHAR2,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN DATE', +' AS', +' l_value VARCHAR2(30) := SUBSTR(REPLACE(in_value, ''T'', '' ''), 1, 30);', +' BEGIN', +' IF in_format IS NOT NULL THEN', +' BEGIN', +' RETURN TO_DATE(l_value, in_format);', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''INVALID_DATE'', in_value, in_format);', +' END;', +' END IF;', +'', +' -- try different formats', +' BEGIN', +' RETURN TO_DATE(l_value, app.format_date_time); -- YYYY-MM-DD HH24:MI:SS', +' EXCEPTION', +' WHEN OTHERS THEN', +' BEGIN', +' RETURN TO_DATE(l_value, app.format_date_short); -- YYYY-MM-DD HH24:MI', +' EXCEPTION', +' WHEN OTHERS THEN', +' BEGIN', +' RETURN TO_DATE(SUBSTR(l_value, 1, 10), app.format_date); -- YYYY-MM-DD', +' EXCEPTION', +' WHEN OTHERS THEN', +' BEGIN', +' RETURN TO_DATE(SUBSTR(REPLACE(l_value, ''.'', ''/''), 1, 10), ''DD/MM/YYYY'');', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''INVALID_DATE'', in_value, in_format);', +' END;', +' END;', +' END;', +' END;', +' END;', +'', +'', +'', +' FUNCTION get_date (', +' in_date DATE := NULL,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN TO_CHAR(COALESCE(in_date, SYSDATE), NVL(in_format, app.format_date));', +' END;', +'', +'', +'', +' FUNCTION get_date_time (', +' in_date DATE := NULL,', +' in_format VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN TO_CHAR(COALESCE(in_date, SYSDATE), NVL(in_format, app.format_date_time));', +' END;', +'', +'', +'', +' FUNCTION get_time_bucket (', +' in_date DATE,', +' in_interval NUMBER', +' )', +' RETURN NUMBER', +' RESULT_CACHE', +' AS', +' PRAGMA UDF;', +' BEGIN', +' RETURN FLOOR((in_date - TRUNC(in_date)) * 1440 / in_interval) + 1;', +' END;', +'', +'', +'', +' FUNCTION get_duration (', +' in_interval INTERVAL DAY TO SECOND', +' )', +' RETURN VARCHAR2 AS', +' BEGIN', +' RETURN REGEXP_SUBSTR(in_interval, ''(\d{2}:\d{2}:\d{2}\.\d{3})'');', +' END;', +'', +'', +'', +' FUNCTION get_duration (', +' in_interval NUMBER', +' )', +' RETURN VARCHAR2 AS', +' BEGIN', +' RETURN TO_CHAR(TRUNC(SYSDATE) + in_interval, ''HH24:MI:SS'');', +' END;', +'', +'', +'', +' FUNCTION get_duration (', +' in_start TIMESTAMP,', +' in_end TIMESTAMP := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' v_end CONSTANT logs.created_at%TYPE := SYSTIMESTAMP; -- to prevent timezone shift, APEX_UTIL.GET_SESSION_TIME_ZONE', +' BEGIN', +' RETURN SUBSTR(TO_CHAR(COALESCE(in_end, v_end) - in_start), 12, 12); -- keep 00:00:00.000', +' END;', +'', +'', +'', +' PROCEDURE set_item (', +' in_name VARCHAR2,', +' in_value VARCHAR2 := NULL,', +' in_raise BOOLEAN := TRUE', +' )', +' AS', +' v_item_name apex_application_page_items.item_name%TYPE;', +' BEGIN', +' v_item_name := app.get_item_name(in_name);', +' --', +' IF v_item_name IS NOT NULL THEN', +' BEGIN', +' APEX_UTIL.SET_SESSION_STATE (', +' p_name => v_item_name,', +' p_value => in_value,', +' p_commit => FALSE', +' );', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''ITEM_MISSING'', v_item_name);', +' END;', +' ELSIF in_raise THEN', +' app.raise_error(''ITEM_MISSING'', v_item_name);', +' END IF;', +' END;', +'', +'', +'', +' PROCEDURE set_date_item (', +' in_name VARCHAR2,', +' in_value DATE,', +' in_raise BOOLEAN := TRUE', +' )', +' AS', +' BEGIN', +' app.set_item (', +' in_name => in_name,', +' in_value => TO_CHAR(in_value, app.format_date_time),', +' in_raise => in_raise', +' );', +' END;', +'', +'', +'', +' PROCEDURE clear_items', +' AS', +' req VARCHAR2(32767) := app.get_request_url();', +' BEGIN', +' -- delete page items one by one, except items passed in url (query string)', +' FOR c IN (', +' SELECT i.item_name', +' FROM apex_application_page_items i', +' WHERE i.application_id = app.get_app_id()', +' AND i.page_id = app.get_page_id()', +' AND (', +' NOT REGEXP_LIKE(req, ''[:,]'' || i.item_name || ''[,:]'') -- for legacy', +' AND NOT REGEXP_LIKE(req, LOWER(i.item_name) || ''[=&]'') -- for friendly url', +' )', +' ) LOOP', +' app.set_item (', +' in_name => c.item_name,', +' in_value => NULL,', +' in_raise => FALSE', +' );', +' END LOOP;', +' END;', +'', +'', +'', +' FUNCTION get_page_items (', +' in_page_id logs.page_id%TYPE := NULL,', +' in_filter logs.arguments%TYPE := ''%''', +' )', +' RETURN VARCHAR2', +' AS', +' out_payload VARCHAR2(32767);', +' BEGIN', +' SELECT JSON_OBJECTAGG(t.item_name VALUE APEX_UTIL.GET_SESSION_STATE(t.item_name) ABSENT ON NULL)', +' INTO out_payload', +' FROM apex_application_page_items t', +' WHERE t.application_id = app.get_real_app_id()', +' AND t.page_id = COALESCE(in_page_id, app.get_page_id())', +' AND t.item_name LIKE in_filter;', +' --', +' RETURN out_payload;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_global_items (', +' in_filter logs.arguments%TYPE := ''%''', +' )', +' RETURN VARCHAR2', +' AS', +' out_payload VARCHAR2(32767);', +' BEGIN', +' SELECT JSON_OBJECTAGG(t.item_name VALUE APEX_UTIL.GET_SESSION_STATE(t.item_name) ABSENT ON NULL)', +' INTO out_payload', +' FROM apex_application_items t', +' WHERE t.application_id = app.get_real_app_id()', +' AND t.item_name LIKE in_filter;', +' --', +' RETURN out_payload;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' PROCEDURE apply_items (', +' in_items VARCHAR2', +' )', +' AS', +' json_keys JSON_KEY_LIST;', +' BEGIN', +' IF in_items IS NULL THEN', +' RETURN;', +' END IF;', +' --', +' json_keys := JSON_OBJECT_T(in_items).get_keys();', +' --', +' FOR i IN 1 .. json_keys.COUNT LOOP', +' BEGIN', +' app.set_item(json_keys(i), JSON_VALUE(in_items, ''$.'' || json_keys(i)));', +' EXCEPTION', +' WHEN OTHERS THEN', +' NULL;', +' END;', +' END LOOP;', +' END;', +'', +'', +'', +' FUNCTION get_json_list (', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL,', +' in_arg5 VARCHAR2 := NULL,', +' in_arg6 VARCHAR2 := NULL,', +' in_arg7 VARCHAR2 := NULL,', +' in_arg8 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN NULLIF(REGEXP_REPLACE(', +' REGEXP_REPLACE(', +' NULLIF(JSON_ARRAY(in_arg1, in_arg2, in_arg')) +); +null; +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'3, in_arg4, in_arg5, in_arg6, in_arg7, in_arg8 NULL ON NULL), ''[]''),', +' ''"(\d+)([.,]\d+)?"'', ''\1\2'' -- convert to numbers if possible', +' ),', +' ''(,null)+\]$'', '']''), -- strip NULLs from the right side', +' ''[null]'');', +' END;', +'', +'', +'', +' FUNCTION get_json_object (', +' in_name1 VARCHAR2 := NULL, in_value1 VARCHAR2 := NULL,', +' in_name2 VARCHAR2 := NULL, in_value2 VARCHAR2 := NULL,', +' in_name3 VARCHAR2 := NULL, in_value3 VARCHAR2 := NULL,', +' in_name4 VARCHAR2 := NULL, in_value4 VARCHAR2 := NULL,', +' in_name5 VARCHAR2 := NULL, in_value5 VARCHAR2 := NULL,', +' in_name6 VARCHAR2 := NULL, in_value6 VARCHAR2 := NULL,', +' in_name7 VARCHAR2 := NULL, in_value7 VARCHAR2 := NULL,', +' in_name8 VARCHAR2 := NULL, in_value8 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' v_obj JSON_OBJECT_T;', +' BEGIN', +' -- construct a key-value pairs', +' v_obj := JSON_OBJECT_T(JSON_OBJECT (', +' CASE WHEN (in_name1 IS NULL OR in_value1 IS NULL) THEN ''__'' ELSE in_name1 END VALUE in_value1,', +' CASE WHEN (in_name2 IS NULL OR in_value2 IS NULL) THEN ''__'' ELSE in_name2 END VALUE in_value2,', +' CASE WHEN (in_name3 IS NULL OR in_value3 IS NULL) THEN ''__'' ELSE in_name3 END VALUE in_value3,', +' CASE WHEN (in_name4 IS NULL OR in_value4 IS NULL) THEN ''__'' ELSE in_name4 END VALUE in_value4,', +' CASE WHEN (in_name5 IS NULL OR in_value5 IS NULL) THEN ''__'' ELSE in_name5 END VALUE in_value5,', +' CASE WHEN (in_name6 IS NULL OR in_value6 IS NULL) THEN ''__'' ELSE in_name6 END VALUE in_value6,', +' CASE WHEN (in_name7 IS NULL OR in_value7 IS NULL) THEN ''__'' ELSE in_name7 END VALUE in_value7,', +' CASE WHEN (in_name8 IS NULL OR in_value8 IS NULL) THEN ''__'' ELSE in_name8 END VALUE in_value8', +' ));', +' v_obj.REMOVE(''__''); -- remove empty pairs', +' --', +' RETURN NULLIF(v_obj.STRINGIFY, ''{}'');', +' END;', +'', +'', +'', +' FUNCTION log_request', +' RETURN logs.log_id%TYPE', +' AS', +' v_args logs.arguments%TYPE;', +' BEGIN', +' map_tree := app.arr_map_tree();', +'', +' -- parse arguments', +' v_args := app.get_request_url(in_arguments_only => TRUE);', +' --', +' IF v_args IS NOT NULL THEN', +' BEGIN', +' SELECT JSON_OBJECTAGG (', +' REGEXP_REPLACE(REGEXP_SUBSTR(v_args, ''[^&]+'', 1, LEVEL), ''[=].*$'', '''')', +' VALUE REGEXP_REPLACE(REGEXP_SUBSTR(v_args, ''[^&]+'', 1, LEVEL), ''^[^=]+[=]'', '''')', +' ) INTO v_args', +' FROM DUAL', +' CONNECT BY LEVEL <= REGEXP_COUNT(v_args, ''&'') + 1', +' ORDER BY LEVEL;', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.log_error(''JSON_ERROR'', v_args);', +' END;', +' END IF;', +'', +' -- create log', +' RETURN app.log__ (', +' in_flag => app.flag_request,', +' in_action_name => app.get_request(),', +' in_arguments => v_args,', +' in_payload => NULL', +' );', +' END;', +'', +'', +'', +' FUNCTION log_module (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN app.log__ (', +' in_flag => app.flag_module,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_module (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_module,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' FUNCTION log_module_json (', +' in_name1 logs.arguments%TYPE := NULL, in_value1 logs.arguments%TYPE := NULL,', +' in_name2 logs.arguments%TYPE := NULL, in_value2 logs.arguments%TYPE := NULL,', +' in_name3 logs.arguments%TYPE := NULL, in_value3 logs.arguments%TYPE := NULL,', +' in_name4 logs.arguments%TYPE := NULL, in_value4 logs.arguments%TYPE := NULL,', +' in_name5 logs.arguments%TYPE := NULL, in_value5 logs.arguments%TYPE := NULL,', +' in_name6 logs.arguments%TYPE := NULL, in_value6 logs.arguments%TYPE := NULL,', +' in_name7 logs.arguments%TYPE := NULL, in_value7 logs.arguments%TYPE := NULL,', +' in_name8 logs.arguments%TYPE := NULL, in_value8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN app.log__ (', +' in_flag => app.flag_module,', +' in_arguments => app.get_json_object (', +' in_name1, in_value1,', +' in_name2, in_value2,', +' in_name3, in_value3,', +' in_name4, in_value4,', +' in_name5, in_value5,', +' in_name6, in_value6,', +' in_name7, in_value7,', +' in_name8, in_value8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_module_json (', +' in_name1 logs.arguments%TYPE := NULL, in_value1 logs.arguments%TYPE := NULL,', +' in_name2 logs.arguments%TYPE := NULL, in_value2 logs.arguments%TYPE := NULL,', +' in_name3 logs.arguments%TYPE := NULL, in_value3 logs.arguments%TYPE := NULL,', +' in_name4 logs.arguments%TYPE := NULL, in_value4 logs.arguments%TYPE := NULL,', +' in_name5 logs.arguments%TYPE := NULL, in_value5 logs.arguments%TYPE := NULL,', +' in_name6 logs.arguments%TYPE := NULL, in_value6 logs.arguments%TYPE := NULL,', +' in_name7 logs.arguments%TYPE := NULL, in_value7 logs.arguments%TYPE := NULL,', +' in_name8 logs.arguments%TYPE := NULL, in_value8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_module,', +' in_arguments => app.get_json_object (', +' in_name1, in_value1,', +' in_name2, in_value2,', +' in_name3, in_value3,', +' in_name4, in_value4,', +' in_name5, in_value5,', +' in_name6, in_value6,', +' in_name7, in_value7,', +' in_name8, in_value8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' FUNCTION log_action (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN app.log__ (', +' in_flag => app.flag_action,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_action (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_action,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_debug (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_debug,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_result (', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_result,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_warning (', +' in_action_name logs.action_name%TYPE,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_warning,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' FUNCTION log_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN app.log__ (', +' in_flag => app.flag_error,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_error,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_success (', +' in_log_id logs.log_id%TYPE := NULL,', +' in_action_name logs.action_name%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' -- mark module success by updating timer', +' UPDATE logs l', +' SET l.action_name = NVL(in_action_name, l.action_name),', +' l.payload = NVL(in_payload, l.payload),', +' l.module_timer = app.get_duration(in_start => l.created_at)', +' WHERE l.log_id = NVL(in_log_id, recent_log_id);', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE log_success (', +' in_log_id logs.log_id%TYPE,', +' in_rows_inserted NUMBER,', +' in_rows_updated NUMBER,', +' in_rows_deleted NUMBER,', +' in_last_rowid VARCHAR2 := NULL,', +' in_payload logs.payload%TYPE := NULL', +' ) AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' v_args logs.arguments%TYPE;', +' BEGIN', +' v_args := app.get_json_object (', +' ''inserted'', NULLIF(in_rows_inserted, 0),', +' ''updated'', NULLIF(in_rows_updated, 0),', +' ''deleted'', NULLIF(in_rows_deleted, 0),', +' ''rowid'', in_last_rowid', +' );', +' --', +' UPDATE logs l', +' SET l.arguments = v_args,', +' l.payload = NVL(in_payload, l.payload),', +' l.module_timer = app.get_duration(in_start => l.created_at)', +' WHERE l.log_id = in_log_id;', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION log_trigger (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN app.log__ (', +' in_flag => app.flag_trigger,', +' in_action_name => in_action_name,', +' in_arguments => app.get_json_list (', +' in_arg1, in_arg2,', +' in_arg3, in_arg4,', +' in_arg5, in_arg6,', +' in_arg7, in_arg8', +' ),', +' in_payload => in_payload,', +' in_parent_id => in_parent_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_progress (', +' in_action_name logs.action_name%TYPE := NULL,', +' in_progress NUMBER := NULL, -- percentage (1 = 100%)', +' in_note VARCHAR2 := NULL,', +' in_parent_id logs.log_id%TYPE := NULL', +' )', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' callstack_hash VARCHAR2(40);', +' callstack_depth PLS_INTEGER := 2;', +' v_rindex PLS_INTEGER;', +' v_slno PLS_INTEGER;', +' rec logs%ROWTYPE;', +' BEGIN', +' rec.log_parent := in_parent_id;', +'', +' -- find parent from callstack', +' IF rec.log_parent IS NULL THEN', +' callstack_hash := app.get_hash(app.get_call_stack (', +' in_offset => callstack_depth,', +' in_skip_others => TRUE,', +' in_line_numbers => FALSE,', +' in_splitter => ''|''', +' ));', +' --', +' IF map_tree.EXISTS(callstack_hash) THEN', +' rec.log_parent := map_tree(callstack_hash);', +' END IF;', +' END IF;', +' --', +' IF rec.log_parent IS NULL THEN', +' rec.log_parent := recent_log_id;', +' END IF;', +'', +' -- find parent to get rindex, module and action names', +' BEGIN', +' SELECT l.log_id, l.module_name, l.action_name, l.arguments, l.created_at', +' INTO rec.log_id, rec.module_name, rec.action_name, rec.arguments, rec.created_at', +' FROM logs l', +' WHERE l.log_id > rec.log_parent', +' AND l.log_parent = rec.log_parent', +' AND l.flag = app.flag_longops;', +' --', +' v_rindex := REPLACE(REGEXP_SUBSTR(rec.arguments, ''\|[^\|]*$''), ''|'', '''');', +'', +' -- update progress in log', +' UPDATE logs l', +' SET l.arguments = ROUND(NVL(in_progress, 0) * 100, 2) || ''%|'' || in_note || ''|'' || v_rindex,', +' l.module_timer = app.get_duration(in_start => rec.created_at)', +' WHERE l.log_id = rec.log_id;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' v_rindex := DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS_NOHINT;', +'', +' -- create new longops record', +' rec.log_id := app.log__ (', +' in_flag => app.flag_longops,', +' in_action_name => in_action_name,', +' in_arguments => ROUND(NVL(in_progress, 0) * 100, 2) || ''%|'' || in_note || ''|'' || v_rindex,', +' in_parent_id => rec.log_parent', +' );', +' END;', +'', +' -- update progress for system views', +' DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS (', +' rindex => v_rindex,', +' slno => v_slno,', +' op_name => rec.module_name, -- 64 chars', +' target_desc => rec.action_name, -- 32 chars', +' context => rec.log_id,', +' sofar => LEAST(NVL(in_progress, 0), 1),', +' totalwork => 1, -- 1 = 100%', +' units => ''%''', +' );', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION log_event (', +' in_event_id log_events.event_id%TYPE,', +' in_event_value log_events.event_value%TYPE := NULL,', +' in_parent_id logs.log_parent%TYPE := NULL', +' )', +' RETURN log_events.log_id%TYPE', +' AS', +' rec log_events%ROWTYPE;', +' BEGIN', +' rec.app_id := app.get_app_id();', +' rec.event_id := in_event_id;', +'', +' -- check if event is active', +' BEGIN', +' SELECT e.event_id INTO rec.event_id', +' FROM events e', +' WHERE e.app_id = rec.app_id', +' AND e.event_id = rec.event_id', +' AND e.is_active = ''Y'';', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' IF app.is_developer() THEN', +' -- create event on the fly for developers', +' BEGIN', +' app.log_warning(''CREATING_EVENT'', rec.event_id);', +' --', +' INSERT INTO events (app_id, event_id, is_active, updated_by, updated_at)', +' VALUES (', +' rec.app_id,', +' rec.event_id,', +' ''Y'',', +' app.get_user_id(),', +' SYSDATE', +' );', +' EXCEPTION', +' WHEN DUP_VAL_ON_INDEX THEN', +' RETURN NULL; -- must be inactive', +' END;', +' ELSE', +' RETURN NULL;', +' END IF;', +' END;', +'', +' -- store in event table', +' rec.log_id := log_id.NEXTVAL;', +' rec.log_parent := NVL(in_parent_id, recent_log_id);', +' rec.page_id := app.get_page_id();', +' rec.user_id := app.get_user_id();', +' rec.session_id := app.get_session_id();', +' rec.event_value := in_event_value;', +' rec.created_at := SYSDATE;', +' --', +' INSERT INTO log_events VALUES rec;', +' --', +' RETURN rec.log_id;', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE log_event (', +' in_event_id log_events.event_id%TYPE,', +' in_event_value log_events.event_value%TYPE := NULL', +' )', +' AS', +' out_log_id log_events.log_id%TYPE;', +' BEGIN', +' out_log_id := app.log_event (', +' in_event_id => in_event_id,', +' in_event_value => in_event_value', +' );', +' END;', +'', +'', +'', +' PROCEDURE log_scheduler (', +' in_log_id logs.log_id%TYPE,', +' in_job_name VARCHAR2', +' )', +' AS', +' curr_id logs.log_id%TYPE;', +' BEGIN', +' curr_id := app.log__ (', +' in_flag => app.flag_scheduler,', +' in_arguments => in_job_name,', +' in_parent_id => in_log_id', +' );', +' END;', +'', +'', +'', +' PROCEDURE create_one_time_job (', +' in_job_name VARCHAR2,', +' in_statement VARCHAR2 := NULL,', +' in_comments VARCHAR2 := NULL,', +' in_priority PLS_INTEGER := NULL', +' ) AS', +' v_log_id logs.log_id%TYPE;', +' BEGIN', +' v_log_id := app.log_module(in_job_name, in_statement, in_comments, in_priority);', +' --', +' DBMS_SCHEDULER.CREATE_JOB (', +' in_job_name,', +' job_type => ''PLSQL_BLOCK'',', +' job_action => ''BEGIN'' || CHR(10) ||', +' '' app.log_scheduler('' || v_log_id || '', '''''' || in_job_name || '''''');'' || CHR(10) ||', +' '' '' || RTRIM(in_statement, '';'') || '';'' || CHR(10) ||', +' '' app.log_success();'' || CHR(10) ||', +' ''EXCEPTION'' || CHR(10) ||', +' ''WHEN OTHERS THEN'' || CHR(10) ||', +' '' app.raise_error();'' || CHR(10) ||', +' ''END;'',', +' start_date => NULL,', +' enabled => FALSE,', +' auto_drop => TRUE,', +' comments => v_log_id || ''|'' || in_comments', +' );', +' --', +' IF in_priority IS NOT NULL THEN', +' DBMS_SCHEDULER.SET_ATTRIBUTE(in_job_name, ''JOB_PRIORITY'', in_priority);', +' END IF;', +' --', +' DBMS_SCHEDULER')) +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'.ENABLE(in_job_name);', +' --', +' app.log_success(v_log_id);', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION log__ (', +' in_flag logs.flag%TYPE,', +' in_module_name logs.module_name%TYPE := NULL,', +' in_module_line logs.module_line%TYPE := NULL,', +' in_action_name logs.action_name%TYPE := NULL,', +' in_arguments logs.arguments%TYPE := NULL,', +' in_payload logs.payload%TYPE := NULL,', +' in_parent_id logs.log_parent%TYPE := NULL,', +' in_app_id logs.app_id%TYPE := NULL,', +' in_page_id logs.page_id%TYPE := NULL,', +' in_user_id logs.user_id%TYPE := NULL,', +' in_session_id logs.session_id%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' rec logs%ROWTYPE;', +' callstack_hash VARCHAR2(40);', +' callstack_depth PLS_INTEGER := 4;', +' BEGIN', +' -- prepare record', +' rec.log_id := log_id.NEXTVAL;', +' rec.log_parent := COALESCE(in_parent_id, recent_request_id);', +' rec.app_id := COALESCE(in_app_id, app.get_app_id());', +' rec.page_id := COALESCE(in_page_id, app.get_page_id());', +' rec.user_id := COALESCE(in_user_id, app.get_user_id());', +' rec.session_id := COALESCE(in_session_id, app.get_session_id());', +' rec.flag := COALESCE(in_flag, ''?'');', +' --', +' rec.module_name := SUBSTR(COALESCE(in_module_name, app.get_caller_name(callstack_depth)), 1, app.length_module);', +' rec.module_line := COALESCE(in_module_line, app.get_caller_line(callstack_depth));', +' --', +' IF rec.flag = app.flag_error AND rec.module_name = raise_error_procedure THEN', +' -- make it more usefull for raised errors, shift by one more', +' rec.module_name := SUBSTR(COALESCE(in_module_name, app.get_caller_name(callstack_depth + 1)), 1, app.length_module);', +' rec.module_line := COALESCE(in_module_line, app.get_caller_line(callstack_depth + 1));', +' END IF;', +' --', +' rec.action_name := SUBSTR(in_action_name, 1, app.length_action);', +' rec.arguments := SUBSTR(in_arguments, 1, app.length_arguments);', +' rec.payload := SUBSTR(in_payload, 1, app.length_payload);', +' rec.created_at := SYSTIMESTAMP;', +'', +' -- dont log blacklisted records', +' IF SQLCODE = 0 AND NOT app.is_debug_on() AND app.is_blacklisted(rec) THEN', +' RETURN NULL; -- skip blacklisted record only if there is no error and debug mode off', +' END IF;', +'', +' -- retrieve parent log from map', +' IF in_parent_id IS NULL AND rec.flag != app.flag_request THEN', +' callstack_hash := app.get_hash(app.get_call_stack (', +' in_offset => callstack_depth + CASE WHEN rec.flag = app.flag_module THEN 1 ELSE 0 END, -- magic', +' in_skip_others => TRUE,', +' in_line_numbers => FALSE,', +' in_splitter => ''|''', +' ));', +' --', +' IF map_tree.EXISTS(callstack_hash) THEN', +' rec.log_parent := map_tree(callstack_hash);', +' END IF;', +' END IF;', +'', +' -- save new map record for log hierarchy', +' IF rec.flag IN (app.flag_module, app.flag_trigger) THEN', +' callstack_hash := app.get_hash(app.get_call_stack (', +' in_offset => callstack_depth,', +' in_skip_others => TRUE,', +' in_line_numbers => FALSE,', +' in_splitter => ''|''', +' ));', +' --', +' map_tree(callstack_hash) := rec.log_id;', +' END IF;', +'', +' -- set session things', +' IF rec.flag IN (app.flag_request, app.flag_module) THEN', +' recent_log_id := rec.log_id;', +' --', +' app.set_session (', +' in_module_name => CASE WHEN rec.flag = app.flag_request THEN ''APEX|'' || TO_CHAR(rec.app_id) || ''|'' || TO_CHAR(rec.page_id) ELSE rec.module_name END,', +' in_action_name => rec.action_name,', +' in_log_id => rec.log_id', +' );', +' END IF;', +'', +' -- add call stack', +' IF (SQLCODE != 0 OR INSTR(app.track_callstack, rec.flag) > 0) THEN', +' rec.payload := SUBSTR(rec.payload || app.get_shorter_stack(app.get_call_stack()), 1, app.length_payload);', +' END IF;', +'', +' -- add error stack', +' IF SQLCODE != 0 THEN', +' rec.payload := SUBSTR(rec.payload || app.get_shorter_stack(app.get_error_stack()), 1, app.length_payload);', +' END IF;', +'', +' -- print message to console', +' IF app.is_developer() THEN', +' DBMS_OUTPUT.PUT_LINE(', +' rec.log_id || '' ^'' || COALESCE(rec.log_parent, 0) || '' ['' || rec.flag || '']: '' ||', +' --RPAD('' '', (rec.module_depth - 1) * 2, '' '') ||', +' rec.module_name || '' ['' || rec.module_line || ''] '' || rec.action_name ||', +' RTRIM('': '' || SUBSTR(rec.arguments, 1, 40), '': '')', +' );', +' END IF;', +'', +' -- finally store record in table', +' INSERT INTO logs VALUES rec;', +' --', +' COMMIT;', +' --', +' RETURN rec.log_id;', +' EXCEPTION', +' WHEN OTHERS THEN', +' COMMIT;', +' --', +' DBMS_OUTPUT.PUT_LINE(''-- NOT LOGGED ERROR:'');', +' DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);', +' DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);', +' DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_CALL_STACK);', +' DBMS_OUTPUT.PUT_LINE(''-- ^'');', +' --', +' RAISE_APPLICATION_ERROR(app.app_exception_code, ''LOG_FAILED'', TRUE);', +' END;', +'', +'', +'', +' FUNCTION is_blacklisted (', +' in_row logs%ROWTYPE', +' )', +' RETURN BOOLEAN', +' AS', +' BEGIN', +' FOR i IN 1 .. log_blacklist.COUNT LOOP', +' IF (in_row.flag = log_blacklist(i).flag OR log_blacklist(i).flag IS NULL)', +' AND (in_row.module_name LIKE log_blacklist(i).module_like OR log_blacklist(i).module_like IS NULL)', +' AND (in_row.action_name LIKE log_blacklist(i).action_like OR log_blacklist(i).action_like IS NULL)', +' THEN', +' RETURN TRUE;', +' END IF;', +' END LOOP;', +' --', +' RETURN FALSE;', +' END;', +'', +'', +'', +' PROCEDURE raise_error (', +' in_action_name logs.action_name%TYPE := NULL,', +' --', +' in_arg1 logs.arguments%TYPE := NULL,', +' in_arg2 logs.arguments%TYPE := NULL,', +' in_arg3 logs.arguments%TYPE := NULL,', +' in_arg4 logs.arguments%TYPE := NULL,', +' in_arg5 logs.arguments%TYPE := NULL,', +' in_arg6 logs.arguments%TYPE := NULL,', +' in_arg7 logs.arguments%TYPE := NULL,', +' in_arg8 logs.arguments%TYPE := NULL,', +' --', +' in_payload logs.payload%TYPE := NULL,', +' in_rollback BOOLEAN := FALSE', +' )', +' AS', +' v_log_id logs.log_id%TYPE;', +' v_action_name logs.action_name%TYPE;', +' BEGIN', +' IF in_rollback THEN', +' ROLLBACK;', +' END IF;', +' --', +' v_action_name := COALESCE(in_action_name, app.get_caller_name(), ''UNEXPECTED_ERROR'');', +' --', +' v_log_id := app.log_error (', +' in_action_name => v_action_name,', +' in_arg1 => in_arg1,', +' in_arg2 => in_arg2,', +' in_arg3 => in_arg3,', +' in_arg4 => in_arg4,', +' in_arg5 => in_arg5,', +' in_arg6 => in_arg6,', +' in_arg7 => in_arg7,', +' in_arg8 => in_arg8,', +' in_payload => in_payload', +' );', +' --', +' RAISE_APPLICATION_ERROR (', +' app.app_exception_code,', +' v_action_name || '' ['' || v_log_id || '']'',', +' FALSE -- dont stack, we have that in log', +' );', +' END;', +'', +'', +'', +' FUNCTION handle_apex_error (', +' p_error APEX_ERROR.T_ERROR', +' )', +' RETURN APEX_ERROR.T_ERROR_RESULT', +' AS', +' out_result APEX_ERROR.T_ERROR_RESULT;', +' --', +' v_log_id NUMBER; -- log_id from your log_error function (returning most likely sequence)', +' v_action_name logs.action_name%TYPE; -- short error type visible to user', +' v_component logs.action_name%TYPE; -- to identify source component in your app', +' BEGIN', +' out_result := APEX_ERROR.INIT_ERROR_RESULT(p_error => p_error);', +'', +' -- assign log_id sequence (app specific, probably from sequence)', +' IF p_error.ora_sqlcode IN (-1, -2091, -2290, -2291, -2292) THEN', +' -- handle constraint violations', +' -- ORA-00001: unique constraint violated', +' -- ORA-02091: transaction rolled back (can hide a deferred constraint)', +' -- ORA-02290: check constraint violated', +' -- ORA-02291: integrity constraint violated - parent key not found', +' -- ORA-02292: integrity constraint violated - child record found', +' v_action_name := ''CONSTRAINT_ERROR|'' || APEX_ERROR.EXTRACT_CONSTRAINT_NAME (', +' p_error => p_error,', +' p_include_schema => FALSE', +' );', +' --', +' out_result.message := v_action_name;', +' out_result.display_location := APEX_ERROR.C_INLINE_IN_NOTIFICATION;', +' --', +' ELSIF p_error.is_internal_error THEN', +' v_action_name := ''INTERNAL_ERROR'';', +' ELSE', +' v_action_name := ''UNKNOWN_ERROR'';', +' END IF;', +'', +' -- store incident in your log', +' v_component := TO_CHAR(APEX_APPLICATION.G_FLOW_STEP_ID) || ''|'' || REPLACE(p_error.component.type, ''APEX_APPLICATION_'', '''') || ''|'' || p_error.component.name;', +' --', +' v_log_id := app.log_error (', +' in_action_name => v_action_name,', +' in_arg1 => v_component,', +' in_arg2 => APEX_ERROR.GET_FIRST_ORA_ERROR_TEXT(p_error => p_error),', +' in_payload =>', +' out_result.message || CHR(10) || ''--'' || CHR(10) ||', +' app.get_shorter_stack(p_error.error_statement) || CHR(10) || ''--'' || CHR(10) ||', +' app.get_shorter_stack (p_error.ora_sqlerrm) || CHR(10) || ''--'' || CHR(10)', +' --app.get_shorter_stack (p_error.error_backtrace) || CHR(10) || ''--'' || CHR(10)', +' );', +'', +' -- mark associated page item (when possible)', +' IF out_result.page_item_name IS NULL AND out_result.column_alias IS NULL THEN', +' APEX_ERROR.AUTO_SET_ASSOCIATED_ITEM (', +' p_error => p_error,', +' p_error_result => out_result', +' );', +' END IF;', +'', +' -- show only the latest error message to common users', +' /*', +' IF p_error.ora_sqlcode = app.app_exception_code THEN', +' out_result.message := v_action_name || ''|'' || TO_CHAR(v_log_id) || ''
'' ||', +' v_component || ''
'' ||', +' out_result.message || ''
'' ||', +' APEX_ERROR.GET_FIRST_ORA_ERROR_TEXT(p_error => p_error);', +' out_result.additional_info := '''';', +' ELSIF v_action_name != ''UNKNOWN_ERROR'' THEN', +' out_result.message := v_action_name || ''|'' || TO_CHAR(v_log_id);', +' out_result.additional_info := '''';', +' END IF;', +' */', +'', +' out_result.message := REGEXP_REPLACE(out_result.message, ''^(ORA'' || TO_CHAR(app.app_exception_code) || '': )'', '''');', +' --', +' RETURN out_result;', +' END;', +'', +'', +'', +' PROCEDURE purge_logs (', +' in_age PLS_INTEGER := NULL', +' )', +' AS', +' data_exists PLS_INTEGER;', +' --', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' app.log_module(in_age);', +'', +' -- purge all', +' IF in_age < 0 THEN', +' EXECUTE IMMEDIATE ''TRUNCATE TABLE '' || app.logs_table_name || '' CASCADE'';', +' END IF;', +'', +' -- remove old sessions', +' DELETE FROM sessions s', +' WHERE s.created_at <= TRUNC(SYSDATE) - NVL(in_age, app.logs_max_age);', +'', +' -- remove old partitions', +' FOR c IN (', +' SELECT p.table_name, p.partition_name', +' FROM user_tab_partitions p,', +' -- trick to convert LONG to VARCHAR2 on the fly', +' XMLTABLE(''/ROWSET/ROW''', +' PASSING (DBMS_XMLGEN.GETXMLTYPE(', +' ''SELECT p.high_value'' || CHR(10) ||', +' ''FROM user_tab_partitions p'' || CHR(10) ||', +' ''WHERE p.table_name = '''''' || p.table_name || '''''''' || CHR(10) ||', +' '' AND p.partition_name = '''''' || p.partition_name || ''''''''', +' ))', +' COLUMNS high_value VARCHAR2(4000) PATH ''HIGH_VALUE''', +' ) h', +' WHERE p.table_name = app.logs_table_name', +' AND TO_DATE(REGEXP_SUBSTR(h.high_value, ''(\d{4}-\d{2}-\d{2})''), ''YYYY-MM-DD'') <= TRUNC(SYSDATE) - COALESCE(in_age, app.logs_max_age)', +' ) LOOP', +' -- delete old data in batches', +' FOR i IN 1 .. 100 LOOP', +' EXECUTE IMMEDIATE', +' ''DELETE FROM '' || c.table_name ||', +' '' PARTITION ('' || c.partition_name || '') WHERE ROWNUM <= 100000'';', +' --', +' COMMIT; -- to reduce UNDO violations', +' END LOOP;', +'', +' -- check if data in partition exists', +' EXECUTE IMMEDIATE', +' ''SELECT COUNT(*) FROM '' || c.table_name ||', +' '' PARTITION ('' || c.partition_name || '') WHERE ROWNUM = 1''', +' INTO data_exists;', +' --', +' IF data_exists = 0 THEN', +' EXECUTE IMMEDIATE', +' ''ALTER TABLE '' || c.table_name ||', +' '' DROP PARTITION '' || c.partition_name || '' UPDATE GLOBAL INDEXES'';', +' END IF;', +' END LOOP;', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' COMMIT;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE purge_logs (', +' in_log_id logs.log_id%TYPE', +' ) AS', +' rows_to_delete app.arr_logs_log_id;', +' --', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' SELECT l.log_id', +' BULK COLLECT INTO rows_to_delete', +' FROM logs l', +' CONNECT BY PRIOR l.log_id = l.log_parent', +' START WITH l.log_id = in_log_id;', +' --', +' FORALL i IN rows_to_delete.FIRST .. rows_to_delete.LAST', +' DELETE FROM logs', +' WHERE log_id = rows_to_delete(i);', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' COMMIT;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE purge_logs (', +' in_date DATE', +' ) AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' DELETE FROM logs l', +' WHERE l.created_at >= in_date', +' AND l.created_at < in_date + 1;', +' --', +' DELETE FROM sessions s', +' WHERE s.created_at >= in_date', +' AND s.created_at < in_date + 1;', +' --', +' COMMIT;', +' EXCEPTION', +' WHEN OTHERS THEN', +' COMMIT;', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION get_caller_name (', +' in_offset PLS_INTEGER := NULL', +' )', +' RETURN logs.module_name%TYPE', +' AS', +' BEGIN', +' RETURN SUBSTR(UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(NVL(in_offset, 2))), 1, app.length_module);', +' EXCEPTION', +' WHEN BAD_DEPTH THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_caller_line (', +' in_offset PLS_INTEGER := NULL', +' )', +' RETURN logs.module_line%TYPE', +' AS', +' BEGIN', +' RETURN UTL_CALL_STACK.UNIT_LINE(NVL(in_offset, 2));', +' EXCEPTION', +' WHEN BAD_DEPTH THEN', +' RETURN NULL;', +' END;', +'', +'', +'', +' FUNCTION get_hash (', +' in_payload VARCHAR2', +' )', +' RETURN VARCHAR2', +' RESULT_CACHE', +' AS', +' out_ VARCHAR2(40);', +' BEGIN', +' -- quick hash alg, shame we need a context switch, compensate with result cache', +' SELECT STANDARD_HASH(in_payload) INTO out_', +' FROM DUAL;', +' --', +' RETURN out_;', +' END;', +'', +'', +'', +' FUNCTION get_call_stack (', +' in_offset PLS_INTEGER := NULL,', +' in_skip_others BOOLEAN := FALSE,', +' in_line_numbers BOOLEAN := TRUE,', +' in_splitter VARCHAR2 := CHR(10)', +' )', +' RETURN logs.payload%TYPE', +' AS', +' out_stack VARCHAR2(32767);', +' out_module logs.module_name%TYPE;', +' BEGIN', +' -- better version of DBMS_UTILITY.FORMAT_CALL_STACK', +' FOR i IN REVERSE NVL(in_offset, 2) .. UTL_CALL_STACK.DYNAMIC_DEPTH LOOP -- 2 = ignore this function, 3 = ignore caller', +' CONTINUE WHEN in_skip_others AND NVL(UTL_CALL_STACK.OWNER(i), ''-'') != app.schema_owner;', +' --', +' out_module := SUBSTR(UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(i)), 1, app.length_module);', +' out_stack := out_stack || out_module || CASE WHEN in_line_numbers THEN '' ['' || TO_CHAR(UTL_CALL_STACK.UNIT_LINE(i)) || '']'' END || in_splitter;', +' END LOOP;', +' --', +' RETURN out_stack;', +' END;', +'', +'', +'', +' FUNCTION get_error_stack', +' RETURN logs.payload%TYPE', +' AS', +' out_stack VARCHAR2(32767);', +' BEGIN', +' -- switch NLS to get error message in english', +' BEGIN', +' DBMS_SESSION.SET_NLS(''NLS_LANGUAGE'', ''''''ENGLISH'''''');', +' EXCEPTION', +' WHEN OTHERS THEN -- cant set NLS in triggers', +' NULL;', +' END;', +'', +' -- better version of DBMS_UTILITY.FORMAT_ERROR_STACK, FORMAT_ERROR_BACKTRACE', +' FOR i IN REVERSE 1 .. UTL_CALL_STACK.ERROR_DEPTH LOOP', +' BEGIN', +' out_stack := out_stack ||', +' UTL_CALL_STACK.BACKTRACE_UNIT(i) || '' ['' || UTL_CALL_STACK.BACKTRACE_LINE(i) || ''] '' ||', +' ''ORA-'' || LPAD(UTL_CALL_STACK.ERROR_NUMBER(i), 5, ''0'') || '' '' ||', +' UTL_CALL_STACK.ERROR_MSG(i) || CHR(10);', +' EXCEPTION', +' WHEN BAD_DEPTH THEN', +' NULL;', +' END;', +' END LOOP;', +' --', +' RETURN out_stack;', +' END;', +'', +'', +'', +' FUNCTION get_shorter_stack (', +' in_stack VARCHAR2', +' )', +' RETURN VARCHAR2', +' AS', +' out_stack VARCHAR2(32767);', +' BEGIN', +' out_stack := REPLACE(REPLACE(in_stack, ''WWV_FLOW'', ''%''), app.schema_apex, ''%'');', +' --', +' out_stack := REGEXP_REPLACE(out_stack, ''\s.*SQL.*\.EXEC.*\]'', ''.'');', +' out_stack := REGEXP_REPLACE(out_stack, ''\s%.*EXEC.*\]'', ''.'');', +' out_stack := REGEXP_REPLACE(out_stack, ''\s%_PROCESS.*\]'', ''.'');', +' out_stack := REGEXP_REPLACE(out_stack, ''\s%_ERROR.*\]'', ''.'');', +' out_stack := REGEXP_REPLACE(out_stack, ''\s%_SECURITY.*\]'', ''.'');', +' out_stack := REGEXP_REPLACE(out_stack, ''\sHTMLDB*\]'', ''.'');', +' --', +' RETURN out_stack;', +' END;', +'', +'', +'', +' FUNCTION get_log_root (', +' in_log_id logs.log_id%TYPE := NULL', +' )', +' RETURN logs.log_id%TYPE', +' AS', +' out_log_id logs.log_id%TYPE;', +' BEGIN', +' SELECT MIN(COALESCE(e.log_parent, e.log_id)) INTO out_log_id', +' FROM logs e', +' CONNECT BY PRIOR e.log_parent = e.log_id', +' START WITH e.log_id = COALESCE(in_log_id, recent_log_id);', +' --', +' RETURN out_log_id;', +' END;', +'', +'', +'', +' FUNCTION get_log_request_id', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN recent_request_id;', +' END;', +'', +'', +'', +' FUNCTION get_log_tree_id', +' RETURN logs.log_id%TYPE', +' AS', +' BEGIN', +' RETURN recent_tree_id;', +' END;', +'', +'', +'', +' PROCEDURE set_log_tree_id (', +' in_log_id logs.log_id%TYPE', +' ) AS', +' BEGIN', +' recent_tree_id := in_log_id;', +' END;', +'', +'', +'', +'', +'', +'', +'', +' -- ### DML Error Handling', +' --', +'', +' --', +' -- Creates `MERGE` query for selected `_E$` table and row', +' --', +' FUNCTION get_dml_query (', +' in_log_id logs.log_id%TYPE,', +' in_table_name logs.module_name%TYPE,', +' in_table_rowid VARCHAR2,', +' in_operation CHAR -- [I|U|D]', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN NULL;', +' END;', +'', +'', +'', +' --', +' -- Maps existing `DML` errors to proper row in `logs` table', +' --', +' PROCEDURE process_dml_error (', +' in_log_id logs.log_id%TYPE,', +' in_error_table VARCHAR2, -- remove references to logs_dml_errors view', +' in_table_name VARCHAR2, -- because it can get invalidated too often', +' in_table_rowid VARCHAR2,', +' in_action_name VARCHAR2', +' )', +' AS', +' BEGIN', +' RETURN;', +' END;', +'', +'', +'', +' --', +' -- Drop `DML` error tables matching filter', +' --', +' PROCEDURE drop_dml_tables (', +' in_table_like logs.module_name%TYPE', +' )', +' AS', +' BEGIN', +' RETURN;', +' END;', +'', +'', +'', +' --', +' -- Recreates `DML` error tables matching filter', +' --', +' PROCEDURE create_dml_tables (', +' in_table_like logs.module_name%TYPE', +' )', +' AS', +' BEGIN', +' RETURN;', +' END;', +'', +'', +'', +' --', +' -- Merge all `DML` error tables (`_E$`) into single view', +' --', +' PROCEDURE create_dml_errors_view', +' AS', +' BEGIN', +' RETURN;', +' END;', +'', +'', +'', +' PROCEDURE call_custom_procedure (', +' in_name VARCHAR2 := NULL,', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL', +' ) AS', +' v_object_name VARCHAR2(64);', +' v_args PLS_INTEGER;', +' is_valid CHAR;', +' BEGIN', +' -- determice object name from caller (based on current application)', +' v_object_name := COALESCE(in_name, ''A'' || app.get_app_id() || ''.'' || REGEXP_REPLACE(app.get_caller_name(3), ''([^\.]+\.)'', ''''));', +' --', +' --app.log_module(v_object_name, in_arg1, in_arg2, in_arg3, in_arg4);', +'', +' -- check object existance', +' BEGIN', +' SELECT ''Y'' INTO is_valid', +' FROM user_procedures p', +' WHERE RTRIM(p.object_name || ''.'' || p.procedure_name, ''.'') = UPPER(v_object_name)', +' AND p.object_type IN (''PACKAGE'', ''PROCEDURE'')', +' AND p.overload IS NULL;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' app.log_warning(''PROCEDURE_MISSING'');', +' RETURN;', +' END;', +'', +' -- check object arguments', +' SELECT COUNT(*) INTO v_args', +' FROM user_arguments a', +' WHERE RTRIM(a.package_name || ''.'' || a.object_name, ''.'') = UPPER(v_object_name)', +' AND a.position > 0', +' AND a.in_out = ''IN'';', +' --', +' BEGIN', +' CASE v_args', +' WHEN 1 THEN EXECUTE IMMEDIATE ''BEGIN '' || v_object_name || ''(:1); END;'' USING in_arg1;', +' WHEN 2 THEN EXECUTE IMMEDIATE ''BEGIN '' || v_object_name || ''(:1, :2); END;'' USING in_arg1, in_arg2;', +' WHEN 3 THEN EXECUTE IMMEDIATE ''BEGIN '' || v_object_name || ''(:1, :2, :3); END;'' USING in_arg1, in_arg2, in_arg3;', +' WHEN 4 THEN EXECUTE IMMEDIATE ''BEGIN '' || v_object_name || ''(:1, :2, :3, :4); END;'' USING in_arg1, in_arg2, in_arg3, in_arg4;', +' ELSE EXECUTE IMMEDIATE ''BEGIN '' || v_object_name || ''(); END;'';', +' END CASE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''CUSTOM_CODE_FAILED'');', +' END;', +' --', +' --app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' --', +' -- @TODO:', +' --', +' FUNCTION call_custom_function (', +' in_name VARCHAR2 := NULL,', +' in_arg1 VARCHAR2 := NULL,', +' in_arg2 VARCHAR2 := NULL,', +' in_arg3 VARCHAR2 := NULL,', +' in_arg4 VARCHAR2 := NULL', +' )', +' RETURN VARCHAR2', +' AS', +' BEGIN', +' RETURN NULL;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE init', +' AS', +' BEGIN', +' -- clear map for tracking logs hierarchy', +' map_tree := app.arr_map_tree();', +'', +' -- load blacklisted records from logs_blacklist table when session starts', +' -- this block is initialized with every APEX request', +' -- so app_id, user_id and page_id wont change until next request', +' SELECT t.*', +' BULK COLLECT INTO log_blacklist', +' FROM logs_blacklist t', +' WHERE t.app_id = app.get_app_id()', +' AND (t.user_id = app.get_user_id() OR t.user_id IS NULL)', +' AND (t.page_id = app.get_page_id() OR t.page_id IS NULL);', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'END;', +'/', +'', +'CREATE OR REPLACE PACKAGE "APP_ACTIONS" AS', +'', +' /**', +' * This package is part of the APP CORE project under MIT licence.', +' * https://github.com/jkvetina/#core', +' *', +' * Copyright (c) Jan Kvetina, 2021', +' *', +' * (R)', +' * --- ---', +' * #@@@@@@ &@@@@@@', +' * @@@@@@@@ .@ @@@@@@@@', +' * ----- @@@@@@ @@@@@@, @@@@@@@ -----', +' * &@@@@@@@@@@@ @@@ &@@@@@@@@@. @@@@ .@@@@@@@@@@@#', +' * @@@@@@@@@@@ @ @@@@@@@@@@@@@ @ @@@@@@@@@@@', +' * \@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@@@@@', +' * @@@@@@@@@ @@@@@@@@@@@@@@@ &@@@@@@@@', +' * @@@@@@@( @@@@@@@@@@@@@@@ @@@@@@@@', +' * @@@@@@( @@@@@@@@@@@@@@, @@@@@@@', +' * .@@@@@, @@@@@@@@@@@@@ @@@@@@', +' * @@@@@@ *@@@@@@@@@@@@@ @@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * .@@@@@@@@@@@@@@@@@@@@@@@@@', +' * .@@@@@@@@@@@@@@@@@@@@@', +' * jankvetina.cz', +' * -------', +' *', +' */', +'', +' settings_package CONSTANT VARCHAR2(30) := ''SETT'';', +' settings_prefix CONSTANT VARCHAR2(30) := ''get_'';', +'', +' -- for sending emails', +unistr(' smtp_from CONSTANT VARCHAR2(200) := ''Jan Kv\011Btina '';'), +' smtp_username CONSTANT VARCHAR2(50) := NULL;', +' smtp_password CONSTANT VARCHAR2(50) := NULL;', +' smtp_host CONSTANT VARCHAR2(50) := ''smtp.email.eu-frankfurt-1.oci.oraclecloud.com'';', +' smtp_port CONSTANT NUMBER(4) := 25;', +' smtp_timeout CONSTANT NUMBER(2) := 20;', +'', +'', +'', +'', +'', +'', +'', +' -- ### Navigation page', +' --', +'', +' --', +' -- Remove missing pages from NAVIGATION table', +' --', +' PROCEDURE nav_remove_pages (', +' in_page_id navigation.page_id%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Add new pages to NAVIGATION table', +' --', +' PROCEDURE nav_add_pages (', +' in_page_id navigation.page_id%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Auto update navigation (add missing pages, remove old records)', +' --', +' PROCEDURE nav_autoupdate;', +'', +'', +'', +'', +'', +'', +'', +' -- ### User Roles page', +' --', +'', +' --', +' --', +' --', +' PROCEDURE prep_user_roles_pivot (', +' in_page_id apex_application_pages.page_id%TYPE', +' );', +'', +'', +'', +' --', +' --', +' --', +' PROCEDURE save_user_roles (', +' in_action CHAR,', +' in_c001 VARCHAR2 := NULL,', +' in_c002 VARCHAR2 := NULL,', +' in_c003 VARCHAR2 := NULL,', +' in_c004 VARCHAR2 := NULL,', +' in_c005 VARCHAR2 := NULL,', +' in_c006 VARCHAR2 := NULL,', +' in_c007 VARCHAR2 := NULL,', +' in_c008 VARCHAR2 := NULL,', +' in_c009 VARCHAR2 := NULL,', +' in_c010 VARCHAR2 := NULL,', +' in_c011 VARCHAR2 := NULL,', +' in_c012 VARCHAR2 := NULL,', +' in_c013 VARCHAR2 := NULL,', +' in_c014 VARCHAR2 := NULL,', +' in_c015 VARCHAR2 := NULL,', +' in_c016 VARCHAR2 := NULL,', +' in_c017 VARCHAR2 := NULL,', +' in_c018 VARCHAR2 := NULL,', +' in_c019 VARCHAR2')) +); +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +' := NULL,', +' in_c020 VARCHAR2 := NULL,', +' in_c021 VARCHAR2 := NULL,', +' in_c022 VARCHAR2 := NULL,', +' in_c023 VARCHAR2 := NULL,', +' in_c024 VARCHAR2 := NULL,', +' in_c025 VARCHAR2 := NULL,', +' in_c026 VARCHAR2 := NULL,', +' in_c027 VARCHAR2 := NULL,', +' in_c028 VARCHAR2 := NULL,', +' in_c029 VARCHAR2 := NULL,', +' in_c030 VARCHAR2 := NULL,', +' in_c031 VARCHAR2 := NULL,', +' in_c032 VARCHAR2 := NULL,', +' in_c033 VARCHAR2 := NULL,', +' in_c034 VARCHAR2 := NULL,', +' in_c035 VARCHAR2 := NULL,', +' in_c036 VARCHAR2 := NULL,', +' in_c037 VARCHAR2 := NULL,', +' in_c038 VARCHAR2 := NULL,', +' in_c039 VARCHAR2 := NULL,', +' in_c040 VARCHAR2 := NULL,', +' in_c041 VARCHAR2 := NULL,', +' in_c042 VARCHAR2 := NULL,', +' in_c043 VARCHAR2 := NULL,', +' in_c044 VARCHAR2 := NULL,', +' in_c045 VARCHAR2 := NULL,', +' in_c046 VARCHAR2 := NULL,', +' in_c047 VARCHAR2 := NULL,', +' in_c048 VARCHAR2 := NULL,', +' in_c049 VARCHAR2 := NULL,', +' in_c050 VARCHAR2 := NULL', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### Settings page', +' --', +'', +' --', +' -- Get value from Settings table', +' --', +' FUNCTION get_setting (', +' in_name settings.setting_name%TYPE,', +' in_context settings.setting_context%TYPE := NULL', +' )', +' RETURN settings.setting_value%TYPE;', +'', +'', +'', +' --', +' -- Store/update settings', +' --', +' PROCEDURE set_setting (', +' in_action CHAR,', +' in_setting_name_old settings.setting_name%TYPE,', +' in_setting_name settings.setting_name%TYPE,', +' in_setting_group settings.setting_group%TYPE := NULL,', +' in_setting_value settings.setting_value%TYPE := NULL,', +' in_is_numeric settings.is_numeric%TYPE := NULL,', +' in_is_date settings.is_date%TYPE := NULL,', +' in_description settings.description_%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Store/update settings for specific contexts (pivot), including default', +' --', +' PROCEDURE set_setting_bulk (', +' in_c001 settings.setting_value%TYPE,', +' in_c002 settings.setting_value%TYPE,', +' in_c003 settings.setting_value%TYPE := NULL,', +' in_c004 settings.setting_value%TYPE := NULL,', +' in_c005 settings.setting_value%TYPE := NULL,', +' in_c006 settings.setting_value%TYPE := NULL,', +' in_c007 settings.setting_value%TYPE := NULL,', +' in_c008 settings.setting_value%TYPE := NULL,', +' in_c009 settings.setting_value%TYPE := NULL,', +' in_c010 settings.setting_value%TYPE := NULL,', +' in_c011 settings.setting_value%TYPE := NULL,', +' in_c012 settings.setting_value%TYPE := NULL,', +' in_c013 settings.setting_value%TYPE := NULL,', +' in_c014 settings.setting_value%TYPE := NULL,', +' in_c015 settings.setting_value%TYPE := NULL,', +' in_c016 settings.setting_value%TYPE := NULL,', +' in_c017 settings.setting_value%TYPE := NULL,', +' in_c018 settings.setting_value%TYPE := NULL,', +' in_c019 settings.setting_value%TYPE := NULL,', +' in_c020 settings.setting_value%TYPE := NULL,', +' in_c021 settings.setting_value%TYPE := NULL,', +' in_c022 settings.setting_value%TYPE := NULL,', +' in_c023 settings.setting_value%TYPE := NULL,', +' in_c024 settings.setting_value%TYPE := NULL,', +' in_c025 settings.setting_value%TYPE := NULL,', +' in_c026 settings.setting_value%TYPE := NULL,', +' in_c027 settings.setting_value%TYPE := NULL,', +' in_c028 settings.setting_value%TYPE := NULL,', +' in_c029 settings.setting_value%TYPE := NULL,', +' in_c030 settings.setting_value%TYPE := NULL,', +' in_c031 settings.setting_value%TYPE := NULL,', +' in_c032 settings.setting_value%TYPE := NULL,', +' in_c033 settings.setting_value%TYPE := NULL,', +' in_c034 settings.setting_value%TYPE := NULL,', +' in_c035 settings.setting_value%TYPE := NULL,', +' in_c036 settings.setting_value%TYPE := NULL,', +' in_c037 settings.setting_value%TYPE := NULL,', +' in_c038 settings.setting_value%TYPE := NULL,', +' in_c039 settings.setting_value%TYPE := NULL,', +' in_c040 settings.setting_value%TYPE := NULL,', +' in_c041 settings.setting_value%TYPE := NULL,', +' in_c042 settings.setting_value%TYPE := NULL,', +' in_c043 settings.setting_value%TYPE := NULL,', +' in_c044 settings.setting_value%TYPE := NULL,', +' in_c045 settings.setting_value%TYPE := NULL,', +' in_c046 settings.setting_value%TYPE := NULL,', +' in_c047 settings.setting_value%TYPE := NULL,', +' in_c048 settings.setting_value%TYPE := NULL,', +' in_c049 settings.setting_value%TYPE := NULL,', +' in_c050 settings.setting_value%TYPE := NULL', +' );', +'', +'', +'', +' --', +' -- Rebuild package containing function matching Settings table', +' --', +' PROCEDURE rebuild_settings;', +'', +'', +'', +' --', +' -- Prepare pivot for Settings page', +' --', +' PROCEDURE prep_settings_pivot (', +' in_page_id apex_application_pages.page_id%TYPE', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### Views source table', +' --', +'', +' --', +' -- Refresh views source (convert views source to lines)', +' --', +' PROCEDURE refresh_user_source_views;', +'', +'', +'', +' PROCEDURE clob_to_lines (', +' in_name VARCHAR2,', +' in_clob CLOB', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### E-mails', +' --', +'', +' FUNCTION clob_to_blob (', +' in_clob CLOB', +' )', +' RETURN BLOB;', +'', +'', +'', +' --', +' -- Send UTF_8 email with compressed attachements', +' --', +' PROCEDURE send_mail (', +' in_to VARCHAR2,', +' in_subject VARCHAR2,', +' in_body CLOB,', +' in_cc VARCHAR2 := NULL,', +' in_bcc VARCHAR2 := NULL,', +' in_from VARCHAR2 := NULL,', +' in_attach_name VARCHAR2 := NULL,', +' in_attach_mime VARCHAR2 := NULL,', +' in_attach_data CLOB := NULL,', +' in_compress BOOLEAN := FALSE', +' );', +'', +'', +'', +'', +'', +'', +'', +' -- ### Various APEX functions', +' --', +'', +' --', +' -- Set global notification message', +' --', +' PROCEDURE update_global_message (', +' in_message VARCHAR2 := NULL,', +' in_app_id apex_applications.application_id%TYPE := NULL', +' );', +'', +'END;', +'/', +'', +'', +'CREATE OR REPLACE PACKAGE BODY "APP_ACTIONS" AS', +'', +' PROCEDURE nav_remove_pages (', +' in_page_id navigation.page_id%TYPE := NULL', +' )', +' AS', +' BEGIN', +' app.log_module(in_page_id);', +'', +' -- remove references', +' FOR c IN (', +' SELECT n.app_id, n.page_id', +' FROM navigation n', +' JOIN nav_pages_to_remove p', +' ON p.page_id = n.parent_id', +' AND n.page_id = NVL(in_page_id, n.page_id)', +' WHERE n.app_id = app.get_app_id()', +' ) LOOP', +' app.log_debug(''REMOVING_PARENT'', c.page_id);', +' --', +' UPDATE navigation n', +' SET n.parent_id = NULL', +' WHERE n.app_id = c.app_id', +' AND n.page_id = c.page_id;', +' END LOOP;', +'', +' -- remove rows for pages which dont exists', +' FOR c IN (', +' SELECT p.page_id', +' FROM nav_pages_to_remove p', +' WHERE p.page_id = NVL(in_page_id, p.page_id)', +' ) LOOP', +' app.log_debug(''DELETING'', c.page_id);', +' --', +' DELETE FROM navigation n', +' WHERE n.app_id = app.get_app_id()', +' AND n.page_id = c.page_id;', +' END LOOP;', +' --', +' app.log_success();', +' END;', +'', +'', +'', +' PROCEDURE nav_add_pages (', +' in_page_id navigation.page_id%TYPE := NULL', +' )', +' AS', +' rec navigation%ROWTYPE;', +' BEGIN', +' app.log_module(in_page_id);', +'', +' -- add pages which are present in APEX but missing in Navigation table', +' FOR c IN (', +' SELECT n.*', +' FROM nav_pages_to_add n', +' WHERE n.page_id = NVL(in_page_id, n.page_id)', +' ) LOOP', +' app.log_debug(''ADDING'', c.page_id);', +' --', +' rec.app_id := c.app_id;', +' rec.page_id := c.page_id;', +' rec.parent_id := c.parent_id;', +' rec.order# := c.order#;', +' rec.is_hidden := c.is_hidden;', +' rec.is_reset := c.is_reset;', +' --', +' INSERT INTO navigation VALUES rec;', +' END LOOP;', +' --', +' app.log_success();', +' END;', +'', +'', +'', +' PROCEDURE nav_autoupdate', +' AS', +' BEGIN', +' app.log_module();', +' --', +' nav_remove_pages();', +' nav_add_pages();', +'', +' -- renumber sublings', +' MERGE INTO navigation g', +' USING (', +' SELECT n.app_id, n.page_id, n.new_order#', +' FROM (', +' SELECT', +' n.app_id,', +' n.page_id,', +' n.order#,', +' ROW_NUMBER() OVER (PARTITION BY n.parent_id ORDER BY n.order#, n.page_id) * 5 + 5 AS new_order#', +' FROM navigation n', +' WHERE n.app_id = app.get_app_id()', +' AND n.parent_id IS NOT NULL', +' ) n', +' WHERE n.new_order# != n.order#', +' ) n', +' ON (', +' g.app_id = n.app_id', +' AND g.page_id = n.page_id', +' )', +' WHEN MATCHED THEN', +' UPDATE SET g.order# = n.new_order#;', +' --', +' app.log_success();', +' END;', +'', +'', +'', +' PROCEDURE prep_user_roles_pivot (', +' in_page_id apex_application_pages.page_id%TYPE', +' ) AS', +' in_collection CONSTANT apex_collections.collection_name%TYPE := ''P'' || TO_CHAR(in_page_id);', +' --', +' v_query VARCHAR2(32767);', +' v_cols PLS_INTEGER;', +' v_cursor PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;', +' v_desc DBMS_SQL.DESC_TAB;', +' BEGIN', +' -- build query', +' v_query := v_query || ''SELECT'' || CHR(10) || '' u.user_id,'';', +' --', +' FOR r IN (', +' SELECT r.role_id', +' FROM roles r', +' WHERE r.app_id = app.get_app_id()', +' ORDER BY r.role_group NULLS LAST, r.order# NULLS LAST, r.role_id', +' ) LOOP', +' v_query := v_query || CHR(10) || '' MAX(CASE WHEN r.role_id = '''''' || r.role_id || '''''' THEN ''''Y'''' END) AS '' || LOWER(r.role_id) || ''_, '';', +' END LOOP;', +' --', +' v_query := RTRIM(v_query, '', '') || CHR(10) || ''FROM users u LEFT JOIN user_roles r ON r.app_id = app.get_app_id() AND r.user_id = u.user_id'' || CHR(10) || ''GROUP BY u.user_id'';', +' --', +' DBMS_OUTPUT.PUT_LINE(v_query);', +'', +' -- initialize and populate collection', +' IF APEX_COLLECTION.COLLECTION_EXISTS(in_collection) THEN', +' APEX_COLLECTION.DELETE_COLLECTION(in_collection);', +' END IF;', +' --', +' APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY (', +' p_collection_name => in_collection,', +' p_query => v_query', +' );', +'', +' -- pass proper column names via page items', +' DBMS_SQL.PARSE(v_cursor, v_query, DBMS_SQL.NATIVE);', +' DBMS_SQL.DESCRIBE_COLUMNS(v_cursor, v_cols, v_desc);', +' DBMS_SQL.CLOSE_CURSOR(v_cursor);', +' --', +' FOR i IN 1 .. v_desc.COUNT LOOP', +' BEGIN', +' APEX_UTIL.SET_SESSION_STATE (', +' p_name => ''P'' || in_page_id || ''_C'' || LPAD(i, 3, 0),', +' p_value => app.get_role_name(RTRIM(v_desc(i).col_name, ''_'')),', +' p_commit => FALSE', +' );', +' EXCEPTION', +' WHEN OTHERS THEN', +' NULL; -- item might not exists', +' END;', +' END LOOP;', +' END;', +'', +'', +'', +' PROCEDURE save_user_roles (', +' in_action CHAR,', +' in_c001 VARCHAR2 := NULL,', +' in_c002 VARCHAR2 := NULL,', +' in_c003 VARCHAR2 := NULL,', +' in_c004 VARCHAR2 := NULL,', +' in_c005 VARCHAR2 := NULL,', +' in_c006 VARCHAR2 := NULL,', +' in_c007 VARCHAR2 := NULL,', +' in_c008 VARCHAR2 := NULL,', +' in_c009 VARCHAR2 := NULL,', +' in_c010 VARCHAR2 := NULL,', +' in_c011 VARCHAR2 := NULL,', +' in_c012 VARCHAR2 := NULL,', +' in_c013 VARCHAR2 := NULL,', +' in_c014 VARCHAR2 := NULL,', +' in_c015 VARCHAR2 := NULL,', +' in_c016 VARCHAR2 := NULL,', +' in_c017 VARCHAR2 := NULL,', +' in_c018 VARCHAR2 := NULL,', +' in_c019 VARCHAR2 := NULL,', +' in_c020 VARCHAR2 := NULL,', +' in_c021 VARCHAR2 := NULL,', +' in_c022 VARCHAR2 := NULL,', +' in_c023 VARCHAR2 := NULL,', +' in_c024 VARCHAR2 := NULL,', +' in_c025 VARCHAR2 := NULL,', +' in_c026 VARCHAR2 := NULL,', +' in_c027 VARCHAR2 := NULL,', +' in_c028 VARCHAR2 := NULL,', +' in_c029 VARCHAR2 := NULL,', +' in_c030 VARCHAR2 := NULL,', +' in_c031 VARCHAR2 := NULL,', +' in_c032 VARCHAR2 := NULL,', +' in_c033 VARCHAR2 := NULL,', +' in_c034 VARCHAR2 := NULL,', +' in_c035 VARCHAR2 := NULL,', +' in_c036 VARCHAR2 := NULL,', +' in_c037 VARCHAR2 := NULL,', +' in_c038 VARCHAR2 := NULL,', +' in_c039 VARCHAR2 := NULL,', +' in_c040 VARCHAR2 := NULL,', +' in_c041 VARCHAR2 := NULL,', +' in_c042 VARCHAR2 := NULL,', +' in_c043 VARCHAR2 := NULL,', +' in_c044 VARCHAR2 := NULL,', +' in_c045 VARCHAR2 := NULL,', +' in_c046 VARCHAR2 := NULL,', +' in_c047 VARCHAR2 := NULL,', +' in_c048 VARCHAR2 := NULL,', +' in_c049 VARCHAR2 := NULL,', +' in_c050 VARCHAR2 := NULL', +' ) AS', +' rec user_roles%ROWTYPE;', +' v_offset CONSTANT PLS_INTEGER := 1; -- used columns', +' BEGIN', +' app.log_module(in_action, in_c001);', +' --', +' rec.app_id := app.get_app_id();', +' rec.user_id := in_c001;', +' rec.role_id := NULL;', +' rec.updated_by := app.get_user_id();', +' rec.updated_at := SYSDATE;', +'', +' -- cleanup all roles', +' DELETE FROM user_roles t', +' WHERE t.app_id = rec.app_id', +' AND t.user_id = rec.user_id;', +' --', +' IF in_action = ''D'' THEN', +' app.log_success();', +' RETURN;', +' END IF;', +'', +' -- match order with view on page', +' FOR r IN (', +' SELECT', +' r.role_id,', +' ''C'' || SUBSTR(1000 + v_offset + ROW_NUMBER() OVER(ORDER BY r.role_group NULLS LAST, r.order# NULLS LAST, r.role_id), 2, 3) AS arg', +' FROM roles r', +' WHERE r.app_id = rec.app_id', +' ) LOOP', +' rec.role_id := CASE', +' WHEN r.arg = ''C002'' AND in_c002 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C003'' AND in_c003 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C004'' AND in_c004 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C005'' AND in_c005 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C006'' AND in_c006 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C007'' AND in_c007 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C008'' AND in_c008 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C009'' AND in_c009 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C010'' AND in_c010 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C011'' AND in_c011 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C012'' AND in_c012 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C013'' AND in_c013 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C014'' AND in_c014 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C015'' AND in_c015 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C016'' AND in_c016 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C017'' AND in_c017 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C018'' AND in_c018 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C019'' AND in_c019 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C020'' AND in_c020 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C021'' AND in_c021 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C022'' AND in_c022 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C023'' AND in_c023 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C024'' AND in_c024 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C025'' AND in_c025 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C026'' AND in_c026 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C027'' AND in_c027 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C028'' AND in_c028 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C029'' AND in_c029 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C030'' AND in_c030 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C031'' AND in_c031 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C032'' AND in_c032 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C033'' AND in_c033 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C034'' AND in_c034 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C035'' AND in_c035 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C036'' AND in_c036 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C037'' AND in_c037 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C038'' AND in_c038 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C039'' AND in_c039 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C040'' AND in_c040 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C041'' AND in_c041 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C042'' AND in_c042 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C043'' AND in_c043 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C044'' AND in_c044 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C045'' AND in_c045 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C046'' AND in_c046 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C047'' AND in_c047 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C048'' AND in_c048 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C049'' AND in_c049 = ''Y'' THEN r.role_id', +' WHEN r.arg = ''C050'' AND in_c050 = ''Y'' THEN r.role_id', +' END;', +' --', +' IF rec.role_id IS NOT NULL THEN', +' INSERT INTO user_roles', +' VALUES rec;', +' END IF;', +' END LOOP;', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' FUNCTION get_setting (', +' in_name settings.setting_name%TYPE,', +' in_context settings.setting_context%TYPE := NULL', +' )', +' RETURN settings.setting_value%TYPE', +' AS', +' out_value settings.setting_value%TYPE;', +' BEGIN', +' SELECT s.setting_value INTO out_value', +' FROM settings s', +' WHERE s.app_id = app.get_app_id()', +' AND s.setting_name = in_name', +' AND (s.setting_context = in_context', +' OR (', +' s.setting_context IS NULL', +' AND in_context IS NULL', +' )', +' );', +' --', +' RETURN out_value;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' BEGIN', +' SELECT s.setting_value INTO out_value', +' FROM settings s', +' JOIN setting_contexts c', +' ON c.app_id = s.app_id', +' AND c.context_id = in_context', +' WHERE s.app_id = app.get_app_id()', +' AND s.setting_name = in_name', +' AND s.setting_context IS NULL;', +' --', +' RETURN out_value;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' RETURN NULL;', +' END;', +' END;', +'', +'', +'', +' PROCEDURE set_setting (', +' in_action CHAR,', +' in_setting_name_old settings.setting_name%TYPE,', +' in_setting_name settings.setting_name%TYPE,', +' in_setting_group settings.setting_group%TYPE := NULL,', +' in_setting_value settings.setting_value%TYPE := NULL,', +' in_is_numeric settings.is_numeric%TYPE := NULL,', +' in_is_date settings.is_date%TYPE := NULL,', +' in_description settings.description_%TYPE := NULL', +' )', +' AS', +' rec settings%ROWTYPE;', +' BEGIN', +' app.log_module_json (', +' ''action'', in_action,', +' ''name_old'', in_setting_name_old,', +' ''name'', in_setting_name,', +' ''value'', in_setting_value,', +' ''group'', in_setting_group,', +' ''is_numeric'', in_is_numeric,', +' ''is_date'', in_is_date', +' );', +' --', +' rec.app_id := app.get_app_id();', +' rec.setting_name := UPPER(in_setting_name);', +' rec.setting_value := in_setting_value;', +' rec.setting_context := NULL;', +' rec.setting_group := in_setting_group;', +' rec.is_numeric := in_is_numeric;', +' rec.is_date := in_is_date;', +' rec.description_ := in_description;', +' rec.updated_by := app.get_user_id();', +' rec.updated_at := SYSDATE;', +' --', +' CASE in_action', +' WHEN ''D'' THEN', +' DELETE FROM settings s', +' WHERE s.app_id = rec.app_id', +' AND s.setting_name = in_setting_name_old;', +' --', +' WHEN ''U'' THEN', +' UPDATE settings s', +' SET ROW = rec', +' WHERE s.app_id = rec.app_id', +' AND s.setting_name = in_setting_name_old', +' AND s.setting_context IS NULL;', +' --', +' IF SQL%ROWCOUNT = 0 THEN', +' app.raise_error(''SETTINGS_UPDATE_FAILED'');', +' END IF;', +' --', +' UPDATE settings s', +' SET s.setting_name = rec.setting_name', +' WHERE s.app_id = rec.app_id', +' AND s.setting_name = in_setting_name_old;', +' --', +' ELSE', +' BEGIN', +' INSERT INTO settings VALUES rec;', +' EXCEPTION', +' WHEN DUP_VAL_ON_INDEX THEN', +' app.raise_error(''SETTINGS_EXISTS'');', +' END;', +' END CASE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE set_setting_bulk (', +' in_c001 settings.setting_value%TYPE,', +' in_c002 settings.setting_value%TYPE,', +' in_c003 settings.setting_value%TYPE := NULL,', +' in_c004 settings.setting_value%TYPE := NULL,', +' in_c005 settings.setting_value%TYPE := NULL,', +' in_c006 settings.setting_value%TYPE := NULL,', +' in_c007 settings.setting_value%TYPE := NULL,', +' in_c008 settings.setting_value%TYPE := NULL,', +' in_c009 settings.setting_value%TYPE := NULL,', +' in_c010 settings.setting_value%TYPE := NULL,', +' in_c011 settings.setting_value%TYPE := NULL,', +' in_c012 settings.setting_value%TYPE := NULL,', +' in_c013 settings.setting_value%TYPE := NULL,', +' in_c014 settings.setting_value%TYPE := NULL,', +' in_c015 settings.setting_value%TYPE := NULL,', +' in_c016 settings.setting_value%TYPE := NULL,', +' in_c017 settings.setting_value%TYPE := NULL,', +' in_c018 settings.setting_value%TYPE := NULL,', +' in_c019 settings.setting_value%TYPE := NULL,', +' in_c020 settings.setting_value%TYPE := NULL,', +' in_c021 settings.setting_value%TYPE := NULL,', +' in_c022 settings.setting_value%TYPE := NULL,', +' in_c023 settings.setting_value%TYPE := NULL,', +' in_c024 settings.setting_value%TYPE := NULL,', +' in_c025 settings.setting_value%TYPE := NULL,', +' in_c026 settings.setting_value%TYPE := NULL,', +' in_c027 settings.setting_value%TYPE := NULL,', +' in_c028 settings.setting_value%TYPE := NULL,', +' in_c029 settings.setting_value%TYPE := NULL,', +' in_c030 settings.setting_value%TYPE := NULL,', +' in_c031 settings.setting_value%TYPE := NULL,', +' in_c032 settings.setting_value%TYPE := NULL,', +' in_c033 settings.setting_value%TYPE := NULL,', +' in_c034 settings.setting_value%TYPE := NULL,', +' in_c035 settings.setting_value%TYPE := NULL,', +' in_c036 settings.setting_value%TYPE := NULL,', +' in_c037 settings.setting_value%TYPE := NULL,', +' in_c038 settings.setting_value%TYPE := NULL,', +' in_c039 settings.setting_value%TYPE := NULL,', +' in_c040 settings.setting_value%TYPE := NULL,', +' in_c041 settings.setting_value%TYPE := NULL,', +' in_c042 settings.setting_value%TYPE := NULL,', +' in_c043 settings.setting_value%TYPE := NULL,', +' in_c044 settings.setting_value%TYPE := NULL,', +' in_c045 settings.setting_value%TYPE := NULL,', +' in_c046 settings.setting_value%TYPE := NULL,', +' in_c047 settings.setting_value%TYPE := NULL,', +' in_c048 settings.setting_value%TYPE := NULL,', +' in_c049 settings.setting_value%TYPE := NULL,', +' in_c050 settings.setting_value%TYPE := NULL', +' )', +' AS', +' rec settings%ROWTYPE;', +' v_offset CONSTANT PLS_INTEGER := 3; -- used columns (name, group, default)', +' BEGIN', +' app.log_module(in_c001, in_c002, in_c003, in_c004, in_c005, in_c006, in_c007, in_c008);', +' --', +' rec.app_id := app.get_app_id();', +' rec.setting_name := in_c001;', +' rec.setting_value := in_c003; -- fill in the loop', +' rec.setting_context := NULL; -- fill in the loop', +' rec.setting_group := in_c002;', +' rec.updated_by := app.get_user_id();', +' rec.updated_at := SYSDATE;', +'', +' -- cleanup setting', +' DELETE FROM settings s', +' WHERE s.app_id = rec.app_id', +' AND s.setting_name = rec.setting_name', +' AND s.setting_context IS NOT NULL;', +'', +' -- update default value', +' UPDATE settings s', +' SET ROW = rec', +' WHERE s.app_id = rec.app_id', +' AND s.setting_name = rec.setting_name', +' AND s.setting_context IS NULL;', +'', +' -- match order with view on page', +' FOR r IN (', +' SELECT', +' s.context_id,', +' ''C'' || SUBSTR(1000 + v_offset + ROW_NUMBER() OVER(ORDER BY s.order# NULLS LAST, s.context_id), 2, 3) AS arg', +' FROM setting_contexts s', +' WHERE s.app_id = rec.app_id', +' ) LOOP', +' CONTINUE WHEN r.arg IN (''C001'', ''C002'', ''C003'');', +' --', +' rec.setting_context := CASE', +' WHEN r.arg = ''C003'' THEN r.context_id WHEN r.arg = ''C004'' THEN r.context_id', +' WHEN r.arg = ''C005'' THEN r.context_id WHEN r.arg = ''C006'' THEN r.context_id', +' WHEN r.arg = ''C007'' THEN r.context_id WHEN r.arg = ''C008'' THEN r.context_id', +' WHEN r.arg = ''C009'' THEN r.context_id WHEN r.arg = ''C010'' THEN r.context_id', +' WHEN r.arg = ''C011'' THEN r.context_id WHEN r.arg = ''C012'' THEN r.context_id', +' WHEN ')) +); +null; +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'r.arg = ''C013'' THEN r.context_id WHEN r.arg = ''C014'' THEN r.context_id', +' WHEN r.arg = ''C015'' THEN r.context_id WHEN r.arg = ''C016'' THEN r.context_id', +' WHEN r.arg = ''C017'' THEN r.context_id WHEN r.arg = ''C018'' THEN r.context_id', +' WHEN r.arg = ''C019'' THEN r.context_id WHEN r.arg = ''C020'' THEN r.context_id', +' WHEN r.arg = ''C021'' THEN r.context_id WHEN r.arg = ''C022'' THEN r.context_id', +' WHEN r.arg = ''C023'' THEN r.context_id WHEN r.arg = ''C024'' THEN r.context_id', +' WHEN r.arg = ''C025'' THEN r.context_id WHEN r.arg = ''C026'' THEN r.context_id', +' WHEN r.arg = ''C027'' THEN r.context_id WHEN r.arg = ''C028'' THEN r.context_id', +' WHEN r.arg = ''C029'' THEN r.context_id WHEN r.arg = ''C030'' THEN r.context_id', +' WHEN r.arg = ''C031'' THEN r.context_id WHEN r.arg = ''C032'' THEN r.context_id', +' WHEN r.arg = ''C033'' THEN r.context_id WHEN r.arg = ''C034'' THEN r.context_id', +' WHEN r.arg = ''C035'' THEN r.context_id WHEN r.arg = ''C036'' THEN r.context_id', +' WHEN r.arg = ''C037'' THEN r.context_id WHEN r.arg = ''C038'' THEN r.context_id', +' WHEN r.arg = ''C039'' THEN r.context_id WHEN r.arg = ''C040'' THEN r.context_id', +' WHEN r.arg = ''C041'' THEN r.context_id WHEN r.arg = ''C042'' THEN r.context_id', +' WHEN r.arg = ''C043'' THEN r.context_id WHEN r.arg = ''C044'' THEN r.context_id', +' WHEN r.arg = ''C045'' THEN r.context_id WHEN r.arg = ''C046'' THEN r.context_id', +' WHEN r.arg = ''C047'' THEN r.context_id WHEN r.arg = ''C048'' THEN r.context_id', +' WHEN r.arg = ''C049'' THEN r.context_id WHEN r.arg = ''C050'' THEN r.context_id', +' END;', +' --', +' rec.setting_value := CASE', +' WHEN r.arg = ''C003'' THEN in_c003 WHEN r.arg = ''C004'' THEN in_c004', +' WHEN r.arg = ''C005'' THEN in_c005 WHEN r.arg = ''C006'' THEN in_c006', +' WHEN r.arg = ''C007'' THEN in_c007 WHEN r.arg = ''C008'' THEN in_c008', +' WHEN r.arg = ''C009'' THEN in_c009 WHEN r.arg = ''C010'' THEN in_c010', +' WHEN r.arg = ''C011'' THEN in_c011 WHEN r.arg = ''C012'' THEN in_c012', +' WHEN r.arg = ''C013'' THEN in_c013 WHEN r.arg = ''C014'' THEN in_c014', +' WHEN r.arg = ''C015'' THEN in_c015 WHEN r.arg = ''C016'' THEN in_c016', +' WHEN r.arg = ''C017'' THEN in_c017 WHEN r.arg = ''C018'' THEN in_c018', +' WHEN r.arg = ''C019'' THEN in_c019 WHEN r.arg = ''C020'' THEN in_c020', +' WHEN r.arg = ''C021'' THEN in_c021 WHEN r.arg = ''C022'' THEN in_c022', +' WHEN r.arg = ''C023'' THEN in_c023 WHEN r.arg = ''C024'' THEN in_c024', +' WHEN r.arg = ''C025'' THEN in_c025 WHEN r.arg = ''C026'' THEN in_c026', +' WHEN r.arg = ''C027'' THEN in_c027 WHEN r.arg = ''C028'' THEN in_c028', +' WHEN r.arg = ''C029'' THEN in_c029 WHEN r.arg = ''C030'' THEN in_c030', +' WHEN r.arg = ''C031'' THEN in_c031 WHEN r.arg = ''C032'' THEN in_c032', +' WHEN r.arg = ''C033'' THEN in_c033 WHEN r.arg = ''C034'' THEN in_c034', +' WHEN r.arg = ''C035'' THEN in_c035 WHEN r.arg = ''C036'' THEN in_c036', +' WHEN r.arg = ''C037'' THEN in_c037 WHEN r.arg = ''C038'' THEN in_c038', +' WHEN r.arg = ''C039'' THEN in_c039 WHEN r.arg = ''C040'' THEN in_c040', +' WHEN r.arg = ''C041'' THEN in_c041 WHEN r.arg = ''C042'' THEN in_c042', +' WHEN r.arg = ''C043'' THEN in_c043 WHEN r.arg = ''C044'' THEN in_c044', +' WHEN r.arg = ''C045'' THEN in_c045 WHEN r.arg = ''C046'' THEN in_c046', +' WHEN r.arg = ''C047'' THEN in_c047 WHEN r.arg = ''C048'' THEN in_c048', +' WHEN r.arg = ''C049'' THEN in_c049 WHEN r.arg = ''C050'' THEN in_c050', +' END;', +' --', +' CONTINUE WHEN (rec.setting_context IS NULL OR rec.setting_value IS NULL);', +' --', +' INSERT INTO settings', +' VALUES rec;', +' END LOOP;', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE rebuild_settings', +' AS', +' q VARCHAR2(32767);', +' b VARCHAR2(32767);', +' BEGIN', +' app.log_module();', +' --', +' app_actions.refresh_user_source_views();', +' --', +' q := ''CREATE OR REPLACE PACKAGE '' || LOWER(settings_package) || '' AS'' || CHR(10);', +' b := ''CREATE OR REPLACE PACKAGE BODY '' || LOWER(settings_package) || '' AS'' || CHR(10);', +' --', +' -- @TODO: MULTIPLE APPS !!!', +' --', +' -- merge all apps/settings (in same schema) into 1 sett package', +' -- use get_setting_name_DATATYPE ??? for dates, numbers', +' -- resolve app inside for current application', +' --', +' FOR c IN (', +' SELECT', +' s.setting_name,', +' s.is_numeric,', +' s.is_date', +' FROM settings s', +' WHERE s.app_id = app.get_app_id()', +' --', +' -- @TODO: all (active?) apps', +' --', +' AND s.setting_context IS NULL', +' ORDER BY s.setting_name', +' ) LOOP', +' -- create specification', +' q := q || CHR(10);', +' q := q || '' FUNCTION '' || LOWER(settings_prefix) || LOWER(c.setting_name) || '' ('' || CHR(10);', +' q := q || '' in_context settings.setting_context%TYPE := NULL'' || CHR(10);', +' q := q || '' )'' || CHR(10);', +' q := q || '' RETURN '' || CASE', +' WHEN c.is_numeric = ''Y'' THEN ''NUMBER''', +' WHEN c.is_date = ''Y'' THEN ''DATE''', +' ELSE ''VARCHAR2'' END || CHR(10);', +' q := q || '' RESULT_CACHE;'' || CHR(10);', +'', +' -- create package body', +' b := b || CHR(10);', +' b := b || '' FUNCTION '' || LOWER(settings_prefix) || LOWER(c.setting_name) || '' ('' || CHR(10);', +' b := b || '' in_context settings.setting_context%TYPE := NULL'' || CHR(10);', +' b := b || '' )'' || CHR(10);', +' b := b || '' RETURN '' || CASE', +' WHEN c.is_numeric = ''Y'' THEN ''NUMBER''', +' WHEN c.is_date = ''Y'' THEN ''DATE''', +' ELSE ''VARCHAR2'' END || CHR(10);', +' b := b || '' RESULT_CACHE AS'' || CHR(10);', +' b := b || '' BEGIN'' || CHR(10);', +' b := b || '' RETURN '' || CASE', +' WHEN c.is_numeric = ''Y'' THEN ''TO_NUMBER(''', +' WHEN c.is_date = ''Y'' THEN ''app.get_date(''', +' END || ''app_actions.get_setting ('' || CHR(10);', +' b := b || '' in_name => '''''' || c.setting_name || '''''','' || CHR(10);', +' b := b || '' in_context => in_context'' || CHR(10);', +' b := b || '' '' || CASE', +' WHEN NVL(c.is_numeric, c.is_date) = ''Y'' THEN '')''', +' END || '');'' || CHR(10);', +' b := b || '' EXCEPTION'' || CHR(10);', +' b := b || '' WHEN NO_DATA_FOUND THEN'' || CHR(10);', +' b := b || '' RETURN NULL;'' || CHR(10);', +' b := b || '' END;'' || CHR(10);', +' END LOOP;', +' --', +' q := q || CHR(10) || ''END;'';', +' b := b || CHR(10) || ''END;'';', +' --', +' EXECUTE IMMEDIATE q;', +' EXECUTE IMMEDIATE b;', +' --', +' recompile();', +' --', +' /*', +' DBMS_RESULT_CACHE.INVALIDATE (', +' owner => app.schema_owner,', +' name => app_actions.settings_package', +' );', +' */', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE prep_settings_pivot (', +' in_page_id apex_application_pages.page_id%TYPE', +' ) AS', +' in_collection CONSTANT apex_collections.collection_name%TYPE := ''P'' || TO_CHAR(in_page_id);', +' --', +' v_query VARCHAR2(32767);', +' v_cols PLS_INTEGER;', +' v_cursor PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;', +' v_desc DBMS_SQL.DESC_TAB;', +' --', +' v_context_name setting_contexts.context_name%TYPE;', +' BEGIN', +' -- build query', +' v_query := v_query || ''SELECT'' || CHR(10);', +' v_query := v_query || '' s.setting_name,'' || CHR(10);', +' v_query := v_query || '' MAX(s.setting_group) AS setting_group,'' || CHR(10);', +' --', +' v_query := v_query || '' MAX(CASE WHEN s.setting_context IS NULL THEN s.setting_value END) AS null__,'' || CHR(10);', +' --', +' FOR c IN (', +' SELECT c.context_id', +' FROM setting_contexts c', +' WHERE c.app_id = app.get_app_id()', +' ORDER BY c.order#, c.context_id', +' ) LOOP', +' v_query := v_query || '' MAX(CASE WHEN s.setting_context = '''''' || c.context_id || '''''' THEN s.setting_value END) AS '' || LOWER(c.context_id) || ''_,'' || CHR(10);', +' END LOOP;', +' --', +' v_query := RTRIM(RTRIM(v_query, CHR(10)), '','') || CHR(10);', +' v_query := v_query || ''FROM settings s'' || CHR(10);', +' v_query := v_query || ''WHERE s.app_id = app.get_app_id()'' || CHR(10);', +' v_query := v_query || ''GROUP BY s.setting_name'';', +' --', +' app.log_debug(in_payload => v_query);', +' DBMS_OUTPUT.PUT_LINE(v_query);', +'', +' -- initialize and populate collection', +' IF APEX_COLLECTION.COLLECTION_EXISTS(in_collection) THEN', +' APEX_COLLECTION.DELETE_COLLECTION(in_collection);', +' END IF;', +' --', +' APEX_COLLECTION.CREATE_COLLECTION_FROM_QUERY (', +' p_collection_name => in_collection,', +' p_query => v_query', +' );', +'', +' -- pass proper column names via page items', +' DBMS_SQL.PARSE(v_cursor, v_query, DBMS_SQL.NATIVE);', +' DBMS_SQL.DESCRIBE_COLUMNS(v_cursor, v_cols, v_desc);', +' DBMS_SQL.CLOSE_CURSOR(v_cursor);', +' --', +' FOR i IN 1 .. v_desc.COUNT LOOP', +' BEGIN', +' SELECT NVL(c.context_name, c.context_id) INTO v_context_name', +' FROM setting_contexts c', +' WHERE c.app_id = app.get_app_id()', +' AND c.context_id = RTRIM(v_desc(i).col_name, ''_'');', +' --', +' APEX_UTIL.SET_SESSION_STATE (', +' p_name => ''P'' || in_page_id || ''_C'' || LPAD(i, 3, 0),', +' p_value => v_context_name,', +' p_commit => FALSE', +' );', +' EXCEPTION', +' WHEN OTHERS THEN', +' NULL; -- item might not exists', +' END;', +' END LOOP;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE refresh_user_source_views', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' BEGIN', +' app.log_module();', +' --', +' DELETE FROM user_source_views;', +' --', +' FOR c IN (', +' SELECT', +' v.view_name,', +' DBMS_METADATA.GET_DDL(''VIEW'', v.view_name) AS content', +' FROM user_views v', +' ) LOOP', +' DBMS_OUTPUT.PUT_LINE(c.view_name);', +' app_actions.clob_to_lines(c.view_name, REGEXP_REPLACE(c.content, ''^(\s*)'', ''''));', +' END LOOP;', +' --', +' COMMIT;', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' ROLLBACK;', +' RAISE;', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'', +'', +' PROCEDURE clob_to_lines (', +' in_name VARCHAR2,', +' in_clob CLOB', +' )', +' AS', +' clob_len PLS_INTEGER := DBMS_LOB.GETLENGTH(in_clob);', +' clob_line PLS_INTEGER := 1;', +' offset PLS_INTEGER := 1;', +' amount PLS_INTEGER := 32767;', +' buffer VARCHAR2(32767);', +' BEGIN', +' WHILE offset < clob_len LOOP', +' IF INSTR(in_clob, CHR(10), offset) = 0 THEN', +' amount := clob_len - offset + 1;', +' ELSE', +' amount := INSTR(in_clob, CHR(10), offset) - offset;', +' END IF;', +' --', +' IF amount = 0 THEN', +' buffer := '''';', +' ELSE', +' DBMS_LOB.READ(in_clob, amount, offset, buffer);', +' END IF;', +' --', +' --', +' -- CREATE COLLECTION INSTEAD', +' -- RETURN', +' --', +' IF clob_line > 1 THEN', +' INSERT INTO user_source_views (name, line, text)', +' VALUES (', +' in_name,', +' clob_line - 1,', +' REPLACE(REPLACE(CASE WHEN clob_line = 2 THEN LTRIM(buffer) ELSE buffer END, CHR(13), ''''), CHR(10), '''')', +' );', +' END IF;', +' --', +' clob_line := clob_line + 1;', +' IF INSTR(in_clob, CHR(10), offset) = clob_len THEN', +' buffer := '''';', +' END IF;', +' --', +' offset := offset + amount + 1;', +' END LOOP;', +' END;', +'', +'', +'', +' FUNCTION clob_to_blob (', +' in_clob CLOB', +' )', +' RETURN BLOB', +' AS', +' out_blob BLOB;', +' --', +' v_file_size INTEGER := DBMS_LOB.LOBMAXSIZE;', +' v_dest_offset INTEGER := 1;', +' v_src_offset INTEGER := 1;', +' v_blob_csid NUMBER := DBMS_LOB.DEFAULT_CSID;', +' v_lang_context NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;', +' v_warning INTEGER;', +' v_length NUMBER;', +' BEGIN', +' DBMS_LOB.CREATETEMPORARY(out_blob, TRUE);', +' DBMS_LOB.CONVERTTOBLOB(out_blob, in_clob, v_file_size, v_dest_offset, v_src_offset, v_blob_csid, v_lang_context, v_warning);', +' RETURN out_blob;', +' END;', +'', +'', +'', +' PROCEDURE send_mail (', +' in_to VARCHAR2,', +' in_subject VARCHAR2,', +' in_body CLOB,', +' in_cc VARCHAR2 := NULL,', +' in_bcc VARCHAR2 := NULL,', +' in_from VARCHAR2 := NULL,', +' in_attach_name VARCHAR2 := NULL,', +' in_attach_mime VARCHAR2 := NULL,', +' in_attach_data CLOB := NULL,', +' in_compress BOOLEAN := FALSE', +' ) AS', +' boundary CONSTANT VARCHAR2(80) := ''-----5b9d8059445a8eb8c025f159131f02d94969a12c16363d4dec42e893b374cb85-----'';', +' --', +' reply UTL_SMTP.REPLY;', +' conn UTL_SMTP.CONNECTION;', +' --', +' blob_content BLOB;', +' blob_gzipped BLOB;', +' blob_amount BINARY_INTEGER := 6000;', +' blob_offset PLS_INTEGER := 1;', +' buffer VARCHAR2(24000);', +' buffer_raw RAW(6000);', +' --', +' FUNCTION quote_encoding (', +' in_text VARCHAR2', +' )', +' RETURN VARCHAR2 AS', +' BEGIN', +' RETURN ''=?UTF-8?Q?'' || REPLACE(', +' UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.QUOTED_PRINTABLE_ENCODE(', +' UTL_RAW.CAST_TO_RAW(in_text))), ''='' || UTL_TCP.CRLF, '''') || ''?='';', +' END;', +' --', +' FUNCTION quote_address (', +' in_address VARCHAR2,', +' in_strip_name BOOLEAN := FALSE', +' )', +' RETURN VARCHAR2 AS', +' in_found PLS_INTEGER;', +' BEGIN', +' IF in_strip_name THEN', +' RETURN REGEXP_REPLACE(in_address, ''.*\s?<(\S+)>$'', ''\1'');', +' ELSE', +' in_found := REGEXP_INSTR(in_address, ''\s?<\S+@\S+\.\S{2,6}>$'');', +' IF in_found > 1 THEN', +' RETURN quote_encoding(RTRIM(SUBSTR(in_address, 1, in_found))) || SUBSTR(in_address, in_found);', +' ELSE', +' RETURN in_address;', +' END IF;', +' END IF;', +' END;', +' --', +' PROCEDURE split_addresses (', +' in_out_conn IN OUT NOCOPY UTL_SMTP.CONNECTION,', +' in_to IN VARCHAR2', +' )', +' AS', +' BEGIN', +' FOR i IN (', +' SELECT LTRIM(RTRIM(REGEXP_SUBSTR(in_to, ''[^;,]+'', 1, LEVEL))) AS address', +' FROM DUAL', +' CONNECT BY REGEXP_SUBSTR(in_to, ''[^;,]+'', 1, LEVEL) IS NOT NULL)', +' LOOP', +' UTL_SMTP.RCPT(in_out_conn, quote_address(i.address, TRUE));', +' END LOOP;', +' END;', +' BEGIN', +' app.log_module(in_to, in_subject, in_cc, in_bcc, in_attach_name);', +'', +' -- connect to SMTP server', +' reply := UTL_SMTP.OPEN_CONNECTION(smtp_host, smtp_port, conn, smtp_timeout);', +' UTL_SMTP.HELO(conn, smtp_host);', +' IF smtp_username IS NOT NULL THEN', +' UTL_SMTP.COMMAND(conn, ''AUTH LOGIN'');', +' UTL_SMTP.COMMAND(conn, UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(smtp_username)));', +' IF smtp_password IS NOT NULL THEN', +' UTL_SMTP.COMMAND(conn, UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(smtp_password)));', +' END IF;', +' END IF;', +'', +' -- prepare headers', +' UTL_SMTP.MAIL(conn, quote_address(COALESCE(in_from, smtp_from), TRUE));', +' --', +' -- apex_applications.email_from', +' --', +'', +' -- handle multiple recipients', +' split_addresses(conn, in_to);', +' --', +' IF in_cc IS NOT NULL THEN', +' split_addresses(conn, in_cc);', +' END IF;', +' --', +' IF in_bcc IS NOT NULL THEN', +' split_addresses(conn, in_bcc);', +' END IF;', +'', +' -- continue with headers', +' UTL_SMTP.OPEN_DATA(conn);', +' --', +' UTL_SMTP.WRITE_DATA(conn, ''Date: '' || TO_CHAR(SYSDATE, ''DD-MON-YYYY HH24:MI:SS'') || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''From: '' || quote_address(COALESCE(in_from, smtp_from)) || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''To: '' || quote_address(in_to) || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Subject: '' || quote_encoding(in_subject) || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Reply-To: '' || in_from || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''MIME-Version: 1.0'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Type: multipart/mixed; boundary="'' || boundary || ''"'' || UTL_TCP.CRLF || UTL_TCP.CRLF);', +'', +' -- prepare body content', +' IF in_body IS NOT NULL THEN', +' UTL_SMTP.WRITE_DATA(conn, ''--'' || boundary || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Type: '' || ''text/html'' || ''; charset="utf-8"'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Transfer-Encoding: base64'' || UTL_TCP.CRLF || UTL_TCP.CRLF);', +' --', +' FOR i IN 0 .. TRUNC((DBMS_LOB.GETLENGTH(in_body) - 1) / 12000) LOOP', +' UTL_SMTP.WRITE_RAW_DATA(conn, UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(in_body, 12000, i * 12000 + 1))));', +' END LOOP;', +' --', +' UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF || UTL_TCP.CRLF);', +' END IF;', +'', +' -- prepare attachment', +' IF in_attach_name IS NOT NULL AND in_compress THEN', +' -- compress attachment', +' UTL_SMTP.WRITE_DATA(conn, ''--'' || boundary || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Transfer-Encoding: base64'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Type: '' || ''application/octet-stream'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Disposition: attachment; filename="'' || in_attach_name || ''.gz"'' || UTL_TCP.CRLF || UTL_TCP.CRLF);', +' --', +' blob_content := app_actions.clob_to_blob(in_attach_data);', +' DBMS_LOB.CREATETEMPORARY(blob_gzipped, TRUE, DBMS_LOB.CALL);', +' DBMS_LOB.OPEN(blob_gzipped, DBMS_LOB.LOB_READWRITE);', +' --', +' UTL_COMPRESS.LZ_COMPRESS(blob_content, blob_gzipped, quality => 8);', +' --', +' WHILE blob_offset <= DBMS_LOB.GETLENGTH(blob_gzipped) LOOP', +' DBMS_LOB.READ(blob_gzipped, blob_amount, blob_offset, buffer_raw);', +' UTL_SMTP.WRITE_RAW_DATA(conn, UTL_ENCODE.BASE64_ENCODE(buffer_raw));', +' blob_offset := blob_offset + blob_amount;', +' END LOOP;', +' DBMS_LOB.FREETEMPORARY(blob_gzipped);', +' --', +' UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF || UTL_TCP.CRLF);', +' ELSIF in_attach_name IS NOT NULL THEN', +' -- regular attachment', +' UTL_SMTP.WRITE_DATA(conn, ''--'' || boundary || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Transfer-Encoding: base64'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Type: '' || in_attach_mime || ''; name="'' || in_attach_name || ''"'' || UTL_TCP.CRLF);', +' UTL_SMTP.WRITE_DATA(conn, ''Content-Disposition: attachment; filename="'' || in_attach_name || ''"'' || UTL_TCP.CRLF || UTL_TCP.CRLF);', +' --', +' FOR i IN 0 .. TRUNC((DBMS_LOB.GETLENGTH(in_attach_data) - 1) / 12000) LOOP', +' UTL_SMTP.WRITE_RAW_DATA(conn, UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(in_attach_data, 12000, i * 12000 + 1))));', +' END LOOP;', +' --', +' UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF || UTL_TCP.CRLF);', +' END IF;', +'', +' -- close', +' UTL_SMTP.WRITE_DATA(conn, ''--'' || boundary || ''--'' || UTL_TCP.CRLF);', +' UTL_SMTP.CLOSE_DATA(conn);', +' UTL_SMTP.QUIT(conn);', +' EXCEPTION', +' WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN', +' BEGIN', +' UTL_SMTP.QUIT(conn);', +' EXCEPTION', +' WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN', +' NULL;', +' END;', +' END;', +'', +'', +'', +' PROCEDURE update_global_message (', +' in_message VARCHAR2 := NULL,', +' in_app_id apex_applications.application_id%TYPE := NULL', +' )', +' AS', +' PRAGMA AUTONOMOUS_TRANSACTION;', +' --', +' v_workspace_id apex_applications.workspace%TYPE;', +' BEGIN', +' app.log_module(in_message, in_app_id);', +'', +' -- setup workspace first', +' SELECT a.workspace INTO v_workspace_id', +' FROM apex_applications a', +' WHERE a.application_id = COALESCE(in_app_id, app.get_app_id());', +' --', +' APEX_UTIL.SET_WORKSPACE (', +' p_workspace => v_workspace_id', +' );', +' APEX_UTIL.SET_SECURITY_GROUP_ID (', +' p_security_group_id => APEX_UTIL.FIND_SECURITY_GROUP_ID(p_workspace => v_workspace_id)', +' );', +'', +' -- update global message', +' APEX_UTIL.SET_GLOBAL_NOTIFICATION (', +' p_application_id => COALESCE(in_app_id, app.get_app_id()),', +' p_global_notification_message => in_message', +' );', +' --', +' app.log_success();', +' EXCEPTION', +' WHEN app.app_exception THEN', +' ROLLBACK;', +' RAISE;', +' WHEN OTHERS THEN', +' ROLLBACK;', +' app.raise_error();', +' END;', +'', +'END;', +'/', +'', +'CREATE OR REPLACE PROCEDURE "RECOMPILE" (', +' in_filter_type VARCHAR2 := ''%'',', +' in_filter_name VARCHAR2 := ''%'',', +' in_code_type VARCHAR2 := ''INTERPRETED'',', +' in_scope VARCHAR2 := ''IDENTIFIERS:ALL, STATEMENTS:ALL'',', +' in_warnings VARCHAR2 := ''ENABLE:SEVERE, ENABLE:PERFORMANCE'',', +' in_optimize NUMBER := 2,', +' in_ccflags VARCHAR2 := NULL,', +' in_invalid_only BOOLEAN := TRUE', +') AS', +' in_invalids CONSTANT CHAR := CASE WHEN in_invalid_only THEN ''Y'' END;', +' ccflags VARCHAR2(32767);', +' query_ VARCHAR2(32767);', +' invalids PLS_INTEGER;', +'BEGIN', +' /**', +' * This procedure is part of the Kvido project under MIT licence.', +' * https://github.com/jkvetina/Kvido', +' *', +' * Copyright (c) Jan Kvetina, 2021', +' *', +' * (R)', +' * --- ---', +' * #@@@@@@ &@@@@@@', +' * @@@@@@@@ .@ @@@@@@@@', +' * ----- @@@@@@ @@@@@@, @@@@@@@ -----', +' * &@@@@@@@@@@@ @@@ &@@@@@@@@@. @@@@ .@@@@@@@@@@@#', +' * @@@@@@@@@@@ @ @@@@@@@@@@@@@ @ @@@@@@@@@@@', +' * /@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@@@@@', +' * @@@@@@@@@ @@@@@@@@@@@@@@@ &@@@@@@@@', +' * @@@@@@@( @@@@@@@@@@@@@@@ @@@@@@@@', +' * @@@@@@( @@@@@@@@@@@@@@ @@@@@@@', +' * .@@@@@, @@@@@@@@@@@@@ @@@@@@', +' * @@@@@@ *@@@@@@@@@@@@@ @@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * @@@@@@@@@@@@@@@@@@@@@@@@@@@@', +' * ,@@@@@@@@@@@@@@@@@@@@@@@@@', +' * ,@@@@@@@@@@@@@@@@@@@@@', +' * jankvetina.cz', +' * -------', +' *', +' */', +'', +' -- first recompile invalid and requested objects', +' DBMS_OUTPUT.PUT_LINE(''--'');', +' DBMS_OUTPUT.PUT(''INVALID: '');', +' --', +' FOR c IN (', +' SELECT o.object_name, o.object_type', +' FROM user_objects o', +' WHERE o.status != ''VALID''', +' AND o.object_type NOT IN (''SEQUENCE'', ''MATERIALIZED VIEW'')', +' AND o.object_name != $$PLSQL_UNIT -- not this procedure', +' UNION ALL', +' SELECT o.object_name, o.object_type', +' FROM user_objects o', +' WHERE in_invalids IS NULL', +' AND o.object_type IN (''PACKAGE'', ''PACKAGE BODY'', ''PROCEDURE'', ''FUNCTION'', ''TRIGGER'', ''VIEW'', ''SYNONYM'')', +' AND (o.object_type LIKE in_filter_type OR in_filter_type IS NULL)', +' AND (o.object_name LIKE in_filter_name OR in_filter_name IS NULL)', +' AND o.object_name != $$PLSQL_UNIT -- not this procedure', +' ) LOOP', +' -- apply ccflags only relevant to current object', +' IF in_ccflags IS NOT NULL THEN', +' BEGIN', +' SELECT', +' LISTAGG(REGEXP_SUBSTR(in_ccflags, ''('' || s.flag_name || '':[^,]+)'', 1, 1, NULL, 1), '', '')', +' WITHIN GROUP (ORDER BY s.flag_name)', +' INTO ccflags', +' FROM (', +' SELECT DISTINCT REGEXP_SUBSTR(s.text, ''[$].*\s[$][$]([A-Z0-9-_]+)\s.*[$]'', 1, 1, NULL, 1) AS flag_name', +' FROM user_source s', +' WHERE REGEXP_LIKE(s.text, ''[$].*\s[$][$][A-Z0-9-_]+\s.*[$]'')', +' AND s.name = c.object_name', +' AND s.type = c.object_type', +' ) s;', +' EXCEPTION', +' WHEN NO_DATA_FOUND THEN', +' ccflags := NULL;', +' END;', +' END IF;', +' --', +' BEGIN', +' query_ := ''ALTER '' || REPLACE(c.object_type, '' BODY'', '''') || '' '' || c.object_name || '' COMPILE'' ||', +' CASE WHEN c.object_type LIKE ''% BODY'' THEN '' BODY'' END || '' '' ||', +' CASE WHEN c.object_type IN (', +' ''PACKAGE'', ''PACKAGE BODY'', ''PROCEDURE'', ''FUNCTION'', ''TRIGGER''', +' ) THEN', +' CASE WHEN ccflags IS NOT NULL THEN ''PLSQL_CCFLAGS = '''''' || RTRIM(ccflags) || '''''' '' END ||', +' CASE WHEN in_code_type IS NOT NULL THEN ''PLSQL_CODE_TYPE = '' || in_code_type || '' '' END ||', +' CASE WHEN in_optimize IS NOT NULL THEN ''PLSQL_OPTIMIZE_LEVEL = '' || in_optimize || '' '' END ||', +' CASE WHEN in_warnings IS NOT NULL THEN ''PLSQL_WARNINGS = '''''' || REPLACE(in_warnings, '','', '''''', '''''') || '''''' '' END ||', +' CASE WHEN in_scope IS NOT NULL THEN ''PLSCOPE_SETTINGS = '''''' || RTRIM(in_scope) || '''''' '' END ||', +' ''REUSE SETTINGS''', +' END;', +' --', +' EXECUTE IMMEDIATE query_;', +' --DBMS_OUTPUT.PUT_LINE(query_);', +' DBMS_OUTPUT.PUT(''.'');', +' EXCEPTION', +' WHEN OTHERS THEN', +' DBMS_OUTPUT.PUT(''!''); -- something went wrong', +' END;', +' END LOOP;', +'', +' -- show number of invalid objects', +' SELECT COUNT(*) INTO invalids', +' FROM user_objects o', +' WHERE o.status != ''VALID''', +' AND o.object_type != ''MATERIALIZED VIEW''', +' AND o.object_name != $$PLSQL_UNIT; -- not this procedure', +' --', +' DBMS_OUTPUT.PUT_LINE('' -> '' || invalids);', +' DBMS_OUTPUT.PUT_LINE('''');', +'', +' -- list invalid objects', +' IF invalids > 0 THEN', +' FOR c IN (', +' SELECT object_type, LISTAGG(object_name, '', '') WITHIN GROUP (ORDER BY object_name) AS objects', +' FROM (', +' SELECT DISTINCT o.object_type, o.object_name', +' FROM user_objects o', +' WHERE o.status != ''VALID''', +' AND o.object_type != ''MATERIALIZED VIEW''', +' ORDER BY o.object_type, o.object_name', +' )', +' ')) +); +null; +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20451776483336220) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +' GROUP BY object_type', +' ORDER BY object_type', +' ) LOOP', +' DBMS_OUTPUT.PUT_LINE('' '' || RPAD(c.object_type || '':'', 15, '' '') || '' '' || c.objects);', +' END LOOP;', +' DBMS_OUTPUT.PUT_LINE('''');', +' END IF;', +'END;', +'/', +'', +'')) +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20451802002336231) +,p_script_id=>wwv_flow_api.id(20451776483336220) +,p_object_owner=>'#OWNER#' +,p_object_type=>'PACKAGE' +,p_object_name=>'A770' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20452010246336231) +,p_script_id=>wwv_flow_api.id(20451776483336220) +,p_object_owner=>'#OWNER#' +,p_object_type=>'PACKAGE' +,p_object_name=>'APP' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20452213537336231) +,p_script_id=>wwv_flow_api.id(20451776483336220) +,p_object_owner=>'#OWNER#' +,p_object_type=>'PACKAGE' +,p_object_name=>'APP_ACTIONS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20452449161336231) +,p_script_id=>wwv_flow_api.id(20451776483336220) +,p_object_owner=>'#OWNER#' +,p_object_type=>'PROCEDURE' +,p_object_name=>'RECOMPILE' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180503','YYYYMMDDHH24MISS') +); +wwv_flow_api.component_end; +end; +/ diff --git a/apex/f770/application/deployment/install/install_install_sequences.sql b/apex/f770/application/deployment/install/install_install_sequences.sql new file mode 100644 index 0000000..8c279a9 --- /dev/null +++ b/apex/f770/application/deployment/install/install_install_sequences.sql @@ -0,0 +1,38 @@ +prompt --application/deployment/install/install_install_sequences +begin +-- Manifest +-- INSTALL: INSTALL-INSTALL_SEQUENCES +-- Manifest End +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.create_install_script( + p_id=>wwv_flow_api.id(20451203514326110) +,p_install_id=>wwv_flow_api.id(12958699824624058) +,p_name=>'INSTALL_SEQUENCES' +,p_sequence=>30 +,p_script_type=>'INSTALL' +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +' CREATE SEQUENCE "LOG_ID" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 21919 CACHE 100 NOORDER NOCYCLE NOKEEP GLOBAL ;', +'', +'')) +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20451386683326110) +,p_script_id=>wwv_flow_api.id(20451203514326110) +,p_object_owner=>'#OWNER#' +,p_object_type=>'SEQUENCE' +,p_object_name=>'LOG_ID' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180322','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180322','YYYYMMDDHH24MISS') +); +wwv_flow_api.component_end; +end; +/ diff --git a/apex/f770/application/deployment/install/install_install_tables.sql b/apex/f770/application/deployment/install/install_install_tables.sql new file mode 100644 index 0000000..966eb6d --- /dev/null +++ b/apex/f770/application/deployment/install/install_install_tables.sql @@ -0,0 +1,1405 @@ +prompt --application/deployment/install/install_install_tables +begin +-- Manifest +-- INSTALL: INSTALL-INSTALL_TABLES +-- Manifest End +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.create_install_script( + p_id=>wwv_flow_api.id(20440056481310319) +,p_install_id=>wwv_flow_api.id(12958699824624058) +,p_name=>'INSTALL_TABLES' +,p_sequence=>10 +,p_script_type=>'INSTALL' +,p_script_option=>'TABLE' +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'CREATE TABLE "APPS" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_APPS_APP_ID" NOT NULL ENABLE, ', +' "APP_NAME" VARCHAR2(32), ', +' "DESCRIPTION_" VARCHAR2(1000), ', +' "MESSAGE" VARCHAR2(256), ', +' "IS_ACTIVE" CHAR(1), ', +' "IS_VISIBLE" CHAR(1), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_APPS_IS_ACTIVE" CHECK (is_active = ''Y'' OR is_active IS NULL) ENABLE, ', +' CONSTRAINT "CH_APPS_IS_VISIBLE" CHECK (is_visible = ''Y'' OR is_visible IS NULL) ENABLE, ', +' CONSTRAINT "PK_APPS" PRIMARY KEY ("APP_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "ROLES" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_ROLES_APP_ID" NOT NULL ENABLE, ', +' "ROLE_ID" VARCHAR2(30) CONSTRAINT "NN_ROLES_ROLE_ID" NOT NULL ENABLE, ', +' "ROLE_NAME" VARCHAR2(64), ', +' "ROLE_GROUP" VARCHAR2(64), ', +' "DESCRIPTION_" VARCHAR2(1000), ', +' "IS_ACTIVE" CHAR(1), ', +' "ORDER#" NUMBER(4,0), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_ROLES_IS_ACTIVE" CHECK (is_active = ''Y'' OR is_active IS NULL) ENABLE, ', +' CONSTRAINT "PK_ROLES" PRIMARY KEY ("APP_ID", "ROLE_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "USERS" ', +' ( "USER_ID" VARCHAR2(30) CONSTRAINT "NN_USERS_USER_ID" NOT NULL ENABLE, ', +' "USER_LOGIN" VARCHAR2(128) CONSTRAINT "NN_USERS_LOGIN" NOT NULL ENABLE, ', +' "USER_NAME" VARCHAR2(64), ', +' "LANG_ID" VARCHAR2(5), ', +' "IS_ACTIVE" CHAR(1), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_USERS_IS_ACTIVE" CHECK (is_active = ''Y'' OR is_active IS NULL) ENABLE, ', +' CONSTRAINT "PK_USERS" PRIMARY KEY ("USER_ID")', +' USING INDEX ENABLE, ', +' CONSTRAINT "UQ_USERS_USER_LOGIN" UNIQUE ("USER_LOGIN")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "USER_ROLES" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_USER_ROLES_APP_ID" NOT NULL ENABLE, ', +' "USER_ID" VARCHAR2(30) CONSTRAINT "NN_USER_ROLES_USER_ID" NOT NULL ENABLE, ', +' "ROLE_ID" VARCHAR2(30) CONSTRAINT "NN_USER_ROLES_ROLE_ID" NOT NULL ENABLE, ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "PK_USER_ROLES" PRIMARY KEY ("APP_ID", "USER_ID", "ROLE_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "EVENTS" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_EVENTS_APP_ID" NOT NULL ENABLE, ', +' "EVENT_ID" VARCHAR2(30) CONSTRAINT "NN_EVENTS_EVENT_ID" NOT NULL ENABLE, ', +' "EVENT_NAME" VARCHAR2(64), ', +' "EVENT_GROUP" VARCHAR2(64), ', +' "DESCRIPTION_" VARCHAR2(1000), ', +' "IS_ACTIVE" CHAR(1), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_EVENTS_IS_ACTIVE" CHECK (is_active = ''Y'' OR is_active IS NULL) ENABLE, ', +' CONSTRAINT "PK_EVENTS" PRIMARY KEY ("APP_ID", "EVENT_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "LOGS_BLACKLIST" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_LOGS_BLACKLIST_APP_ID" NOT NULL ENABLE, ', +' "FLAG" CHAR(1), ', +' "USER_ID" VARCHAR2(240), ', +' "PAGE_ID" NUMBER(6,0), ', +' "MODULE_LIKE" VARCHAR2(30), ', +' "ACTION_LIKE" VARCHAR2(30), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "UQ_LOGS_BLACKLIST" UNIQUE ("APP_ID", "USER_ID", "PAGE_ID", "FLAG", "MODULE_LIKE", "ACTION_LIKE")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "NAVIGATION" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_NAVIGATION_APP_ID" NOT NULL ENABLE, ', +' "PAGE_ID" NUMBER(6,0) CONSTRAINT "NN_NAVIGATION_PAGE_ID" NOT NULL ENABLE, ', +' "PARENT_ID" NUMBER(6,0), ', +' "ORDER#" NUMBER(4,0), ', +' "IS_HIDDEN" CHAR(1), ', +' "IS_RESET" CHAR(1), ', +' "IS_SHARED" CHAR(1), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_NAVIGATION_IS_HIDDEN" CHECK (is_hidden = ''Y'' OR is_hidden IS NULL) ENABLE, ', +' CONSTRAINT "CH_NAVIGATION_IS_RESET" CHECK (is_reset = ''Y'' OR is_reset IS NULL) ENABLE, ', +' CONSTRAINT "PK_NAVIGATION" PRIMARY KEY ("APP_ID", "PAGE_ID")', +' USING INDEX ENABLE, ', +' CONSTRAINT "CH_NAVIGATION_IS_SHARED" CHECK (is_shared = ''Y'' OR is_shared IS NULL) ENABLE', +' ) ;', +'', +'CREATE TABLE "SESSIONS" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_SESSIONS_APP_ID" NOT NULL ENABLE, ', +' "SESSION_ID" NUMBER CONSTRAINT "NN_SESSIONS_SESSION_ID" NOT NULL ENABLE, ', +' "USER_ID" VARCHAR2(30) CONSTRAINT "NN_SESSIONS_USER_ID" NOT NULL ENABLE, ', +' "CREATED_AT" DATE CONSTRAINT "NN_SESSIONS_CREATED_AT" NOT NULL ENABLE, ', +' "UPDATED_AT" DATE CONSTRAINT "NN_SESSIONS_UPDATED_AT" NOT NULL ENABLE, ', +' CONSTRAINT "PK_SESSIONS" PRIMARY KEY ("APP_ID", "SESSION_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "SETTINGS" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_SETTINGS_APP_ID" NOT NULL ENABLE, ', +' "SETTING_NAME" VARCHAR2(30) CONSTRAINT "NN_SETTINGS_ID" NOT NULL ENABLE, ', +' "SETTING_VALUE" VARCHAR2(256), ', +' "SETTING_CONTEXT" VARCHAR2(64), ', +' "SETTING_GROUP" VARCHAR2(64), ', +' "IS_NUMERIC" CHAR(1), ', +' "IS_DATE" CHAR(1), ', +' "DESCRIPTION_" VARCHAR2(1000), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "CH_SETTINGS_IS_ACTIVE" CHECK ((is_numeric = ''Y'' AND is_date IS NULL) OR is_numeric IS NULL) ENABLE, ', +' CONSTRAINT "CH_SETTINGS_IS_DATE" CHECK ((is_date = ''Y'' AND is_numeric IS NULL) OR is_date IS NULL) ENABLE, ', +' CONSTRAINT "UQ_SETTINGS" UNIQUE ("APP_ID", "SETTING_NAME", "SETTING_CONTEXT")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "SETTING_CONTEXTS" ', +' ( "APP_ID" NUMBER(4,0) CONSTRAINT "NN_SETTING_CONTEXTS_APP_ID" NOT NULL ENABLE, ', +' "CONTEXT_ID" VARCHAR2(64) CONSTRAINT "NN_SETTING_CONTEXTS_NAME" NOT NULL ENABLE, ', +' "CONTEXT_NAME" VARCHAR2(64), ', +' "DESCRIPTION_" VARCHAR2(1000), ', +' "ORDER#" NUMBER(4,0), ', +' "UPDATED_BY" VARCHAR2(30), ', +' "UPDATED_AT" DATE, ', +' CONSTRAINT "UQ_SETTING_CONTEXTS" UNIQUE ("APP_ID", "CONTEXT_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "LOG_EVENTS" ', +' ( "LOG_ID" NUMBER(*,0) CONSTRAINT "NN_LOG_EVENTS_LOG_ID" NOT NULL ENABLE, ', +' "LOG_PARENT" NUMBER(*,0), ', +' "APP_ID" NUMBER(4,0) CONSTRAINT "NN_LOG_EVENTS_APP_ID" NOT NULL ENABLE, ', +' "PAGE_ID" NUMBER(6,0) CONSTRAINT "NN_LOG_EVENTS_PAGE_ID" NOT NULL ENABLE, ', +' "USER_ID" VARCHAR2(30) CONSTRAINT "NN_LOG_EVENTS_USER_ID" NOT NULL ENABLE, ', +' "SESSION_ID" NUMBER CONSTRAINT "NN_LOG_EVENTS_SESSION_ID" NOT NULL ENABLE, ', +' "EVENT_ID" VARCHAR2(30) CONSTRAINT "NN_LOG_EVENTS_EVENT_ID" NOT NULL ENABLE, ', +' "EVENT_VALUE" NUMBER, ', +' "CREATED_AT" DATE CONSTRAINT "NN_LOG_EVENTS_CREATED_AT" NOT NULL ENABLE, ', +' CONSTRAINT "PK_LOG_EVENTS" PRIMARY KEY ("LOG_ID")', +' USING INDEX ENABLE', +' ) ;', +'', +'CREATE TABLE "LOGS" ', +' ( "LOG_ID" NUMBER(*,0) CONSTRAINT "NN_LOGS_LOG_ID" NOT NULL ENABLE, ', +' "LOG_PARENT" NUMBER(*,0), ', +' "APP_ID" NUMBER(4,0) CONSTRAINT "NN_LOGS_APP_ID" NOT NULL ENABLE, ', +' "PAGE_ID" NUMBER(6,0), ', +' "USER_ID" VARCHAR2(30), ', +' "FLAG" CHAR(1) CONSTRAINT "NN_LOGS_FLAG" NOT NULL ENABLE, ', +' "ACTION_NAME" VARCHAR2(32), ', +' "MODULE_NAME" VARCHAR2(48), ', +' "MODULE_LINE" NUMBER(8,0), ', +' "MODULE_TIMER" VARCHAR2(12), ', +' "ARGUMENTS" VARCHAR2(2000), ', +' "PAYLOAD" VARCHAR2(4000), ', +' "SESSION_ID" NUMBER, ', +' "CREATED_AT" TIMESTAMP (6) CONSTRAINT "NN_LOGS_CREATED_AT" NOT NULL ENABLE, ', +' CONSTRAINT "PK_LOGS" PRIMARY KEY ("LOG_ID")', +' USING INDEX ENABLE', +' ) ', +' PARTITION BY RANGE ("CREATED_AT") INTERVAL (NUMTODSINTERVAL(1, ''DAY'')) ', +' (PARTITION "SYS_P1687" VALUES LESS THAN (TIMESTAMP'' 2022-01-17 00:00:00'') ) ;', +'', +'CREATE TABLE "USER_SOURCE_VIEWS" ', +' ( "NAME" VARCHAR2(30) CONSTRAINT "NN_USER_SOURCE_VIEWS_NAME" NOT NULL ENABLE, ', +' "LINE" NUMBER(8,0) CONSTRAINT "NN_USER_SOURCE_VIEWS_LINE" NOT NULL ENABLE, ', +' "TEXT" VARCHAR2(4000), ', +' CONSTRAINT "PK_USER_SOURCE_VIEWS" PRIMARY KEY ("NAME", "LINE")', +' USING INDEX ENABLE', +' ) ;', +'', +'ALTER TABLE "ROLES" ADD CONSTRAINT "FK_ROLES_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "USER_ROLES" ADD CONSTRAINT "FK_USERS_ROLES_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "USER_ROLES" ADD CONSTRAINT "FK_USERS_ROLES_USER_ID" FOREIGN KEY ("USER_ID")', +' REFERENCES "USERS" ("USER_ID") DISABLE;', +'', +'ALTER TABLE "USER_ROLES" ADD CONSTRAINT "FK_USERS_ROLES_ROLE_ID" FOREIGN KEY ("APP_ID", "ROLE_ID")', +' REFERENCES "ROLES" ("APP_ID", "ROLE_ID") DEFERRABLE INITIALLY DEFERRED ENABLE;', +'', +'ALTER TABLE "EVENTS" ADD CONSTRAINT "FK_EVENTS_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "LOG_EVENTS" ADD CONSTRAINT "FK_LOG_EVENTS_EVENT_ID" FOREIGN KEY ("APP_ID", "EVENT_ID")', +' REFERENCES "EVENTS" ("APP_ID", "EVENT_ID") ENABLE;', +'', +'ALTER TABLE "LOG_EVENTS" ADD CONSTRAINT "FK_LOG_EVENTS_USERS" FOREIGN KEY ("USER_ID")', +' REFERENCES "USERS" ("USER_ID") DISABLE;', +'', +'ALTER TABLE "LOGS_BLACKLIST" ADD CONSTRAINT "FK_LOGS_BLACKLIST_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "LOGS_BLACKLIST" ADD CONSTRAINT "FK_LOGS_BLACKLIST_USER_ID" FOREIGN KEY ("USER_ID")', +' REFERENCES "USERS" ("USER_ID") ENABLE;', +'', +'ALTER TABLE "NAVIGATION" ADD CONSTRAINT "FK_NAVIGATION_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "NAVIGATION" ADD CONSTRAINT "FK_NAVIGATION_PARENT" FOREIGN KEY ("APP_ID", "PARENT_ID")', +' REFERENCES "NAVIGATION" ("APP_ID", "PAGE_ID") ENABLE;', +'', +'ALTER TABLE "SESSIONS" ADD CONSTRAINT "FK_SESSIONS_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "SESSIONS" ADD CONSTRAINT "FK_SESSIONS_USERS" FOREIGN KEY ("USER_ID")', +' REFERENCES "USERS" ("USER_ID") ENABLE;', +'', +'ALTER TABLE "SETTINGS" ADD CONSTRAINT "FK_SETTINGS_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'ALTER TABLE "SETTING_CONTEXTS" ADD CONSTRAINT "FK_SETTING_CONTEXTS_APP_ID" FOREIGN KEY ("APP_ID")', +' REFERENCES "APPS" ("APP_ID") ENABLE;', +'', +'CREATE INDEX "FK_LOGS_BLACKLIST_USER_ID" ON "LOGS_BLACKLIST" ("USER_ID") ', +' ;', +'', +'CREATE INDEX "FK_NAVIGATION_PARENT" ON "NAVIGATION" ("APP_ID", "PARENT_ID") ', +' ;', +'', +'CREATE INDEX "FK_SESSIONS_USERS" ON "SESSIONS" ("USER_ID") ', +' ;', +'', +'CREATE INDEX "FK_USERS_ROLES_ROLE_ID" ON "USER_ROLES" ("APP_ID", "ROLE_ID") ', +' ;', +'', +'CREATE INDEX "FK_USERS_ROLES_USER_ID" ON "USER_ROLES" ("USER_ID") ', +' ;', +'', +'CREATE OR REPLACE TRIGGER "NAVIGATION__" ', +'FOR UPDATE OR INSERT OR DELETE ON navigation', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''NAVIGATION'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by navigation.updated_by%TYPE;', +' curr_updated_at navigation.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "NAVIGATION__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "APPS__" ', +'FOR UPDATE OR INSERT OR DELETE ON apps', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''APPS'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by apps.updated_by%TYPE;', +' curr_updated_at apps.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' deleted_app_id apps.app_id%TYPE;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +'', +' -- update global message, create APEX session first', +' /*', +' BEGIN', +' IF :NEW.app_id != app.get_app_id() THEN', +' app_actions.update_global_message (', +' in_message => :NEW.message,', +' in_app_id => :NEW.app_id', +' );', +' END IF;', +' EXCEPTION', +' WHEN OTHERS THEN -- ORA-20987: APEX - An API call has been prohibited.', +' :NEW.message := :OLD.message;', +' END;', +' */', +' ELSE', +' DELETE FROM sessions t', +' WHERE t.app_id = :OLD.app_id;', +' --', +' DELETE FROM navigation t', +' WHERE t.app_id = :OLD.app_id;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' --', +' IF app.is_developer() THEN', +' deleted_app_id := :OLD.app_id;', +' END IF;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' --', +' IF rows_deleted > 0 AND deleted_app_id IS NOT NULL THEN', +' DELETE FROM logs t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM logs_blacklist t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM log_events t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM events t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM user_roles t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM roles t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM setting_contexts t', +' WHERE t.app_id = deleted_app_id;', +' --', +' DELETE FROM settings t', +' WHERE t.app_id = deleted_app_id;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "APPS__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "SETTING_CONTEXTS__" ', +'FOR UPDATE OR INSERT OR DELETE ON setting_contexts', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''SETTING_CONTEXTS'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by setting_contexts.updated_by%TYPE;', +' curr_updated_at setting_contexts.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' ELSE', +' -- delete related rows', +' DELETE FROM settings s', +' WHERE s.app_id = :OLD.app_id', +' AND s.setting_context = :OLD.context_id;', +' END IF;', +' --', +' curr_event_id := app.log_event(''SETTING_CONTEXTS_CHANGED'');', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "SETTING_CONTEXTS__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "SETTINGS__" ', +'FOR UPDATE OR INSERT OR DELETE ON settings', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''SETTINGS'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by settings.updated_by%TYPE;', +' curr_updated_at settings.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +'', +' -- check name', +' IF NOT REGEXP_LIKE(:NEW.setting_name, ''^[A-Z0-9_]{1,'' || TO_CHAR(30 - NVL(LENGTH(app_actions.settings_prefix), 0)) || ''}$'') THEN', +' app.raise_error(''WRONG_NAME'', :NEW.setting_name);', +' END IF;', +'', +' -- check date value', +' IF :NEW.is_date = ''Y'' THEN', +' BEGIN', +' :NEW.setting_value := app.get_date(app.get_date(:NEW.setting_value));', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''WRONG_DATE'');', +' END;', +' END IF;', +'', +' -- check numeric value', +' IF :NEW.is_numeric = ''Y'' THEN', +' BEGIN', +' :NEW.setting_value := TO_NUMBER(REPLACE(:NEW.setting_value, '','', ''.''));', +' EXCEPTION', +' WHEN OTHERS THEN', +' app.raise_error(''WRONG_NUMBER'');', +' END;', +' END IF;', +' END IF;', +' --', +' curr_event_id := app.log_event(''SETTINGS_CHANGED'');', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "SETTINGS__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "LOGS_BLACKLIST__" ', +'FOR UPDATE OR INSERT OR DELETE ON logs_blacklist', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''LOGS_BLACKLIST'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by logs_blacklist.updated_by%TYPE;', +' curr_updated_at logs_blacklist.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "LOGS_BLACKLIST__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "ROLES__" ', +'FOR UPDATE OR INSERT OR DELETE ON roles', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''ROLES'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by roles.updated_by%TYPE;', +' curr_updated_at roles.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' --', +' IF UPDATING AND :NEW.role_id != :OLD.role_id THEN', +' UPDATE user_roles u', +' SET u.role_id = :NEW.role_id', +' WHERE u.app_id = :OLD.app_id', +' AND u.role_id = :OLD.role_id;', +' --', +' curr_event_id := app.log_event(''ROLE_ID_CHANGED'');', +' END IF;', +' ELSE', +' DELETE FROM user_roles u', +' WHERE u.app_id = :OLD.app_id', +' AND u.role_id = :OLD.role_id;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "ROLES__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "USER_ROLES__" ', +'FOR UPDATE OR INSERT OR DELETE ON user_roles', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''USER_ROLES'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by user_roles.updated_by%TYPE;', +' curr_updated_at user_roles.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIG')) +); +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20440056481310319) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'GER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "USER_ROLES__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "EVENTS__" ', +'FOR UPDATE OR INSERT OR DELETE ON events', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''EVENTS'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_updated_by events.updated_by%TYPE;', +' curr_updated_at events.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' --', +' IF UPDATING AND :NEW.event_id != :OLD.event_id THEN', +' UPDATE log_events e', +' SET e.event_id = :NEW.event_id', +' WHERE e.app_id = :OLD.app_id', +' AND e.event_id = :OLD.event_id;', +' END IF;', +' ELSE', +' DELETE FROM log_events e', +' WHERE e.app_id = :OLD.app_id', +' AND e.event_id = :OLD.event_id;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "EVENTS__" ENABLE;', +'', +'CREATE OR REPLACE TRIGGER "USERS__" ', +'FOR UPDATE OR INSERT OR DELETE ON users', +'COMPOUND TRIGGER', +'', +' in_table_name CONSTANT user_tables.table_name%TYPE := ''USERS'';', +' --', +' curr_log_id logs.log_id%TYPE;', +' curr_event_id log_events.log_id%TYPE;', +' curr_updated_by users.updated_by%TYPE;', +' curr_updated_at users.updated_at%TYPE;', +' --', +' rows_inserted PLS_INTEGER := 0;', +' rows_updated PLS_INTEGER := 0;', +' rows_deleted PLS_INTEGER := 0;', +' --', +' last_rowid ROWID;', +'', +'', +'', +' BEFORE STATEMENT IS', +' BEGIN', +' curr_log_id := app.log_trigger(in_table_name);', +' curr_updated_by := app.get_user_id();', +' curr_updated_at := SYSDATE;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE STATEMENT;', +'', +'', +'', +' BEFORE EACH ROW IS', +' BEGIN', +' IF NOT DELETING THEN', +' :NEW.updated_by := curr_updated_by;', +' :NEW.updated_at := curr_updated_at;', +' --', +' IF UPDATING AND :NEW.user_id != :OLD.user_id THEN', +' UPDATE user_roles r', +' SET r.user_id = :NEW.user_id', +' WHERE r.user_id = :OLD.user_id;', +' --', +' UPDATE sessions s', +' SET s.user_id = :NEW.user_id', +' WHERE s.user_id = :OLD.user_id;', +' --', +' UPDATE log_events l', +' SET l.user_id = :NEW.user_id', +' WHERE l.user_id = :OLD.user_id;', +' --', +' curr_event_id := app.log_event(''USER_ID_CHANGED'');', +' END IF;', +' ELSE', +' DELETE FROM user_roles t', +' WHERE t.user_id = :OLD.user_id;', +' --', +' DELETE FROM sessions t', +' WHERE t.user_id = :OLD.user_id;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END BEFORE EACH ROW;', +'', +'', +'', +' AFTER EACH ROW IS', +' new_json VARCHAR2(32767);', +' old_json VARCHAR2(32767);', +' BEGIN', +' IF INSERTING THEN', +' rows_inserted := rows_inserted + 1;', +' last_rowid := :NEW.ROWID;', +' ELSIF UPDATING THEN', +' rows_updated := rows_updated + 1;', +' last_rowid := :OLD.ROWID;', +' ELSIF DELETING THEN', +' rows_deleted := rows_deleted + 1;', +' last_rowid := :OLD.ROWID;', +' END IF;', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER EACH ROW;', +'', +'', +'', +' AFTER STATEMENT IS', +' BEGIN', +' app.log_success (', +' in_log_id => curr_log_id,', +' in_rows_inserted => rows_inserted,', +' in_rows_updated => rows_updated,', +' in_rows_deleted => rows_deleted,', +' in_last_rowid => last_rowid', +' );', +' EXCEPTION', +' WHEN app.app_exception THEN', +' RAISE;', +' WHEN OTHERS THEN', +' app.raise_error(''TRIGGER_FAILED'', in_table_name);', +' END AFTER STATEMENT;', +'', +'END;', +'', +'/', +'', +'', +'ALTER TRIGGER "USERS__" ENABLE;', +'', +'')) +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20440182950310344) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'APPS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20440331613310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'EVENTS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20440510982310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'LOGS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20440778556310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'LOGS_BLACKLIST' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20440985003310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'LOG_EVENTS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20441115334310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'NAVIGATION' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20441324995310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'ROLES' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20441557055310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'SESSIONS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20441708772310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'SETTINGS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20441991457310348) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'SETTING_CONTEXTS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20442141014310349) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'USERS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20442365413310349) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'USER_ROLES' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.create_install_object( + p_id=>wwv_flow_api.id(20442559004310349) +,p_script_id=>wwv_flow_api.id(20440056481310319) +,p_object_owner=>'#OWNER#' +,p_object_type=>'TABLE' +,p_object_name=>'USER_SOURCE_VIEWS' +,p_last_updated_by=>'DEV' +,p_last_updated_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +,p_created_by=>'DEV' +,p_created_on=>to_date('20220123180044','YYYYMMDDHH24MISS') +); +wwv_flow_api.component_end; +end; +/ diff --git a/apex/f770/application/deployment/install/install_install_views.sql b/apex/f770/application/deployment/install/install_install_views.sql new file mode 100644 index 0000000..3a069a9 --- /dev/null +++ b/apex/f770/application/deployment/install/install_install_views.sql @@ -0,0 +1,3114 @@ +prompt --application/deployment/install/install_install_views +begin +-- Manifest +-- INSTALL: INSTALL-INSTALL_VIEWS +-- Manifest End +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.create_install_script( + p_id=>wwv_flow_api.id(20442967958321458) +,p_install_id=>wwv_flow_api.id(12958699824624058) +,p_name=>'INSTALL_VIEWS' +,p_sequence=>20 +,p_script_type=>'INSTALL' +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'CREATE OR REPLACE FORCE VIEW "DASHBOARD_OVERVIEW" ("WEEK", "TODAY", "COUNT_REQUESTS", "COUNT_ACTIONS", "COUNT_MODULES", "COUNT_DEBUGS", "COUNT_RESULTS", "COUNT_WARNINGS", "COUNT_ERRORS", "COUNT_LONGOPS", "COUNT_TRIGGERS", "COUNT_SESSIONS", "COUNT_USE' +||'RS", "COUNT_EVENTS", "COUNT_SUCCEEDED", "COUNT_FAILED", "ACTION") AS ', +' WITH x AS (', +' SELECT', +' app.get_app_id() AS app_id', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +'),', +'s AS (', +' SELECT', +' TRUNC(s.created_at) AS today,', +' NULLIF(COUNT(s.session_id), 0) AS count_sessions,', +' NULLIF(COUNT(DISTINCT s.user_id), 0) AS count_users', +' FROM sessions s', +' JOIN x', +' ON x.app_id = s.app_id', +' GROUP BY TRUNC(s.created_at)', +'),', +'e AS (', +' SELECT', +' TRUNC(e.created_at) AS today,', +' NULLIF(COUNT(e.event_id), 0) AS count_events', +' FROM log_events e', +' JOIN x', +' ON x.app_id = e.app_id', +' GROUP BY TRUNC(e.created_at)', +'),', +'l AS (', +' SELECT', +' TRUNC(l.created_at) AS today,', +' NULLIF(SUM(CASE WHEN l.flag = ''P'' THEN 1 ELSE 0 END), 0) AS count_requests, -- must match APP specification', +' NULLIF(SUM(CASE WHEN l.flag = ''A'' THEN 1 ELSE 0 END), 0) AS count_actions,', +' NULLIF(SUM(CASE WHEN l.flag = ''M'' THEN 1 ELSE 0 END), 0) AS count_modules,', +' NULLIF(SUM(CASE WHEN l.flag = ''D'' THEN 1 ELSE 0 END), 0) AS count_debugs,', +' NULLIF(SUM(CASE WHEN l.flag = ''R'' THEN 1 ELSE 0 END), 0) AS count_results,', +' NULLIF(SUM(CASE WHEN l.flag = ''W'' THEN 1 ELSE 0 END), 0) AS count_warnings,', +' NULLIF(SUM(CASE WHEN l.flag = ''E'' THEN 1 ELSE 0 END), 0) AS count_errors,', +' NULLIF(SUM(CASE WHEN l.flag = ''L'' THEN 1 ELSE 0 END), 0) AS count_longops,', +' NULLIF(SUM(CASE WHEN l.flag = ''G'' THEN 1 ELSE 0 END), 0) AS count_triggers', +' FROM logs l', +' JOIN x', +' ON x.app_id = l.app_id', +' GROUP BY TRUNC(l.created_at)', +'),', +'j AS (', +' SELECT', +' TRUNC(d.actual_start_date) AS today,', +' COUNT(d.log_id) AS count_succeeded,', +' SUM(CASE WHEN d.status = ''SUCCEEDED'' THEN 0 ELSE 1 END) AS count_failed', +' FROM user_scheduler_job_run_details d', +' WHERE d.actual_start_date >= TRUNC(SYSDATE) - 7', +' GROUP BY TRUNC(d.actual_start_date)', +')', +'--', +'SELECT', +' LPAD('' '', TO_NUMBER(TO_CHAR(l.today, ''IYIW'') - 2000)) || SUBSTR(TO_CHAR(l.today, ''YYYY''), 1, 2) || TO_CHAR(l.today, ''IY-IW'') AS week,', +' --', +' TO_CHAR(l.today, ''YYYY-MM-DD'') AS today,', +' --', +' l.count_requests,', +' l.count_actions,', +' l.count_modules,', +' l.count_debugs,', +' l.count_results,', +' l.count_warnings,', +' l.count_errors,', +' l.count_longops,', +' l.count_triggers,', +' --', +' s.count_sessions,', +' s.count_users,', +' e.count_events,', +' --', +' NULLIF(j.count_succeeded - j.count_failed, 0) AS count_succeeded,', +' NULLIF(j.count_failed, 0) AS count_failed,', +' --', +' app.get_icon(''fa-trash-o'', ''Delete related logs'') AS action', +'FROM l', +'LEFT JOIN s ON s.today = l.today', +'LEFT JOIN e ON e.today = l.today', +'LEFT JOIN j ON j.today = l.today;', +'', +'CREATE OR REPLACE FORCE VIEW "EVENTS_CHART" ("BUCKET_ID", "CHART_LABEL", "COUNT_EVENTS") AS ', +' WITH x AS (', +' SELECT', +' app.get_app_id() AS app_id,', +' app.get_item(''$EVENT_ID'') AS event_id,', +' app.get_item(''$USER_ID'') AS user_id,', +' TRUNC(app.get_date_item(''G_TODAY'')) AS today', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +'),', +'z AS (', +' SELECT', +' LEVEL AS bucket_id,', +' TRUNC(SYSDATE) + NUMTODSINTERVAL((LEVEL - 1) * 10, ''MINUTE'') AS start_at,', +' TRUNC(SYSDATE) + NUMTODSINTERVAL( LEVEL * 10, ''MINUTE'') AS end_at', +' FROM DUAL', +' CONNECT BY LEVEL <= (1440 / 10)', +')', +'SELECT', +' z.bucket_id,', +' TO_CHAR(z.start_at, ''HH24:MI'') AS chart_label,', +' NULLIF(COUNT(e.event_id), 0) AS count_events', +'FROM z', +'CROSS JOIN x', +'LEFT JOIN log_events e', +' ON e.app_id = x.app_id', +' AND e.created_at >= x.today', +' AND e.created_at < x.today + 1', +' AND e.event_id = NVL(x.event_id, e.event_id)', +' AND e.user_id = NVL(x.user_id, e.user_id)', +' AND z.bucket_id = app.get_time_bucket(e.created_at, 10)', +'GROUP BY z.bucket_id, TO_CHAR(z.start_at, ''HH24:MI'');', +'', +'CREATE OR REPLACE FORCE VIEW "GRANTS_OBJECTS" ("PRIVILEGE", "ROLE", "USER_ID", "OWNER", "OBJECT_NAME", "OBJECT_TYPE", "IS_INHERITED", "IS_GRANTABLE", "GRANTOR") AS ', +' SELECT', +' r.privilege,', +' r.role,', +' NULL AS user_id,', +' r.owner,', +' r.table_name AS object_name,', +' NULL AS object_type,', +' --', +' CASE WHEN r.inherited = ''YES'' THEN ''Y'' END AS is_inherited,', +' CASE WHEN r.grantable = ''YES'' THEN ''Y'' END AS is_grantable,', +' --', +' NULL AS grantor', +'FROM role_tab_privs r', +'UNION ALL', +'--', +'SELECT', +' u.privilege,', +' NULL AS role,', +' u.grantee AS user_id,', +' u.owner,', +' u.table_name AS object_name,', +' u.type AS object_type,', +' --', +' CASE WHEN u.inherited = ''YES'' THEN ''Y'' END AS is_inherited,', +' CASE WHEN u.grantable = ''YES'' THEN ''Y'' END AS is_grantable,', +' --', +' u.grantor', +'FROM user_tab_privs u;', +'', +'CREATE OR REPLACE FORCE VIEW "GRANTS_PRIVILEGES" ("PRIVILEGE", "ROLE", "USER_ID", "IS_ACTIVE", "IS_INHERITED", "IS_ADMIN_OPTION") AS ', +' SELECT', +' r.privilege,', +' r.role,', +' NULL AS user_id,', +' --', +' CASE WHEN s.privilege IS NOT NULL THEN ''Y'' END AS is_active,', +' CASE WHEN r.inherited = ''YES'' THEN ''Y'' END AS is_inherited,', +' CASE WHEN r.admin_option = ''YES'' THEN ''Y'' END AS is_admin_option', +'FROM role_sys_privs r', +'LEFT JOIN session_privs s', +' ON s.privilege = r.privilege', +'UNION ALL', +'--', +'SELECT', +' u.privilege,', +' NULL AS role,', +' u.username AS user_id,', +' --', +' CASE WHEN s.privilege IS NOT NULL THEN ''Y'' END AS is_active,', +' CASE WHEN u.inherited = ''YES'' THEN ''Y'' END AS is_inherited,', +' CASE WHEN u.admin_option = ''YES'' THEN ''Y'' END AS is_admin_option', +'FROM user_sys_privs u', +'LEFT JOIN session_privs s', +' ON s.privilege = u.privilege;', +'', +'CREATE OR REPLACE FORCE VIEW "LOGS_OVERVIEW" ("LOG_ID", "LOG_PARENT", "APP_ID", "PAGE_ID", "USER_ID", "FLAG", "ACTION_NAME", "MODULE_NAME", "MODULE_LINE", "MODULE_TIMER", "ARGUMENTS", "PAYLOAD", "SESSION_ID", "CREATED_AT") AS ', +' WITH x AS (', +' SELECT', +' app.get_app_id() AS app_id,', +' app.get_item(''$RECENT_LOG_ID'') AS recent_log_id,', +' app.get_item(''$FLAG'') AS flag,', +' app.get_item(''$PAGE_ID'') AS page_id,', +' app.get_item(''$USER_ID'') AS user_id,', +' app.get_item(''$SESSION_ID'') AS session_id,', +' app.get_item(''$MODULE_NAME'') AS module_name,', +' app.get_item(''$ACTION_NAME'') AS action_name,', +' app.get_date_item(''G_TODAY'') AS today', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +')', +'SELECT', +' l.log_id,', +' l.log_parent,', +' l.app_id,', +' l.page_id,', +' l.user_id,', +' l.flag,', +' l.action_name,', +' l.module_name,', +' l.module_line,', +' l.module_timer,', +' l.arguments,', +' l.payload,', +' l.session_id,', +' l.created_at', +'FROM logs l', +'JOIN x', +' ON l.created_at >= x.today', +' AND l.created_at < x.today + 1', +' AND l.app_id = x.app_id', +' AND l.log_id > NVL(x.recent_log_id, 0)', +' AND l.flag = NVL(x.flag, l.flag)', +' AND l.page_id = NVL(x.page_id, l.page_id)', +' AND l.user_id = NVL(x.user_id, l.user_id)', +' AND l.session_id = NVL(x.session_id, l.session_id)', +' AND (l.module_name = NVL(x.module_name, l.module_name) OR (l.module_name IS NULL AND x.module_name IS NULL))', +' AND (l.action_name = NVL(x.action_name, l.action_name) OR (l.action_name IS NULL AND x.action_name IS NULL));', +'', +'CREATE OR REPLACE FORCE VIEW "LOGS_TREE" ("LOG_ID", "LOG_PARENT", "APP_ID", "PAGE_ID", "USER_ID", "FLAG", "ACTION_NAME", "MODULE_NAME", "MODULE_LINE", "MODULE_TIMER", "ARGUMENTS", "PAYLOAD", "SESSION_ID", "CREATED_AT") AS ', +' SELECT', +' l.log_id,', +' l.log_parent,', +' l.app_id,', +' l.page_id,', +' l.user_id,', +' l.flag,', +' l.action_name,', +' LPAD('' '', (LEVEL - 1) * 6) || l.module_name AS module_name,', +' l.module_line,', +' l.module_timer,', +' l.arguments,', +' l.payload,', +' l.session_id,', +' l.created_at', +'FROM logs l', +'CONNECT BY l.log_parent = PRIOR l.log_id', +'START WITH l.log_id = app.get_log_tree_id()', +' AND l.app_id = app.get_app_id()', +'ORDER SIBLINGS BY l.log_id;', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_BADGES" ("PAGE_ID", "PAGE_ALIAS", "BADGE") AS ', +' WITH x AS (', +' SELECT', +' app.get_app_id() AS app_id,', +' app.is_developer_y() AS is_developer', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +')', +'SELECT -- today errors on dashboard', +' 900 AS page_id,', +' '' '' AS page_alias,', +' TO_CHAR(NULLIF(COUNT(*), 0)) AS badge', +'FROM logs l', +'JOIN x', +' ON x.is_developer = ''Y''', +'WHERE l.created_at >= TRUNC(SYSDATE)', +' AND l.flag = ''E''', +' AND l.app_id = x.app_id', +'--', +'UNION ALL', +'SELECT -- today users', +' 915 AS page_id,', +' '' '' AS page_alias,', +' --', +' TO_CHAR(NULLIF(COUNT(DISTINCT s.user_id), 0)) AS badge', +'FROM sessions s', +'JOIN x', +' ON x.is_developer = ''Y''', +'WHERE s.created_at >= TRUNC(SYSDATE)', +' AND s.app_id = x.app_id', +'--', +'UNION ALL', +'SELECT -- pages to add/remove', +' 910 AS page_id,', +' '' '' AS page_alias,', +' --', +' TO_CHAR(NULLIF(COUNT(*), 0)) AS badge', +'FROM nav_overview n', +'JOIN x', +' ON x.is_developer = ''Y''', +'WHERE n.app_id = x.app_id', +' AND n.action IS NOT NULL', +'--', +'UNION ALL', +'SELECT -- running jobs', +' 905 AS page_id,', +' '' '' AS page_alias,', +' --', +' TO_CHAR(NULLIF(COUNT(*), 0)) AS badge', +'FROM user_scheduler_running_jobs j', +'--', +'UNION ALL', +'SELECT -- invalid objects', +' 950 AS page_id,', +' '' '' AS page_alias,', +' --', +' TO_CHAR(NULLIF(COUNT(*), 0)) AS badge', +'FROM user_objects o', +'WHERE o.status != ''VALID'';', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_OVERVIEW" ("APP_ID", "PAGE_ID", "PARENT_ID", "ORDER#", "PAGE_GROUP", "PAGE_ALIAS", "PAGE_NAME", "PAGE_TITLE", "CSS_CLASS", "PAGE_TEMPLATE", "IS_MODAL", "IS_HIDDEN", "IS_RESET", "IS_SHARED", "AUTH_SCHEME", "PAGE_URL",' +||' "ALLOW_CHANGES", "SORT_ORDER", "ACTION", "ACTION_URL") AS ', +' WITH x AS (', +' SELECT', +' app.get_page_id() AS page_id,', +' app.get_app_id() AS app_id,', +' app.get_core_app_id() AS core_app_id', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +'),', +'t AS (', +' SELECT', +' ROWNUM AS r#, -- to keep hierarchy sorted', +' t.*', +' FROM (', +' SELECT', +' n.app_id,', +' n.page_id,', +' n.order#,', +' --', +' REPLACE(p.page_name, ''&'' || ''APP_NAME.'', a.application_name) AS page_name,', +' REPLACE(p.page_title, ''&'' || ''APP_NAME.'', a.application_name) AS page_title,', +' --', +' p.page_alias,', +' p.page_group,', +' p.authorization_scheme,', +' p.page_css_classes,', +' p.page_mode,', +' p.page_template,', +' --', +' LEVEL - 1 AS depth,', +' CONNECT_BY_ROOT NVL(n.order#, n.page_id) AS page_root', +' FROM navigation n', +' JOIN apps a', +' ON a.app_id = n.app_id', +' AND a.is_active = ''Y''', +' CROSS JOIN x', +' LEFT JOIN apex_application_pages p', +' ON p.application_id = n.app_id', +' AND p.page_id = n.page_id', +' LEFT JOIN apex_applications a', +' ON a.application_id = p.application_id', +' CONNECT BY n.parent_id = PRIOR n.page_id', +' AND n.app_id = PRIOR n.app_id', +' START WITH n.parent_id IS NULL', +' ORDER SIBLINGS BY n.app_id, n.order#, n.page_id', +' ) t', +')', +'SELECT', +' n.app_id,', +' n.page_id,', +' n.parent_id,', +' n.order#,', +' --', +' t.page_root || '' '' || COALESCE (', +' t.page_group,', +' (', +' SELECT t.page_group', +' FROM t', +' WHERE t.app_id = n.app_id', +' AND t.page_id = n.parent_id', +' )', +' ) AS page_group,', +' --', +' t.page_alias,', +' --', +' CASE WHEN r.page_id IS NULL', +' THEN REPLACE(LTRIM(RPAD(''-'', t.depth * 4), ''-''), '' '', ''&'' || ''nbsp; '') ||', +' app.get_page_name (', +' in_app_id => n.app_id,', +' in_page_id => n.page_id,', +' in_name => t.page_name', +' )', +' END AS page_name,', +' --', +' t.page_title,', +' t.page_css_classes AS css_class,', +' t.page_template,', +' --', +' CASE WHEN t.page_mode = ''Normal'' THEN NULL ELSE ''Y'' END AS is_modal,', +' n.is_hidden,', +' n.is_reset,', +' n.is_shared,', +' --', +' CASE', +' WHEN t.authorization_scheme LIKE ''%MUST_NOT_BE_PUBLIC_USER%''', +' THEN app.get_icon(''fa-check-square'', ''MUST_NOT_BE_PUBLIC_USER'')', +' WHEN t.authorization_scheme IS NULL AND n.page_id NOT IN (0, 9999)', +' THEN app.get_icon(''fa-warning'', ''Auth scheme is missing'')', +' ELSE '''' || t.authorization_scheme || ''''', +' END AS auth_scheme,', +' --', +' CASE WHEN n.page_id > 0 AND r.page_id IS NULL', +' THEN app.get_page_link (', +' in_page_id => n.page_id,', +' in_app_id => n.app_id,', +' in_session_id => CASE WHEN n.page_id = 9999 THEN 0 END', +' )', +' END AS page_url,', +' --', +' ''UD'' AS allow_changes, -- U = update, D = delete', +' --', +' t.page_root || ''.'' || TO_CHAR(10000 + t.r#) || ''.'' || NVL(t.order#, t.page_id) || ''.'' || n.page_id AS sort_order,', +' --', +' CASE', +' WHEN r.page_id IS NOT NULL', +' THEN app.get_icon(''fa-minus-square'', ''Remove record from Navigation table'')', +' END AS action,', +' --', +' app.get_page_link (', +' in_page_id => x.page_id,', +' in_app_id => x.core_app_id,', +' in_names => ''P'' || TO_CHAR(x.page_id) || ''_REMOVE_PAGE'',', +' in_values => TO_CHAR(n.page_id)', +' ) AS action_url', +'FROM navigation n', +'JOIN apps a', +' ON a.app_id = n.app_id', +' AND a.is_active = ''Y''', +'CROSS JOIN x', +'LEFT JOIN t', +' ON t.app_id = n.app_id', +' AND t.page_id = n.page_id', +'LEFT JOIN nav_pages_to_remove r', +' ON r.page_id = n.page_id', +'WHERE (', +' n.app_id = x.app_id', +' OR (', +' n.is_shared = ''Y''', +' AND n.page_id NOT IN (', +' -- pages from active apps takes priority', +' SELECT n.page_id', +' FROM navigation n', +' WHERE n.app_id = x.app_id', +' )', +' )', +')', +'--', +'UNION ALL', +'SELECT', +' n.app_id,', +' n.page_id,', +' n.parent_id,', +' n.order#,', +' NVL(t.page_root, n.page_id) || '' '' || n.page_group AS page_group,', +' n.page_alias,', +' --', +' CASE WHEN n.parent_id IS NOT NULL', +' THEN REPLACE(LTRIM(RPAD(''-'', (t.depth + 1) * 4), ''-''), '' '', ''&'' || ''nbsp; '')', +' END || app.get_page_name(in_app_id => n.app_id, in_page_id => n.page_id, in_name => n.page_name) AS page_name,', +' --', +' n.page_title,', +' n.css_class,', +' n.page_template,', +' --', +' CASE WHEN n.page_mode = ''Normal'' THEN NULL ELSE ''Y'' END AS is_modal,', +' n.is_hidden,', +' n.is_reset,', +' n.is_shared,', +' --', +' CASE WHEN n.auth_scheme LIKE ''%MUST_NOT_BE_PUBLIC_USER%''', +' THEN app.get_icon(''fa-check-square'', ''MUST_NOT_BE_PUBLIC_USER'')', +' ELSE n.auth_scheme', +' END AS auth_scheme,', +' --', +' app.get_page_link (', +' in_page_id => n.page_id,', +' in_app_id => n.app_id', +' ) AS page_url,', +' --', +' NULL AS allow_changes, -- no changes allowed', +' --', +' NVL(t.page_root, n.page_id) || ''.'' || TO_CHAR(10000 + (', +' SELECT NVL(MAX(z.r#), 0) AS nearest_r#', +' FROM t z', +' WHERE z.app_id = n.app_id', +' AND z.page_group = n.page_group', +' AND z.order# = n.order#', +' )) || ''.'' || NVL(n.order#, n.page_id) AS sort_order,', +' --', +' app.get_icon(''fa-plus-square'', ''Create record in Navigation table'') AS action,', +' --', +' app.get_page_link (', +' in_page_id => x.page_id,', +' in_app_id => x.core_app_id,', +' in_names => ''P'' || TO_CHAR(x.page_id) || ''_ADD_PAGE'',', +' in_values => TO_CHAR(n.page_id)', +' ) AS action_url', +'FROM nav_pages_to_add n', +'JOIN apps a', +' ON a.app_id = n.app_id', +' AND a.is_active = ''Y''', +'CROSS JOIN x', +'LEFT JOIN t', +' ON t.app_id = n.app_id', +' AND t.page_id = n.parent_id;', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_PAGES_TO_ADD" ("APP_ID", "PAGE_ID", "PARENT_ID", "PAGE_ALIAS", "PAGE_NAME", "PAGE_TITLE", "ORDER#", "CSS_CLASS", "PAGE_TEMPLATE", "PAGE_MODE", "IS_HIDDEN", "IS_RESET", "IS_SHARED", "PAGE_GROUP", "PAGE_LINK", "AUTH_SC' +||'HEME") AS ', +' WITH g AS (', +' SELECT', +' p.page_group,', +' n.page_id,', +' n.parent_id,', +' n.order#,', +' p.page_mode', +' FROM navigation n', +' JOIN apex_application_pages p', +' ON p.application_id = n.app_id', +' AND p.page_id = n.page_id', +' WHERE n.app_id = app.get_app_id()', +')', +'SELECT', +' p.application_id AS app_id,', +' p.page_id,', +' --', +' (', +' SELECT COALESCE (', +' MAX((', +' SELECT MAX(g.page_id) AS nearest_page', +' FROM g', +' WHERE g.page_id < p.page_id', +' AND g.page_group = p.page_group', +' AND g.page_mode = ''Normal''', +' AND p.page_mode != ''Normal''', +' )),', +' MAX(CASE WHEN g.parent_id IS NULL THEN g.page_id END),', +' MIN(g.page_id)', +' ) AS parent_id', +' FROM g', +' WHERE g.page_group = p.page_group', +' ) AS parent_id,', +' --', +' p.page_alias,', +' p.page_name,', +' p.page_title,', +' --', +' COALESCE (', +' CASE p.page_id', +' WHEN 0 THEN 599 -- preferred order', +' WHEN 9999 THEN 999', +' END,', +' (', +' SELECT MAX(g.order#) AS order#', +' FROM g', +' WHERE g.page_group = p.page_group', +' AND g.page_id < p.page_id', +' AND g.parent_id IN (', +' SELECT MAX(g.parent_id) AS parent_id', +' FROM g', +' WHERE g.page_group = p.page_group', +' AND g.page_id < p.page_id', +' AND g.parent_id IS NOT NULL', +' )', +' ', +' ),', +' CASE WHEN MOD(p.page_id, 100) = 0 THEN p.page_id END', +' ) AS order#,', +' --', +' p.page_css_classes AS css_class,', +' p.page_template,', +' p.page_mode,', +' --', +' CASE WHEN p.page_mode != ''Normal'' THEN ''Y'' END AS is_hidden, -- hide page on default, except for modals', +' --', +' ''Y'' AS is_reset, -- reset page items', +' NULL AS is_shared,', +' --', +' p.page_group,', +' p.page_id AS page_link,', +' p.authorization_scheme AS auth_scheme', +'FROM apex_application_pages p', +'LEFT JOIN navigation n', +' ON n.app_id = p.application_id', +' AND n.page_id = p.page_id', +'WHERE p.application_id = app.get_app_id()', +' AND n.page_id IS NULL;', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_PAGES_TO_REMOVE" ("PAGE_ID") AS ', +' SELECT n.page_id', +'FROM navigation n', +'LEFT JOIN apex_application_pages p', +' ON p.application_id = n.app_id', +' AND p.page_id = n.page_id', +'WHERE n.app_id = app.get_app_id()', +' AND p.application_id IS NULL;', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_REGIONS" ("PAGE_GROUP", "PAGE_ID", "REGION_ICON", "REGION_NAME", "TEMPLATE", "STATIC_ID", "TABLE_NAME", "TABLE_LINK", "FIX_SETUP", "FIX_SYNC", "FIX_HANDLER", "IS_INS_ALLOWED", "IS_UPD_ALLOWED", "IS_DEL_ALLOWED", "ITE' +||'MS", "BUTTONS", "IS_WHERE_CLAUSE", "IS_CONDITIONAL", "TARGET_TYPE", "TARGET_NAME", "IS_GRID_BUTTON", "IS_GRID_CONDITIONAL", "DISPLAY_SEQUENCE", "QUERY_TYPE_CODE", "AUTHORIZATION_SCHEME") AS ', +' WITH x AS (', +' SELECT', +' app.get_item(''$PAGE_ID'') AS page_id,', +' app.get_item(''$AUTH_SCHEME'') AS auth_scheme,', +' a.app_id', +' FROM users u', +' JOIN apps a', +' ON a.app_id = app.get_app_id()', +' WHERE u.user_id = app.get_user_id()', +'),', +'c AS (', +' SELECT', +' r.region_id,', +' c.table_name,', +' --c.data_length, c.nullable', +' c.column_name,', +' --', +' CASE REGEXP_REPLACE(c.data_type, ''\(\d+\)'', '''')', +' WHEN ''CHAR'' THEN ''VARCHAR2''', +' WHEN ''INTERVAL DAY TO SECOND'' THEN ''INTERVAL_D2S''', +' WHEN ''TIMESTAMP WITH TIME ZONE'' THEN ''TIMESTAMP_TZ''', +' ELSE REGEXP_REPLACE(c.data_type, ''\(\d+\)'', '''')', +' END AS data_type', +' FROM user_tab_cols c', +' JOIN apex_application_page_regions r', +' ON r.table_name = c.table_name', +' JOIN x', +' ON x.app_id = r.application_id', +' WHERE r.source_type_code = ''NATIVE_IG''', +' AND r.query_type_code = ''TABLE''', +'),', +'b AS (', +' SELECT', +' c.region_id,', +' r.table_name,', +' --c.max_length, c.is_required,', +' c.source_expression AS column_name,', +' c.data_type', +' FROM apex_appl_page_ig_columns c', +' JOIN apex_application_page_regions r', +' ON r.application_id = c.application_id', +' AND r.region_id = c.region_id', +' JOIN x', +' ON x.app_id = r.application_id', +' WHERE r.source_type_code = ''NATIVE_IG''', +' AND r.query_type_code = ''TABLE''', +' AND c.source_type_code = ''DB_COLUMN''', +' AND c.data_type NOT IN (''ROWID'')', +'),', +'d AS (', +' SELECT', +' NVL(c.region_id, b.region_id) AS region_id,', +' NVL(c.table_name, b.table_name) AS table_name,', +' --', +' LISTAGG(CASE', +' WHEN c.table_name IS NULL THEN ''Removed '' || b.column_name || '' ('' || b.data_type || '')''', +' WHEN b.table_name IS NULL THEN ''Added '' || c.column_name || '' ('' || c.data_type || '')''', +' ELSE ''Changed '' || b.column_name || '' from '' || b.data_type || '' to '' || c.data_type', +' END, CHR(10)) WITHIN GROUP (ORDER BY b.column_name, c.column_name) AS fix_sync', +' FROM b', +' FULL JOIN c', +' ON c.region_id = b.region_id', +' AND c.table_name = b.table_name', +' AND c.column_name = b.column_name', +' WHERE NVL(c.data_type, ''-'') != NVL(b.data_type, ''-'')', +' GROUP BY NVL(c.region_id, b.region_id), NVL(c.table_name, b.table_name)', +')', +'SELECT', +' p.page_group || '' '' || r.page_id || '' '' || p.page_title AS page_group,', +' r.page_id,', +' --r.region_id,', +' --', +' CASE WHEN r.icon_css_classes IS NOT NULL THEN app.get_icon(r.icon_css_classes) END AS region_icon,', +' --', +' CASE', +' WHEN r.template != ''Hero''', +' THEN REPLACE(RPAD('' '', 3), '' '', ''&'' || ''nbsp; '')', +' END || r.region_name AS region_name,', +' --', +' --r.parent_region_id,', +' --r.source_type,', +' --r.source_type_code,', +' --', +' CASE', +' WHEN r.source_type_code = ''NATIVE_IG''', +' THEN r.source_type', +' ELSE r.template', +' END AS template,', +' --', +' CASE', +' WHEN r.source_type_code = ''NATIVE_IG'' AND r.static_id IS NULL', +' THEN app.get_icon(''fa-warning'')', +' ELSE r.static_id', +' END AS static_id,', +' --', +' CASE', +' WHEN r.query_type_code = ''SQL''', +' THEN app.get_icon(''fa-warning'')', +' ELSE r.table_name', +' END AS table_name,', +' --', +' app.get_page_link (', +' in_page_id => CASE', +' WHEN t.object_type = ''TABLE'' THEN 951', +' WHEN t.object_type = ''VIEW'' THEN 955', +' END,', +' in_names => CASE', +' WHEN t.object_type = ''TABLE'' THEN ''P951_TABLE_NAME''', +' WHEN t.object_type = ''VIEW'' THEN ''P955_VIEW_NAME''', +' END,', +' in_values => r.table_name', +' ) AS table_link,', +' --', +' CASE', +' WHEN r.source_type_code != ''NATIVE_IG''', +' THEN NULL', +' WHEN NVL(g.add_row_if_empty, ''No'') = ''No''', +' AND g.select_first_row = ''No''', +' AND g.pagination_type = ''Page''', +' AND g.show_total_row_count = ''Yes''', +' AND g.toolbar_buttons = ''SEARCH_COLUMN:SEARCH_FIELD:ACTIONS_MENU:SAVE''', +' --', +' AND REGEXP_REPLACE(g.javascript_code, ''\s+'', '' '') LIKE ''function(config) { return unified_ig_toolbar(config%''', +' THEN NULL', +' ELSE app.get_icon(''fa-warning'', RTRIM (', +' CASE WHEN NVL(g.add_row_if_empty, ''No'') = ''No'' THEN NULL ELSE ''ADD_ROW_IF_EMPTY, '' END ||', +' CASE WHEN g.select_first_row = ''No'' THEN NULL ELSE ''SELECT_FIRST_ROW, '' END ||', +' CASE WHEN g.pagination_type = ''Page'' THEN NULL ELSE ''PAGINATION_TYPE, '' END ||', +' CASE WHEN g.show_total_row_count = ''Yes'' THEN NULL ELSE ''SHOW_TOTAL_ROW_COUNT, '' END ||', +' --', +' CASE WHEN REGEXP_REPLACE(g.javascript_code, ''\s+'', '' '') LIKE ''function(config) { return unified_ig_toolbar(config%'' THEN NULL ELSE ''JAVASCRIPT_CODE'' END,', +' '', ''))', +' END AS fix_setup,', +' --', +' CASE WHEN d.fix_sync IS NOT NULL THEN app.get_icon(''fa-warning'', d.fix_sync) END AS fix_sync,', +' --', +' CASE', +' WHEN r.source_type_code != ''NATIVE_IG''', +' THEN NULL', +' WHEN r.source_type_code = ''NATIVE_IG''', +' AND g.is_editable = ''No''', +' THEN NULL', +' WHEN r.source_type_code = ''NATIVE_IG''', +' AND s.process_name = ''SAVE_'' || r.static_id', +' AND s.process_type_code = ''NATIVE_IG_DML''', +' AND s.attribute_06 = ''N'' -- lock_row', +' THEN NULL', +' ELSE app.get_icon(''fa-warning'', RTRIM (', +' CASE WHEN r.source_type_code = ''NATIVE_IG'' THEN NULL ELSE ''SOURCE_TYPE, '' END ||', +' CASE WHEN s.process_name = '' SAVE_'' || r.static_id THEN NULL ELSE ''PROCESS_NAME, '' END ||', +' CASE WHEN s.process_type_code = ''NATIVE_IG_DML'' THEN NULL ELSE ''PROCESS_TYPE, '' END ||', +' CASE WHEN s.attribute_06 = ''N'' THEN NULL ELSE ''LOCK_ROW, '' END,', +' '', ''))', +' END AS fix_handler,', +' --', +' CASE WHEN g.edit_operations LIKE ''%i%'' THEN ''Y'' END AS is_ins_allowed,', +' CASE WHEN g.edit_operations LIKE ''%u%'' THEN ''Y'' END AS is_upd_allowed,', +' CASE WHEN g.edit_operations LIKE ''%d%'' THEN ''Y'' END AS is_del_allowed,', +' --', +' NULLIF(r.items, 0) AS items,', +' NULLIF(r.buttons, 0) AS buttons,', +' --', +' CASE WHEN r.where_clause IS NOT NULL THEN ''Y'' END AS is_where_clause,', +' CASE WHEN r.condition_type_code IS NOT NULL THEN ''Y'' END AS is_conditional,', +' --', +' s.attribute_01 AS target_type,', +' s.attribute_03 AS target_name,', +' --', +' CASE', +' WHEN r.source_type_code = ''NATIVE_IG''', +' AND s.when_button_pressed IS NOT NULL', +' THEN ''Y'' END AS is_grid_button,', +' --', +' CASE', +' WHEN r.source_type_code = ''NATIVE_IG''', +' AND s.condition_type_code IS NOT NULL -- s.condition_expression1', +' THEN ''Y'' END AS is_grid_conditional,', +' --', +' r.display_sequence,', +' r.query_type_code,', +' r.authorization_scheme', +'FROM apex_application_page_regions r', +'JOIN apex_application_pages p', +' ON p.application_id = r.application_id', +' AND p.page_id = r.page_id', +'CROSS JOIN x', +'LEFT JOIN user_objects t', +' ON t.object_name = r.table_name', +' AND t.object_type IN (''TABLE'', ''VIEW'')', +'LEFT JOIN apex_appl_page_igs g', +' ON g.application_id = r.application_id', +' AND g.region_id = r.region_id', +'LEFT JOIN d', +' ON d.region_id = r.region_id', +'LEFT JOIN apex_application_page_proc s', +' ON s.application_id = g.application_id', +' AND s.region_id = g.region_id', +' AND s.process_point_code = ''AFTER_SUBMIT''', +'WHERE r.application_id = x.app_id', +' AND r.parent_region_id IS NULL', +' AND (x.page_id = p.page_id OR x.page_id IS NULL)', +' AND (x.auth_scheme = r.authorization_scheme OR x.auth_scheme IS NULL);', +'', +'CREATE OR REPLACE FORCE VIEW "NAV_TOP" ("LVL", "LABEL", "TARGET", "IS_CURRENT_LIST_ENTRY", "IMAGE", "IMAGE_ATTRIBUTE", "IMAGE_ALT_ATTRIBUTE", "ATTRIBUTE01", "ATTRIBUTE02", "ATTRIBUTE03", "ATTRIBUTE04", "ATTRIBUTE05", "ATTRIBUTE06", "ATTRIBUTE07", "AT' +||'TRIBUTE08", "ATTRIBUTE09", "ATTRIBUTE10", "PAGE_GROUP", "SORT_ORDER") AS ', +' WITH curr AS (', +' SELECT', +' app.get_app_id() AS app_id,', +' app.get_page_id() AS page_id,', +' app.get_page_parent() AS parent_id,', +' app.ge')) +); +wwv_flow_api.component_end; +end; +/ +begin +wwv_flow_api.component_begin ( + p_version_yyyy_mm_dd=>'2021.04.15' +,p_release=>'21.1.7' +,p_default_workspace_id=>9014660246496943 +,p_default_application_id=>770 +,p_default_id_offset=>0 +,p_default_owner=>'CORE' +); +wwv_flow_api.append_to_install_script( + p_id=>wwv_flow_api.id(20442967958321458) +,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2( +'t_page_root() AS page_root,', +' app.get_page_group() AS page_group,', +' app.get_user_id() AS user_id,', +' app.get_user_name() AS user_name', +' FROM users u', +' WHERE u.user_id = app.get_user_id()', +')', +'SELECT', +' CASE WHEN n.parent_id IS NULL THEN 1 ELSE 2 END AS lvl,', +' --', +' CASE', +' WHEN n.page_id = 100 -- home page', +' THEN REPLACE(n.page_name, ''&'' || ''ENV_NAME.'', app.get_env_name() || '' &'' || ''nbsp; '')', +' WHEN n.page_id > 0', +' THEN REGEXP_REPLACE(REPLACE(n.page_name, ''&'' || ''APP_USER.'', APEX_ESCAPE.HTML(NVL(curr.user_name, curr.user_id))), ''^(&'' || ''nbsp; )+'', '''')', +' ELSE ''