From d5b5b8c0aab182d905bce3c21aa28e8fda8a83fd Mon Sep 17 00:00:00 2001 From: Daniel Quathamer Date: Mon, 7 Jul 2025 08:14:04 +0200 Subject: [PATCH] Unload / Upload Spaltenlayouts #5 --- .classpath | 2 +- src-modules/module/etl/conf/etl.xml | 4 +- src-modules/module/etl/conf/includes.txt | 1 + .../module/etl/masken/42000_felderinfo.unl | 18 ++- .../etl/masken/42000_masken_felder_bez.unl | 1 + .../create_load_etl_qa_project.sql | 2 +- .../create_load_etl_rpta_column_layout.sql | 68 +++++++++ .../schluesseltabellen/etl_manager_tab.unl | 1 + .../schluesseltabellen/etl_step_fuellen.sql | 59 +++++++- .../trans_rpta_column_layout.sql | 40 +++++ src/de/superx/elt/EtlFmParser.java | 137 ++++++++++++++++++ src/de/superx/elt/SqlExecutor.java | 6 +- superx/WEB-INF/lib/superx-etl.jar | Bin 83825 -> 86206 bytes superx/images/resultset_up.svg | 63 ++++++++ 14 files changed, 392 insertions(+), 10 deletions(-) create mode 100644 src-modules/module/etl/schluesseltabellen/create_load_etl_rpta_column_layout.sql create mode 100644 src-modules/module/etl/schluesseltabellen/trans_rpta_column_layout.sql create mode 100644 src/de/superx/elt/EtlFmParser.java create mode 100644 superx/images/resultset_up.svg diff --git a/.classpath b/.classpath index 3b0f67c..fb26529 100644 --- a/.classpath +++ b/.classpath @@ -18,6 +18,6 @@ - + diff --git a/src-modules/module/etl/conf/etl.xml b/src-modules/module/etl/conf/etl.xml index fb11ba2..417f2eb 100644 --- a/src-modules/module/etl/conf/etl.xml +++ b/src-modules/module/etl/conf/etl.xml @@ -381,7 +381,7 @@ parent="Laderoutinen">Abfragen zur Administration - + @@ -419,7 +419,7 @@ version integer - + diff --git a/src-modules/module/etl/conf/includes.txt b/src-modules/module/etl/conf/includes.txt index 290950c..eec7122 100644 --- a/src-modules/module/etl/conf/includes.txt +++ b/src-modules/module/etl/conf/includes.txt @@ -3,4 +3,5 @@ WEB-INF/conf/edustore/db/bin/SQL_ENV_etl.sam WEB-INF/lib/superx-etl.jar images/eye.svg images/downloadblck.svg +images/resultset_up.svg diff --git a/src-modules/module/etl/masken/42000_felderinfo.unl b/src-modules/module/etl/masken/42000_felderinfo.unl index 850a54f..88ca9a8 100644 --- a/src-modules/module/etl/masken/42000_felderinfo.unl +++ b/src-modules/module/etl/masken/42000_felderinfo.unl @@ -20,4 +20,20 @@ select tid,name from qa_project where active=1 order by 2;\ select null::char(1),'Keine Auwahl möglich' from xdummy\ \ \ -/* <> */^ ^^ +/* <> */^hidden^^ +42008^Spaltenlayout^15^0^0^150^80^1^integer^200^0^1^<> --freemarker template\ +\ +\ +select 1 from xdummy where 0 < (select count(*) from db_version where his_system='rpta')\ +union select 0 from xdummy where \ + 0 = (select count(*) from db_version where his_system='rpta');\ +\ +\ +\ +<#if RPTA_installed==1>\ +select tid,caption from rpta_column_layout order by 2;\ +<#else>\ +select null::char(1),'Keine Auwahl möglich' from xdummy\ +\ +\ +/* <> */^hidden^^ diff --git a/src-modules/module/etl/masken/42000_masken_felder_bez.unl b/src-modules/module/etl/masken/42000_masken_felder_bez.unl index cf98a24..1f92673 100644 --- a/src-modules/module/etl/masken/42000_masken_felder_bez.unl +++ b/src-modules/module/etl/masken/42000_masken_felder_bez.unl @@ -6,3 +6,4 @@ 42000^42005^ 42000^42006^ 42000^42007^ +42000^42008^ diff --git a/src-modules/module/etl/schluesseltabellen/create_load_etl_qa_project.sql b/src-modules/module/etl/schluesseltabellen/create_load_etl_qa_project.sql index e1ed224..71f5f7c 100644 --- a/src-modules/module/etl/schluesseltabellen/create_load_etl_qa_project.sql +++ b/src-modules/module/etl/schluesseltabellen/create_load_etl_qa_project.sql @@ -1,6 +1,6 @@ --Freemarker Template ---used in etl-job sx_insert_mask +--used in etl-job qa_project_upload <#if SQLdialect='Postgres'> drop table if exists tmp_etl_qa_project; drop table if exists tmp_etl_sachgeb_sichtarten; diff --git a/src-modules/module/etl/schluesseltabellen/create_load_etl_rpta_column_layout.sql b/src-modules/module/etl/schluesseltabellen/create_load_etl_rpta_column_layout.sql new file mode 100644 index 0000000..68e315a --- /dev/null +++ b/src-modules/module/etl/schluesseltabellen/create_load_etl_rpta_column_layout.sql @@ -0,0 +1,68 @@ +--Freemarker Template + +--used in etl-job qa_project_upload +<#if SQLdialect='Postgres'> +drop table if exists tmp_rpta_resultset; +drop table if exists tmp_etl_rpta_column_layout; +drop table if exists tmp_rpta_column; +drop table if exists tmp_rpta_column2layout; + + + +CREATE TABLE tmp_rpta_resultset ( + tid integer, + caption character varying(255), + uniquename character varying(255), + fieldclause text, + joinclause text, + whereclause text, + systeminfo_id integer, + is_virtual smallint +); + + +CREATE TABLE tmp_etl_rpta_column_layout ( + tid integer, + uniquename character varying(255), + caption character varying(255), + resultset_id integer, + whereclause text, + description text, + userinfo_id integer, + sortnr integer, + sortclause text, + is_virtual smallint, + resultset_uniquename character varying(255) +); + +CREATE TABLE tmp_rpta_column ( + tid integer, + uniquename character varying(255), + caption character varying(255), + srcfieldname character varying(255), + column_type integer, + col_function text, + is_aggregate smallint, + resultset_id integer, + custom integer, + description text, + targetfieldname character varying(255) +); + + +CREATE TABLE tmp_rpta_column2layout ( + tid integer, + column_id integer, + layout_id integer, + sortnr smallint, + is_visible smallint, + visible_size smallint, + targetfieldname character varying(255), + caption character varying(255), + description text, + format_code character varying(255), + format_code_id integer +); + + + diff --git a/src-modules/module/etl/schluesseltabellen/etl_manager_tab.unl b/src-modules/module/etl/schluesseltabellen/etl_manager_tab.unl index 95da8bf..be21f5c 100644 --- a/src-modules/module/etl/schluesseltabellen/etl_manager_tab.unl +++ b/src-modules/module/etl/schluesseltabellen/etl_manager_tab.unl @@ -1,3 +1,4 @@ 1^MASK^Masken^0^sx_select_mask^sx_insert_mask^TID^42000^42006^1^ 2^SICHT^Sichten^0^sichten_unload^sichten_upload^SYSTEMINFO_ID^42000^42004^1^ 3^QA_PROJECT^Testfälle^0^qa_project_unload^qa_project_upload^QA_PROJECT_ID^42000^42007^1^ +4^RPTA_COLUMN_LAYOUT^Spaltenlayouts^0^rpta_column_layout_unload^rpta_column_layout_upload^RPTA_COLUMN_LAYOUT_TID^42000^42008^1^ diff --git a/src-modules/module/etl/schluesseltabellen/etl_step_fuellen.sql b/src-modules/module/etl/schluesseltabellen/etl_step_fuellen.sql index 5cf0f51..0eb01fe 100644 --- a/src-modules/module/etl/schluesseltabellen/etl_step_fuellen.sql +++ b/src-modules/module/etl/schluesseltabellen/etl_step_fuellen.sql @@ -10,7 +10,9 @@ {"uniquename":"sichten_unload", "name":"Sichten entladen", "systeminfo_id":270 ,"logfile":""}, {"uniquename":"sichten_upload", "name":"Sichten hochladen", "systeminfo_id":270 ,"logfile":""}, {"uniquename":"sos_gewichtung_unload", "name":"Gewichtungen entladen", "systeminfo_id":270 ,"logfile":""}, - {"uniquename":"qa_project_unload", "name":"Testfallprojekte entladen", "systeminfo_id":260 ,"logfile":""} + {"uniquename":"qa_project_unload", "name":"Testfallprojekte entladen", "systeminfo_id":260 ,"logfile":""}, + {"uniquename":"rpta_column_layout_unload", "name":"Spaltenlayout entladen", "systeminfo_id":330 ,"logfile":""}, + {"uniquename":"rpta_column_layout_upload", "name":"Spaltenlayout hochladen", "systeminfo_id":330 ,"logfile":""} ] /> @@ -40,6 +42,15 @@ {"etl_job":"qa_project_unload","param_name":"QA_PROJECT_ID", "name":"Testfall-Projekt", "param_default":""}, {"etl_job":"qa_project_unload","param_name":"PATH_TO_OUTPUTFILE", "name":"Ausgabedatei", "param_default":"$SUPERX_DIR/db/masken/qa_project_$QA_PROJECT_ID.xml"}, {"etl_job":"qa_project_unload","param_name":"FORMAT", "name":"Ausgabeformat", "param_default":"XML"}, + + {"etl_job":"rpta_column_layout_unload","param_name":"RPTA_COLUMN_LAYOUT_TID", "name":"Spaltenlayout", "param_default":""}, + {"etl_job":"rpta_column_layout_unload","param_name":"PATH_TO_OUTPUTFILE", "name":"Ausgabedatei", "param_default":"$SUPERX_DIR/db/masken/rpta_column_layout_$RPTA_COLUMN_LAYOUT_UNIQUENAME.xml"}, + {"etl_job":"rpta_column_layout_unload","param_name":"FORMAT", "name":"Ausgabeformat", "param_default":"XML"}, + + {"etl_job":"rpta_column_layout_upload","param_name":"SYSTEMINFO_ID", "name":"Komponente", "param_default":""}, + {"etl_job":"rpta_column_layout_upload","param_name":"RPTA_COLUMN_LAYOUT_TID", "name":"ID", "param_default":""}, + {"etl_job":"rpta_column_layout_upload","param_name":"PATH_TO_INPUTFILE", "name":"Eingabedatei", "param_default":""}, + {"etl_job":"rpta_column_layout_upload","param_name":"FORMAT", "name":"Format", "param_default":"XML"}, {"etl_job":"sos_gewichtung_unload","param_name":"SYSTEMINFO_ID", "name":"Komponente", "param_default":""}, {"etl_job":"sos_gewichtung_unload","param_name":"PATH_TO_OUTPUTFILE", "name":"Ausgabedatei", "param_default":"$SUPERX_DIR/db/db/module/sos/schluesseltabellen/sichten_$SYSTEMINFO_ID.xml"}, @@ -108,8 +119,20 @@ {"etl_job":"qa_project_unload", "uniquename":"unload_qa_dbtest2project_tab", "name":"DB-Test zu Projekt entladen", "type":"UNLOAD", "parent":"qa_project_unload_ges"}, {"etl_job":"qa_project_unload", "uniquename":"unload_qa_mask_execution_tab", "name":"Masken-Tests entladen", "type":"UNLOAD", "parent":"qa_project_unload_ges"}, {"etl_job":"qa_project_unload", "uniquename":"unload_qa_mask_execution_assert_tab", "name":"Masken-Test Erwartungen entladen", "type":"UNLOAD", "parent":"qa_project_unload_ges"}, - {"etl_job":"qa_project_unload", "uniquename":"unload_qa_mask_execution2project_tab", "name":"Masken-Test zu Projekt entladen", "type":"UNLOAD", "parent":"qa_project_unload_ges"} - + {"etl_job":"qa_project_unload", "uniquename":"unload_qa_mask_execution2project_tab", "name":"Masken-Test zu Projekt entladen", "type":"UNLOAD", "parent":"qa_project_unload_ges"}, + + {"etl_job":"rpta_column_layout_unload", "uniquename":"rpta_column_layout_unload_ges", "name":"Spaltenlayout-Projekt entladen", "type":"MSG"}, + {"etl_job":"rpta_column_layout_unload", "uniquename":"unload_rpta_resultset_tab", "name":"Resultset entladen", "type":"UNLOAD", "parent":"rpta_column_layout_unload_ges"}, + {"etl_job":"rpta_column_layout_unload", "uniquename":"unload_rpta_column_layout_tab", "name":"Spaltenlayout entladen", "type":"UNLOAD", "parent":"rpta_column_layout_unload_ges"}, + {"etl_job":"rpta_column_layout_unload", "uniquename":"unload_rpta_column_tab", "name":"Spalten entladen", "type":"UNLOAD", "parent":"rpta_column_layout_unload_ges"}, + {"etl_job":"rpta_column_layout_unload", "uniquename":"unload_rpta_column2layout_tab", "name":"Spalten zu Layout entladen", "type":"UNLOAD", "parent":"rpta_column_layout_unload_ges"}, + + {"etl_job":"rpta_column_layout_upload", "uniquename":"create_tmp_rpta_column_layout", "name":"Tabelle tmp_rpta_column_layout erzeugen", "type":"DOSQL" }, + {"etl_job":"rpta_column_layout_upload", "uniquename":"upload_rpta_resultset_tab", "name":"tmp_rpta_resultset hochladen", "type":"LOAD" }, + {"etl_job":"rpta_column_layout_upload", "uniquename":"upload_rpta_column_layout_tab", "name":"tmp_rpta_column_layout hochladen", "type":"LOAD" }, + {"etl_job":"rpta_column_layout_upload", "uniquename":"upload_rpta_column_tab", "name":"tmp_rpta_column hochladen", "type":"LOAD" }, + {"etl_job":"rpta_column_layout_upload", "uniquename":"upload_rpta_column2layout_tab", "name":"tmp_rpta_column2layout hochladen", "type":"LOAD" }, + {"etl_job":"rpta_column_layout_upload", "uniquename":"trans_rpta_column_layout", "name":"rpta_column_layout füllen", "type":"DOSQL" } ] /> <#assign etl_step_properties = [ @@ -202,14 +225,42 @@ {"etl_step":"unload_sos_gewichtung_ges","prop_name":"msg", "prop_value":"Entlade Gewichtungen Komponente $SYSTEMINFO_ID" }, {"etl_step":"unload_sos_gewichtung","prop_name":"select_stmt", "prop_value":" SELECT art, ch35_ang_abschluss, fach_nr, kz_fach, text, faktor FROM sos_gewichtung where ch35_ang_abschluss in (''B5'',''B6'',''B7'',''B8'',''M3'',''M4'',''M7'',''M8'') and art=''vzae'' order by 1,2,3,4,5 ;" }, - {"etl_step":"unload_qa_project","prop_name":"msg", "prop_value":"Entlade Testfall-Projekt $QA_PROJECT_ID Stammdaten" }, + {"etl_step":"qa_project_unload_ges","prop_name":"msg", "prop_value":"Entlade Testfall-Projekt $QA_PROJECT_ID Stammdaten" }, {"etl_step":"unload_qa_project_tab","prop_name":"select_stmt", "prop_value":"SELECT uniquename, name, systeminfo_id, sachgebiete_id, active, created_from, issue_link FROM qa_project where tid= $QA_PROJECT_ID order by 1;" }, {"etl_step":"unload_qa_resultset_tab","prop_name":"select_stmt", "prop_value":"SELECT R.uniquename, R.name, R.systeminfo_id, R.fromclause, R.fieldclause, R.groupbyclause, R.orderbyclause FROM qa_resultset R where R.tid in (select distinct T.resultset_id from qa_dbtest T, qa_dbtest2project P where P.dbtest_id=T.tid and P.project_id= $QA_PROJECT_ID ) order by 1;" }, {"etl_step":"unload_qa_dbtest_tab","prop_name":"select_stmt", "prop_value":"SELECT T.uniquename,T.name,T.systeminfo_id,R.uniquename as resultset_uniquename,T.whereclause,T.description,T.active from qa_dbtest T,qa_resultset R where R.tid=T.resultset_id and T.tid in (select P.dbtest_id from qa_dbtest2project P where P.project_id= $QA_PROJECT_ID ) order by 1;" }, {"etl_step":"unload_qa_dbtest_assertion_tab","prop_name":"select_stmt", "prop_value":"SELECT T.uniquename as dbtest_uniquename,A.rownr,A.def_col_caption,A.def_col_name,A.def_col_value,A.def_col_function from qa_dbtest T, qa_dbtest_assertion A where A.dbtest_id=T.tid and T.tid in (select P.dbtest_id from qa_dbtest2project P where P.project_id= $QA_PROJECT_ID ) order by 1;" }, {"etl_step":"unload_qa_dbtest2project_tab","prop_name":"select_stmt", "prop_value":"SELECT T.uniquename as dbtest_uniquename,P.uniquename as project_uniquename,DP.issue_id FROM qa_dbtest2project DP, qa_dbtest T, qa_project P where DP.dbtest_id=T.tid and DP.project_id=P.tid and DP.project_id= $QA_PROJECT_ID order by 1;" }, + {"etl_step":"unload_rpta_column_layout_ges","prop_name":"msg", "prop_value":"Entlade Spaltenlayout $RPTA_COLUMN_LAYOUT_TID Stammdaten" }, + {"etl_step":"unload_rpta_resultset_tab","prop_name":"select_stmt", "prop_value":"SELECT R.* from rpta_resultset R where R.tid in (select L.resultset_id from rpta_column_layout L where L.tid= $RPTA_COLUMN_LAYOUT_TID ) order by 1;" }, + {"etl_step":"unload_rpta_column_layout_tab","prop_name":"select_stmt", "prop_value":"SELECT L.*,R.uniquename as resultset_uniquename from rpta_column_layout L, rpta_resultset R where R.tid=L.resultset_id and L.tid= $RPTA_COLUMN_LAYOUT_TID order by 1;" }, + {"etl_step":"unload_rpta_column_tab","prop_name":"select_stmt", "prop_value":"select * from rpta_column where tid in (select column_id from rpta_column2layout L where L.layout_id = $RPTA_COLUMN_LAYOUT_TID ) order by 1;" }, + {"etl_step":"unload_rpta_column2layout_tab","prop_name":"select_stmt", "prop_value":"select * from rpta_column2layout L where L.layout_id = $RPTA_COLUMN_LAYOUT_TID order by 1;" }, + + {"etl_step":"create_tmp_rpta_column_layout","prop_name":"PATH_TO_INPUTFILE", "prop_value":"$SUPERX_DIR/db/module/etl/schluesseltabellen/create_load_etl_rpta_column_layout.sql" }, + {"etl_step":"upload_rpta_resultset_tab","prop_name":"target_table", "prop_value":"tmp_rpta_resultset" }, + {"etl_step":"upload_rpta_resultset_tab","prop_name":"format", "prop_value":"xml" }, + {"etl_step":"upload_rpta_resultset_tab","prop_name":"search_path", "prop_value":"/etlAction/unload [@name=\"unload_rpta_resultset_tab\"]/rs/row" }, + {"etl_step":"upload_rpta_resultset_tab","prop_name":"path_to_inputfile", "prop_value":"$PATH_TO_INPUTFILE" }, + + {"etl_step":"upload_rpta_column_layout_tab","prop_name":"target_table", "prop_value":"tmp_etl_rpta_column_layout" }, + {"etl_step":"upload_rpta_column_layout_tab","prop_name":"format", "prop_value":"xml" }, + {"etl_step":"upload_rpta_column_layout_tab","prop_name":"search_path", "prop_value":"/etlAction/unload [@name=\"unload_rpta_column_layout_tab\"]/rs/row" }, + {"etl_step":"upload_rpta_column_layout_tab","prop_name":"path_to_inputfile", "prop_value":"$PATH_TO_INPUTFILE" }, + + {"etl_step":"upload_rpta_column_tab","prop_name":"target_table", "prop_value":"tmp_rpta_column" }, + {"etl_step":"upload_rpta_column_tab","prop_name":"format", "prop_value":"xml" }, + {"etl_step":"upload_rpta_column_tab","prop_name":"search_path", "prop_value":"/etlAction/unload [@name=\"unload_rpta_column_tab\"]/rs/row" }, + {"etl_step":"upload_rpta_column_tab","prop_name":"path_to_inputfile", "prop_value":"$PATH_TO_INPUTFILE" }, + + {"etl_step":"upload_rpta_column2layout_tab","prop_name":"target_table", "prop_value":"tmp_rpta_column2layout" }, + {"etl_step":"upload_rpta_column2layout_tab","prop_name":"format", "prop_value":"xml" }, + {"etl_step":"upload_rpta_column2layout_tab","prop_name":"search_path", "prop_value":"/etlAction/unload [@name=\"unload_rpta_column2layout_tab\"]/rs/row" }, + {"etl_step":"upload_rpta_column2layout_tab","prop_name":"path_to_inputfile", "prop_value":"$PATH_TO_INPUTFILE" }, + {"etl_step":"trans_rpta_column_layout","prop_name":"PATH_TO_INPUTFILE", "prop_value":"$SUPERX_DIR/db/module/etl/schluesseltabellen/trans_rpta_column_layout.sql" }, + {"etl_step":"unload_qa_mask_execution_tab","prop_name":"select_stmt", "prop_value":"SELECT E.name,E.userinfo_id,E.maskeninfo_id,E.is_active,E.stylesheet_id,E.contenttype,E.output_filename,E.systeminfo_id,E.uniquename FROM qa_mask_execution E where E.tid in (select P.mask_execution_id from qa_mask_execution2project P where P.project_id= $QA_PROJECT_ID ) order by 1;" }, {"etl_step":"unload_qa_mask_execution_assert_tab","prop_name":"select_stmt", "prop_value":"SELECT E.uniquename,A.rownr,A.colnr,A.result_value_min,A.result_value_max,A.is_active,A.caption FROM qa_mask_execution E, qa_mask_execution_assert A where E.tid=A.mask_execution_id and E.tid in (select P.mask_execution_id from qa_mask_execution2project P where P.project_id= $QA_PROJECT_ID ) order by 1;" }, {"etl_step":"unload_qa_mask_execution2project_tab","prop_name":"select_stmt", "prop_value":"SELECT E.uniquename as mask_execution_uniquename,P.uniquename as project_uniquename,DP.issue_id FROM qa_mask_execution2project DP, qa_mask_execution E, qa_project P where DP.mask_execution_id=E.tid and DP.project_id=P.tid and DP.project_id= $QA_PROJECT_ID order by 1;" } diff --git a/src-modules/module/etl/schluesseltabellen/trans_rpta_column_layout.sql b/src-modules/module/etl/schluesseltabellen/trans_rpta_column_layout.sql new file mode 100644 index 0000000..085863f --- /dev/null +++ b/src-modules/module/etl/schluesseltabellen/trans_rpta_column_layout.sql @@ -0,0 +1,40 @@ +--freemarker template +<#include "SQL_lingua_franca"/> +<#include "SuperX_general"/> +<#include "RPTA-Makros"/> + + + +select uniquename, +caption, +resultset_uniquename as rpta_resultset, +whereclause, +description, +sortclause, +is_virtual +from tmp_etl_rpta_column_layout; + + +select C.uniquename, +null::varchar(255) as caption, +C.caption as caption_der_spalte, +L.caption as caption_in_ergebnistabelle, +C.srcfieldname, +C.targetfieldname, +T.uniquename as column_type, +C.col_function, +L.is_visible, +L.visible_size, +C.is_aggregate, +null::varchar(255) as description, +L.format_code, +C.description as description_der_spalte, +L.description as description_in_ergebnistabelle +from tmp_rpta_column C, tmp_rpta_column2layout L, rpta_column_type T +where L.column_id=C.tid +and T.tid=C.column_type + + + + +<@rpta_column_layout_fuellen /> diff --git a/src/de/superx/elt/EtlFmParser.java b/src/de/superx/elt/EtlFmParser.java new file mode 100644 index 0000000..50a1177 --- /dev/null +++ b/src/de/superx/elt/EtlFmParser.java @@ -0,0 +1,137 @@ +package de.superx.elt; +import static de.superx.servlet.SxSQL_Server.DEFAULT_MANDANTEN_ID; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.DatabaseMetaData; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import de.memtext.db.ConnectionCreator; +import de.memtext.util.DateUtils; +import de.memtext.util.GetOpts; +import de.memtext.util.StringUtils; +import de.superx.common.DBServletException; +import de.superx.common.FieldContainer; +import de.superx.common.Sichten; +import de.superx.common.StandaloneSicht; +import de.superx.common.SuperX_el; +import de.superx.common.SxResultRow; +import de.superx.common.SxResultSet; +import de.superx.common.SxSqlHelper; +import de.superx.common.SxUser; +import de.superx.common.TableFieldExists; +import de.superx.common.TemplateProcessor; +import de.superx.servlet.SuperXManager; +import de.superx.servlet.SxPools; +import de.superx.servlet.SxSQL_Server; +import de.superx.util.PropsReader; +import de.superx.util.SqlStringUtils; + +public class EtlFmParser extends TemplateProcessor { + private String dbprop, infile, outfile; + private Properties props; + + private Statement stm; + private String isSimpleParser; + private static String sqlDialect; + + EtlFmParser(String mandantenID, Connection con) { + super(mandantenID,con); + + } + + + + private void initConAndParser() throws IOException, SQLException, + ClassNotFoundException { + + stm = con.createStatement(); + if(SqlStringUtils.tableExists(con,"fm_templates",DEFAULT_MANDANTEN_ID)) + { + setTemplates(readFromDb("select trim(both from id),content from fm_templates")); + repositoryToMap(readFromDb(REPOSITORY_SELECT), repositoryMap); + } + if(SqlStringUtils.tableExists(con,"konstanten",DEFAULT_MANDANTEN_ID)) + { + SxResultSet rs = readFromDb("select trim(both from beschreibung),apnr from konstanten"); + for (Iterator it = rs.iterator(); it.hasNext();) { + SxResultRow row = (SxResultRow) it.next(); + String beschreibung = (String) row.get(0); + + repositoryMap.put("K_" + beschreibung.trim(), row.get(1)); + } + } + } + + + + protected SxResultSet readFromDb(String sql) throws SQLException { + SuperX_el el = new SuperX_el(); + + SxSqlHelper sh=new SxSqlHelper(); + sh.execute(sql, this.con, el); + + + if (el.getError_String() != null + && !el.getError_String().trim().equals("")) + throw new SQLException("\nProblem bei:" + "\n\n Meldung:" + + el.getError_String() + "\n sql:" + sql); + + return el.getResultSet(); + + + } + + + + + + + + + /* + * Einfacher Parser für Fremddatenbanken, nur sqlDialect wird übergeben wird + * von DOSQL direkt aufgerufen + */ + public String simpleParser( String input) + throws FileNotFoundException, IOException, Exception { + String output = ""; + sqlDialect = "Postgres";// de.superx.util.SqlStringUtils.getSqlDialect(props .getProperty("driverName")); + initConAndParser(); + HashMap map = new HashMap(); + try { + output = "--automatically created by SuperX/Freemarker for " + + sqlDialect + + " (" + + DateUtils.getTodayString() + + " " + + DateUtils.getNowString() + + ")\n" + + process("FM-Parsing ", input, map, + sqlDialect); + + } catch (Exception e) { + System.err.println("Fehler beim FM-Parsen "); + e.printStackTrace(); + System.exit(1); + } + return output; + + } + + } + + // Created on 08.12.2006 at 18:03:46 + + + diff --git a/src/de/superx/elt/SqlExecutor.java b/src/de/superx/elt/SqlExecutor.java index 439d804..370a8d2 100644 --- a/src/de/superx/elt/SqlExecutor.java +++ b/src/de/superx/elt/SqlExecutor.java @@ -252,7 +252,11 @@ public class SqlExecutor { else { //Kommandozeile: TODO hier sind noch keine FM Scripte mit SQLVAR möglich: - sqlScript=FMParser.simpleParser(mySxConnection.getPropfile(), sqlScript); + //FMParser myParser=new FMParser() + Connection con = mySxConnection.getConnection(); + EtlFmParser myParser=new EtlFmParser("default",con); + + sqlScript=myParser.simpleParser(sqlScript); } String keepGenerated=System.getProperty("FreemarkerKeepGenerated"); if(keepGenerated!=null && keepGenerated.equalsIgnoreCase("true")) diff --git a/superx/WEB-INF/lib/superx-etl.jar b/superx/WEB-INF/lib/superx-etl.jar index dffd3b2964fde783eb23c0d462d562b1e12bc12e..9e37524d770d9235fba955b4d5282ee5e0af1d34 100644 GIT binary patch delta 8539 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 diff --git a/superx/images/resultset_up.svg b/superx/images/resultset_up.svg new file mode 100644 index 0000000..cd63395 --- /dev/null +++ b/superx/images/resultset_up.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + +