Загрузка данных


CREATE OR REPLACE FUNCTION smev.f3_create_sfr_register()
RETURNS integer
LANGUAGE plpgsql
AS $function$
    declare
        smev_register_file record;
        sid text;
        smev_processes record;
        query_text text;
        process_j json;
        process_result_stack json[];
        metadata text[];
        v_response_content bytea;
        v_cookies text;
        v_base varchar(255);
        v_file_j json;
        v_file_f text;
        v_oper_code varchar(50);
    
        max_cycle int;
        current_cycle int;
        v_condition bool;
        v_cycle_model_id int;
        p_type    text;
        p_method text;
    
        v_robot text;

        -- Технические переменные для формировании ошибок при сбое в системе (не в процессе формирования реестра)
        err_code text; -- код ошибки
        msg_text text; -- текст ошибки
        exc_context text; -- контекст исключения
        msg_detail text; -- подробный текст ошибки
        exc_hint text; -- текст подсказки к исключению

    begin
        begin -- exception
            sid := uuid_generate_v4()::text;
            select web_base into v_base from tools.settings limit 1;
            v_robot:= 'bb_robot';
            -- ******
            -- LOGIN:
            perform curl.curl_easy_setopt_timeout_ms(1000000);         
            -- LOOP
            for smev_register_file in
                select
                    id, name, description, waiting_time, deadline_for_report_generation, countdown_date, day_type
                from report.conf_scheduler_sfr
                where is_active = true

            loop
                
                perform robot.log_message('Запуск', 'Формируем реестр id= ' || smev_register_file.id::text , sid);
                RAISE NOTICE 'Next id from conf_scheduler_sfr %', smev_register_file.id;
                
                metadata:= null;
                v_cookies:= null;
                process_result_stack:= null;
                v_condition := true;
                max_cycle:=0;
                current_cycle:=0;
                v_cycle_model_id:= 0;
            
                v_cookies := robot.login_ex2(v_base, v_robot);
                
                if coalesce(v_cookies, '') = '' then
                    RAISE EXCEPTION 'Err get cookies postprocess';
                end if;
            
                RAISE NOTICE '-Post process login ok %', sid;
            
                -- **********************************************************************
                while (v_condition) loop
                
                    --smev_processes
                    for smev_processes in
                        select id_etl, id_process, process_type, load_id_var, load_post_process, process_description, operation_type
                        from smev.smev_report_create_register_processes
                        where id_etl = smev_register_file.id
                            and operation_type = 0 and active_task is true
                            -- если current_cycle <> 0 то необходимо добавить в where условие:
                            and case when current_cycle <> 0 then id_process > v_cycle_model_id else true end
                            -- and case when current_cycle <> max_cycle then id_process < id_S6
                    loop
                        
                        RAISE notice 'smev_processes.id_process %, %, %, %, % ',
                            smev_processes.id_etl,
                            smev_processes.id_process,
                            smev_processes.process_type,
                            smev_processes.load_post_process,
                            smev_processes.process_description;
                        
                        v_oper_code:= smev_processes.load_post_process;
                        process_j:= Null;
                        v_file_j:= Null;
                        
                        -- check load_id_var
                        if (smev_processes.load_id_var is not null) then
                            metadata:= smev.f_smev_data_json_build2(smev_processes.load_id_var, process_result_stack, current_cycle, sid);
                        end if;
                        
                        -- 1-модель json, 2-операции, 3-модель файл, 4-модель цикла
                    
                        if smev_processes.process_type in (1, 3, 4) then
                        --raise notice 'тип модели %', smev_processes.process_type::text;
                            -- **********************    
                            -- process is queryModel:
                            if (smev_processes.process_type = 3 ) then
                                query_text:= 'queryModel/file?queryModelCode=' || utils.urlencode(v_oper_code);
                                p_type:= 'application/binary;charset=UTF-8';
                                p_method:= 'GET';
                            else
                                query_text:= 'queryModel?queryModelCode=' || utils.urlencode(v_oper_code);
                                p_type:='application/x-www-form-urlencoded; charset=UTF-8';
                                p_method:= 'POST';
                            end if;
                            if (cardinality(metadata) <> 0 and cardinality(metadata) is not null) then
                                process_j:= json_object(metadata);
                            else
                                -- empty data object {}
                                process_j:= json_build_object();
                            end if;
                        
                        /*elsif smev_processes.process_type = 30 then
                        -- **********************    
                            -- process is queryModel:
                            query_text:= 'queryModel/file?queryModelCode=' || utils.urlencode(v_oper_code);
                            if (cardinality(metadata) <> 0 and cardinality(metadata) is not null) then
                                process_j:= json_object(metadata);
                            else
                                -- empty data object {}
                                process_j:= json_build_object();
                            end if;*/
                        
                        elsif smev_processes.process_type = 2 then
                            -- ***********************
                            -- process is queryAction:
                            query_text:= 'queryAction/action';
                            metadata:= array_prepend(v_oper_code, metadata);
                            metadata:= array_prepend('queryActionCode', metadata);
                            process_j:= json_object(metadata);
                            p_type:='application/x-www-form-urlencoded; charset=UTF-8';
                            p_method:= 'POST';
                        end if;
                        
                        v_response_content:= robot.get_page_data_curl(v_base, query_text, v_cookies, process_j, p_method, p_type);            
                        --v_response_content:= robot.get_page_data(v_base, query_text, v_cookies, process_j);                    
                                
                        -- для формирования xml с проверкой, пропускать модели
                            --raise notice 'пропускаем модель %', smev_processes.process_type::text;
                        if not (smev_processes.process_type = 3) then
                            
                            v_file_j:= convert_from(v_response_content, 'UTF8')::json;
                            
                            if (smev_processes.process_type = 4) then
                                v_cycle_model_id:= smev_processes.id_process;
                                select jsonb_array_length((v_file_j::jsonb)->'list') into max_cycle;
                                raise notice 'Значение v_file_j: %', v_file_j::text;
                                raise notice 'max_cycle length %', max_cycle;
                                if (max_cycle > 0) then
                                    -- cycle initialization(!):
                                    current_cycle:= 1;
                                end if;
                            end if;
                            
                            if (smev_processes.process_type = 5) then
                                if(current_cycle < max_cycle) then
                                    exit; -- Мы выходим из внутреннего цикла
                                else
                                    max_cycle:=0;
                                    current_cycle:=0;
                                end if;
                            end if;
                                
                            process_result_stack[smev_processes.id_process::int] := v_file_j;
                            perform array_append(process_result_stack, v_file_j);
                                
                            -- Проверки перед созданием
                            if smev_register_file.id in (
                                1, 2, 3, 4, 6, 7,
                                8, 9, 12, 14, 15, 16,
                                17, 20, 21, 22, 24, 25, 26,
                                27, 36, 37, 38, 40, 41, 42) then
                                    if smev_processes.id_process = 1 then
                                        if (v_file_j->>'status' <> 'true') then
                                            raise notice 'Нет данных для создания реестра %', smev_register_file.name;
                                            perform robot.log_message('Работа', 'Нет данных для создания реестра ' || smev_register_file.name::text || ', id = ' || smev_register_file.id::text , sid);
                                            exit;
                                        end if;
                                    end if;
                            end if;
                            -- END Проверки перед созданием
                            
                            -- Результа формирования реестра - РАБОТА (логирование в таблицу robot.log)
                            if (v_file_j->>'result' = 'false') then
                                    perform robot.log_message('Работа', 'Ошибка при формировании реестра id = ' || smev_register_file.id::text , sid);
                            else
                                if (v_file_j->>'result' = 'true') then
                                    perform robot.log_message('Работа', 'Успех при формировании реестра id = ' || smev_register_file.id::text , sid);
                                end if;
                            end if;
                        
                        else
                            v_file_f:= convert_from(v_response_content, 'UTF8')::text;
                            raise notice 'Операция формирования xml с проверкой % ', v_file_f;
                            perform robot.log_message('Работа', 'Операция формирования xml с проверкой id = ' || smev_register_file.id::text , sid);
                        end if;
                        
                    end loop;
                    -- END smev_processes
                
                    if(current_cycle >= max_cycle) then
                        v_condition:= false;
                    else
                        current_cycle:= current_cycle + 1;
                        v_condition:= true;
                    end if;
                end loop; -- while loop
                --************************************
                
                    -- logout
                    if not robot.logout_ex(v_base, v_cookies) then
                        RAISE EXCEPTION 'Post process Logout error';
                    else
                        RAISE NOTICE '-Post process logout ok %', sid;
                    end if;    
    
                    perform pg_sleep(1);
                    
                    -- Результа формирования реестра - ФИНИШ (логирование в таблицу robot.log)
                    perform robot.log_message('Финиш', 'Формирование реестра завершено id = ' || smev_register_file.id::text , sid);
                
            end loop;
        
            -- EXCEPTIONS:
            exception when others
            THEN
                GET STACKED DIAGNOSTICS
                err_code = RETURNED_SQLSTATE, -- код ошибки
                msg_text = MESSAGE_TEXT, -- текст ошибки
                exc_context = PG_CONTEXT, -- контекст исключения
                 msg_detail = PG_EXCEPTION_DETAIL, -- подробный текст ошибки
                 exc_hint = PG_EXCEPTION_HINT; -- текст подсказки к исключению
            
                RAISE NOTICE 'ERROR CODE: % MESSAGE TEXT: % CONTEXT: % DETAIL: % HINT: %',
                 err_code, msg_text, exc_context, msg_detail, exc_hint;
            
                -- Результа формирования реестра - ФИНИШ (логирование в таблицу robot.log)
                 perform robot.log_message('Финиш', err_code || ' ; ' || msg_text || ' ; ' || msg_detail , sid);
                
            end;
        
    return 0;

    END;
$function$
;