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


-- DROP FUNCTION smev.f3_create_sfr_register();

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$
;