Skip to content

packages tree.get_caller__

Jan Kvetina edited this page Oct 9, 2020 · 3 revisions

tree.get_caller__

Repository spec: tree.get_caller__, body: tree.get_caller__


Signature

PROCEDURE get_caller__ (
    in_log_id               logs.log_id%TYPE        := NULL,
    in_parent_id            logs.log_parent%TYPE    := NULL,
    in_flag                 logs.flag%TYPE          := NULL,
    out_module_name     OUT logs.module_name%TYPE,
    out_module_line     OUT logs.module_line%TYPE,
    out_parent_id       OUT logs.log_parent%TYPE
)
ACCESSIBLE BY (
    PACKAGE tree,
    PACKAGE tree_ut
);
Show code (85 lines)

PROCEDURE get_caller__ (
    in_log_id               logs.log_id%TYPE        := NULL,
    in_parent_id            logs.log_parent%TYPE    := NULL,
    in_flag                 logs.flag%TYPE          := NULL,
    out_module_name     OUT logs.module_name%TYPE,
    out_module_line     OUT logs.module_line%TYPE,
    out_parent_id       OUT logs.log_parent%TYPE
)
ACCESSIBLE BY (
    PACKAGE tree,
    PACKAGE tree_ut
) AS
    curr_module     logs.module_name%TYPE;
    curr_index      logs.module_name%TYPE;
    parent_index    logs.module_name%TYPE;
    next_module     logs.module_name%TYPE;
    prev_module     logs.module_name%TYPE;
BEGIN
    out_parent_id := in_parent_id;
    --
    FOR i IN 2 .. UTL_CALL_STACK.DYNAMIC_DEPTH LOOP  -- 2 = ignore this function
        curr_module := UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(i));
        --
        CONTINUE WHEN
            curr_module LIKE $$PLSQL_UNIT || '.%'       -- skip this package
            OR UTL_CALL_STACK.UNIT_LINE(i) IS NULL;     -- skip DML queries
        --
        out_module_name     := UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(i));
        out_module_line     := UTL_CALL_STACK.UNIT_LINE(i);
        curr_index          := (UTL_CALL_STACK.DYNAMIC_DEPTH - i) || '|' || out_module_name;
        parent_index        := curr_index;
        --
        BEGIN
            next_module     := UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(i + 1));
            prev_module     := UTL_CALL_STACK.CONCATENATE_SUBPROGRAM(UTL_CALL_STACK.SUBPROGRAM(i - 1));
        EXCEPTION
        WHEN BAD_DEPTH THEN
            NULL;
        END;

        -- map SESS called thru schedulers
        IF UTL_CALL_STACK.DYNAMIC_DEPTH >= i + 1 AND in_parent_id IS NULL THEN
            IF (out_module_name LIKE trigger_sess AND next_module = internal_log_fn) THEN
                out_module_line := 0;
                out_parent_id   := COALESCE(recent_log_id, in_log_id);
                --
                RETURN;  -- exit procedure
            END IF;
        END IF;

        -- create child
        IF in_flag IN (tree.flag_action) THEN
            map_actions(curr_index) := in_log_id;
            --
        ELSIF in_flag IN (tree.flag_module, tree.flag_scheduler) THEN
            map_modules(curr_index) := in_log_id;

            -- find previous module (on another depth)
            parent_index := (UTL_CALL_STACK.DYNAMIC_DEPTH - i - 1) || '|' || next_module;
        END IF;

        -- fix tree.update_timer, it must updates M flags and not A flags
        IF in_log_id IS NULL AND prev_module = tree.internal_update_timer THEN
            -- recover log_id only from map_modules
            IF out_parent_id IS NULL AND map_modules.EXISTS(parent_index) THEN
                out_parent_id := NULLIF(map_modules(parent_index), in_log_id);
            END IF;
            --
            EXIT;  -- break
        END IF;

        -- recover parent_id
        IF out_parent_id IS NULL AND map_actions.EXISTS(parent_index) THEN
            out_parent_id := NULLIF(map_actions(parent_index), in_log_id);
        END IF;
        --
        IF out_parent_id IS NULL AND map_modules.EXISTS(parent_index) THEN
            out_parent_id := NULLIF(map_modules(parent_index), in_log_id);
        END IF;
        --
        EXIT;  -- break, we need just first one
    END LOOP;
    --
    out_module_line := COALESCE(out_module_line, 0);
END;

Clone this wiki locally