Navigation performance improved by using MVW

This commit is contained in:
Jan Kvetina 2022-03-06 10:54:10 +01:00
parent 7be35997cc
commit 54fe17e49d
5 changed files with 325 additions and 234 deletions

View File

@ -23,7 +23,7 @@ wwv_flow_api.create_page(
,p_required_role=>wwv_flow_api.id(9556407311505078)
,p_page_comment=>'Navigation setup page'
,p_last_updated_by=>'DEV'
,p_last_upd_yyyymmddhh24miss=>'20220305173721'
,p_last_upd_yyyymmddhh24miss=>'20220306094513'
);
wwv_flow_api.create_page_plug(
p_id=>wwv_flow_api.id(24141119524306145)
@ -3129,6 +3129,17 @@ wwv_flow_api.create_page_button(
,p_button_css_classes=>'&P910_AUTO_UPDATE_HOT.'
,p_button_cattributes=>'style="margin-left: 2rem;"'
);
wwv_flow_api.create_page_button(
p_id=>wwv_flow_api.id(32964041787841115)
,p_button_sequence=>30
,p_button_plug_id=>wwv_flow_api.id(9192009232668637)
,p_button_name=>'PUBLISH_CHANGES'
,p_button_action=>'SUBMIT'
,p_button_template_options=>'#DEFAULT#'
,p_button_template_id=>wwv_flow_api.id(9145249029569999)
,p_button_image_alt=>'&BUTTON_PUBLISH_CHANGES.'
,p_button_position=>'RIGHT_OF_TITLE'
);
wwv_flow_api.create_page_item(
p_id=>wwv_flow_api.id(9260980865429010)
,p_name=>'P910_ADD_PAGE'
@ -3268,16 +3279,36 @@ wwv_flow_api.create_page_process(
,p_process_sequence=>20
,p_process_point=>'AFTER_SUBMIT'
,p_process_type=>'NATIVE_PLSQL'
,p_process_name=>'AUTO_UPDATE'
,p_process_name=>'ACTION_AUTO_UPDATE'
,p_process_sql_clob=>wwv_flow_string.join(wwv_flow_t_varchar2(
'app.log_action(''AUTO_UPDATE'');',
'--',
'app_actions.nav_autoupdate();',
'--',
'app.log_success();',
''))
,p_process_clob_language=>'PLSQL'
,p_error_display_location=>'INLINE_IN_NOTIFICATION'
,p_process_when_button_id=>wwv_flow_api.id(9261437105429015)
);
wwv_flow_api.create_page_process(
p_id=>wwv_flow_api.id(32964351219841118)
,p_process_sequence=>30
,p_process_point=>'AFTER_SUBMIT'
,p_process_type=>'NATIVE_PLSQL'
,p_process_name=>'ACTION_PUBLISH_CHANGES'
,p_process_sql_clob=>wwv_flow_string.join(wwv_flow_t_varchar2(
'app.log_action(''PUBLISH_CHANGES'');',
'--',
'DBMS_MVIEW.REFRESH(''NAV_AVAILABILITY_MVW'', ''C'', parallelism => 2);',
'DBMS_MVIEW.REFRESH(''NAV_OVERVIEW_MVW'', ''C'', parallelism => 2);',
'--',
'app.log_success();',
''))
,p_process_clob_language=>'PLSQL'
,p_error_display_location=>'INLINE_IN_NOTIFICATION'
,p_process_when_button_id=>wwv_flow_api.id(32964041787841115)
);
wwv_flow_api.create_page_process(
p_id=>wwv_flow_api.id(9261288538429013)
,p_process_sequence=>10
@ -3310,6 +3341,18 @@ wwv_flow_api.create_page_process(
,p_process_when=>'P910_REMOVE_PAGE'
,p_process_when_type=>'ITEM_IS_NOT_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.create_page_process(
p_id=>wwv_flow_api.id(22086431917580632)
,p_process_sequence=>30

View File

@ -1195,32 +1195,15 @@ CREATE OR REPLACE PACKAGE BODY app AS
BEGIN
-- get auth cheme, procedure...
SELECT
MIN(p.authorization_scheme),
MIN(f.package_name), -- package_name
MIN(f.object_name), -- procedure_name
MIN(f.pls_type),
MIN(a.argument_name) -- argument_name
n.auth_scheme,
n.package_name,
n.procedure_name,
n.data_type,
n.argument_name
INTO v_auth_scheme, v_package_name, v_procedure_name, v_data_type, v_page_argument
FROM apex_application_pages p
LEFT JOIN user_procedures s
ON s.object_name IN ('A' || TO_CHAR(in_app_id), 'APP', 'AUTH') -- packages
AND s.procedure_name = p.authorization_scheme
LEFT JOIN user_arguments f
ON f.object_name = s.procedure_name
AND f.package_name = s.object_name
AND f.overload IS NULL
AND f.position = 0
AND f.argument_name IS NULL
AND f.in_out = 'OUT'
LEFT JOIN user_arguments a
ON a.object_name = f.package_name
AND a.package_name = f.object_name
AND a.overload IS NULL
AND a.position = 1
AND a.data_type = 'NUMBER'
AND a.in_out = 'IN'
WHERE p.application_id = in_app_id
AND p.page_id = in_page_id;
FROM nav_availability_mvw n
WHERE n.application_id = in_app_id
AND n.page_id = in_page_id;
-- log current page
IF app.is_debug_on() AND in_page_id = app.get_page_id() THEN

View File

@ -0,0 +1,36 @@
--DROP MATERIALIZED VIEW nav_availability_mvw;
CREATE MATERIALIZED VIEW nav_availability_mvw
BUILD DEFERRED
REFRESH ON DEMAND COMPLETE
AS
SELECT
p.application_id,
p.page_id,
MIN(p.authorization_scheme) AS auth_scheme,
MIN(f.package_name) AS package_name,
MIN(f.object_name) AS procedure_name,
MIN(f.pls_type) AS data_type,
MIN(a.argument_name) AS argument_name
FROM apex_application_pages p
LEFT JOIN all_procedures s
ON s.owner = app.get_core_owner()
AND s.object_name IN ('A' || TO_CHAR(p.application_id), 'APP', 'AUTH') -- packages
AND s.procedure_name = p.authorization_scheme
LEFT JOIN all_arguments f
ON f.owner = s.owner
AND f.object_name = s.procedure_name
AND f.package_name = s.object_name
AND f.overload IS NULL
AND f.position = 0
AND f.argument_name IS NULL
AND f.in_out = 'OUT'
LEFT JOIN all_arguments a
ON a.owner = f.owner
AND a.object_name = f.package_name
AND a.package_name = f.object_name
AND a.overload IS NULL
AND a.position = 1
AND a.data_type = 'NUMBER'
AND a.in_out = 'IN'
GROUP BY p.application_id, p.page_id;

View File

@ -5,154 +5,33 @@ WITH x AS (
app.get_app_id() AS app_id,
app.get_core_app_id() AS core_app_id
FROM DUAL
),
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,
p.page_comment AS comments,
--
'#' AS javascript_target,
i.item_source AS javascript,
--
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
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
LEFT JOIN apex_application_page_items i
ON i.application_id = n.app_id
AND i.item_name = 'P' || TO_CHAR(n.page_id) || '_JAVASCRIPT_TARGET'
WHERE (n.app_id, n.page_id) NOT IN (
SELECT
app.get_core_app_id() AS app_id,
947 AS page_id
FROM DUAL
)
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,
--
app.get_page_title (
in_app_id => n.app_id,
in_page_id => n.page_id,
in_title => t.page_title
) AS page_title,
--
t.page_css_classes AS css_class,
t.page_template,
--
n.page_group,
n.page_alias,
n.page_name,
n.page_title,
n.css_class,
n.page_template,
n.is_hidden,
n.is_reset,
n.is_shared,
--
CASE WHEN t.page_mode = 'Normal' THEN NULL ELSE 'Y' END AS is_modal,
CASE WHEN t.javascript IS NOT NULL THEN 'Y' END AS is_javascript,
t.javascript,
--
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 app_actions.get_html_a(app.get_page_url (
in_page_id => 920,
in_app_id => n.app_id,
in_names => 'P920_AUTH_SCHEME',
in_values => t.authorization_scheme
), t.authorization_scheme)
END AS auth_scheme,
--
CASE
WHEN t.javascript_target IS NOT NULL
THEN t.javascript_target
--
WHEN n.page_id > 0 AND r.page_id IS NULL
THEN app.get_page_url (
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,
--
t.comments,
--
'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_url (
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
n.is_modal,
n.is_javascript,
n.javascript,
n.auth_scheme,
n.page_url,
n.comments,
n.allow_changes,
n.sort_order,
n.action,
n.action_url
FROM nav_overview_mvw n
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 (
@ -164,75 +43,7 @@ WHERE (
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,
--
n.is_hidden,
n.is_reset,
n.is_shared,
--
CASE WHEN n.page_mode = 'Normal' THEN NULL ELSE 'Y' END AS is_modal,
CASE WHEN t.javascript IS NOT NULL THEN 'Y' END AS is_javascript,
t.javascript,
--
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,
--
CASE
WHEN t.javascript_target IS NOT NULL
THEN t.javascript_target
--
ELSE app.get_page_url (
in_page_id => n.page_id,
in_app_id => n.app_id
)
END AS page_url,
--
n.comments,
--
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_url (
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
CROSS JOIN x
LEFT JOIN t
ON t.app_id = n.app_id
AND t.page_id = n.parent_id;
);
--
COMMENT ON TABLE nav_overview IS '[CORE - DASHBOARD] Enriched navigation overview used also for menu rendering';
--

218
views/nav_overview_mvw.sql Normal file
View File

@ -0,0 +1,218 @@
--DROP MATERIALIZED VIEW nav_overview_mvw;
CREATE MATERIALIZED VIEW nav_overview_mvw
BUILD DEFERRED
REFRESH ON DEMAND COMPLETE
AS
WITH t AS (
SELECT /*+ MATERIALIZE */
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,
p.page_comment AS comments,
--
'#' AS javascript_target,
i.item_source AS javascript,
--
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
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
LEFT JOIN apex_application_page_items i
ON i.application_id = n.app_id
AND i.item_name = 'P' || TO_CHAR(n.page_id) || '_JAVASCRIPT_TARGET'
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,
--
app.get_page_title (
in_app_id => n.app_id,
in_page_id => n.page_id,
in_title => t.page_title
) AS page_title,
--
t.page_css_classes AS css_class,
t.page_template,
--
n.is_hidden,
n.is_reset,
n.is_shared,
--
CASE WHEN t.page_mode = 'Normal' THEN NULL ELSE 'Y' END AS is_modal,
CASE WHEN t.javascript IS NOT NULL THEN 'Y' END AS is_javascript,
t.javascript,
--
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 app_actions.get_html_a(app.get_page_url (
in_page_id => 920,
in_app_id => n.app_id,
in_names => 'P920_AUTH_SCHEME',
in_values => t.authorization_scheme
), t.authorization_scheme)
END AS auth_scheme,
--
CASE
WHEN t.javascript_target IS NOT NULL
THEN t.javascript_target
--
WHEN n.page_id > 0 AND r.page_id IS NULL
THEN app.get_page_url (
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,
--
t.comments,
--
'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_url (
in_page_id => 910,--x.page_id,
in_app_id => app.get_core_app_id(),
in_names => 'P' || TO_CHAR(910) || '_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
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, n.page_id) NOT IN (
SELECT
app.get_core_app_id() AS app_id,
947 AS page_id
FROM DUAL
)
--
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,
--
n.is_hidden,
n.is_reset,
n.is_shared,
--
CASE WHEN n.page_mode = 'Normal' THEN NULL ELSE 'Y' END AS is_modal,
CASE WHEN t.javascript IS NOT NULL THEN 'Y' END AS is_javascript,
t.javascript,
--
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,
--
CASE
WHEN t.javascript_target IS NOT NULL
THEN t.javascript_target
--
ELSE app.get_page_url (
in_page_id => n.page_id,
in_app_id => n.app_id
)
END AS page_url,
--
n.comments,
--
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_url (
in_page_id => 910,
in_app_id => app.get_core_app_id(),
in_names => 'P' || TO_CHAR(910) || '_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
LEFT JOIN t
ON t.app_id = n.app_id
AND t.page_id = n.parent_id;