package ch.elexis.data.importer; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.io.IOUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.elexis.arzttarife_schweiz.Messages; import ch.elexis.core.constants.Preferences; import ch.elexis.core.data.activator.CoreHub; import ch.elexis.core.exceptions.PersistenceException; import ch.elexis.core.interfaces.AbstractReferenceDataImporter; import ch.elexis.core.jdt.NonNull; import ch.elexis.core.jdt.Nullable; import ch.elexis.core.ui.importer.div.importers.AccessWrapper; import ch.elexis.core.ui.util.SWTHelper; import ch.elexis.data.Konsultation; import ch.elexis.data.Kontakt; import ch.elexis.data.Leistungsblock; import ch.elexis.data.PersistentObject; import ch.elexis.data.Query; import ch.elexis.data.TarmedKumulation; import ch.elexis.data.TarmedLeistung; import ch.elexis.data.Verrechnet; import ch.rgw.compress.CompEx; import ch.rgw.tools.ExHandler; import ch.rgw.tools.JdbcLink; import ch.rgw.tools.JdbcLink.Stm; import ch.rgw.tools.TimeSpan; import ch.rgw.tools.TimeTool; import com.healthmarketscience.jackcess.Database; public class TarmedReferenceDataImporter extends AbstractReferenceDataImporter { private static final Logger logger = LoggerFactory.getLogger(TarmedReferenceDataImporter.class); private static final String ImportPrefix = "TARMED_IMPORT_"; private JdbcLink pj; private JdbcLink cacheDb = null; // As we have problems parsing dates using the postgresql-JdBC, // we create a temporary H2 DB Stm source, dest; private String lang; private Database mdbDB; private AccessWrapper aw; private String mdbFilename; private Set<String> cachedDbTables = null; private int count = 0; // Our counter for the progress monitor. Twice. Once for Access import, // then real import private boolean updateBlockWarning = false; boolean updateIDs = false; boolean showRestartDialog = true; /** * Only for unit tests! Suppress dialog at end of import */ public void suppressRestartDialog(){ showRestartDialog = false; } @Override public @NonNull Class<?> getReferenceDataTypeResponsibleFor(){ return TarmedLeistung.class; } @Override public int getCurrentVersion(){ return TarmedLeistung.getCurrentVersion(); } @Override public IStatus performImport(@Nullable IProgressMonitor ipm, InputStream input, @Nullable Integer version){ if (ipm == null) { ipm = new NullProgressMonitor(); } // init database connection pj = PersistentObject.getConnection(); cacheDb = new JdbcLink("org.h2.Driver", "jdbc:h2:mem:tarmed_import", "hsql"); cacheDb.connect("", ""); if (openAccessDatabase(ipm, input) != Status.OK_STATUS || deleteCachedAccessTables(ipm) != Status.OK_STATUS || importAllAccessTables(ipm) != Status.OK_STATUS) { mdbDB = null; cachedDbTables = null; return Status.CANCEL_STATUS; } lang = JdbcLink.wrap(CoreHub.localCfg.get(Preferences.ABL_LANGUAGE, "d").toUpperCase()); //$NON-NLS-1$ ipm.subTask(Messages.TarmedImporter_connecting); // always convert ids if there are old ids in the database TarmedLeistung leistung = TarmedLeistung.load("00.0010"); if (leistung.exists()) updateIDs = true; try { source = cacheDb.getStatement(); dest = pj.getStatement(); ipm.subTask(Messages.TarmedImporter_deleteOldData); pj.exec("DELETE FROM TARMED"); //$NON-NLS-1$ pj.exec("DELETE FROM TARMED_DEFINITIONEN"); //$NON-NLS-1$ pj.exec("DELETE FROM TARMED_EXTENSION"); //$NON-NLS-1$ pj.exec("DELETE FROM " + TarmedKumulation.getDBTableName()); //$NON-NLS-1$ ipm.subTask(Messages.TarmedImporter_definitions); importDefinition("ANAESTHESIE", "DIGNI_QUALI", "DIGNI_QUANTI", "LEISTUNG_BLOECKE", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "LEISTUNG_GRUPPEN", "LEISTUNG_TYP", "PFLICHT", "REGEL_EL_ABR", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "SEITE", "SEX", "SPARTE", "ZR_EINHEIT"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ ipm.worked(13); ipm.subTask(Messages.TarmedImporter_chapter); try(ResultSet res = source.query( String.format("SELECT * FROM %sKAPITEL_TEXT WHERE SPRACHE=%s", ImportPrefix, lang))) { while (res != null && res.next()) { String code = res.getString("KNR"); //$NON-NLS-1$ if (code.trim().equals("I")) { //$NON-NLS-1$ continue; } TarmedLeistung tl = TarmedLeistung.load(code); String txt = convert(res, "BEZ_255"); //$NON-NLS-1$ int subcap = code.lastIndexOf('.'); String parent = "NIL"; //$NON-NLS-1$ if (subcap != -1) { parent = code.substring(0, subcap); } if ((!tl.exists()) || (!parent.equals(tl.get("Parent")))) { //$NON-NLS-1$ tl = new TarmedLeistung(code, parent, "", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } if (tl.exists()) { tl.setText(txt); tl.flushExtension(); } ipm.worked(1); } } ipm.subTask(Messages.TarmedImporter_singleLst); ResultSet res = source.query(String.format("SELECT * FROM %sLEISTUNG", ImportPrefix)); //$NON-NLS-1$ PreparedStatement preps_extension = pj.prepareStatement("UPDATE TARMED_EXTENSION SET MED_INTERPRET=?,TECH_INTERPRET=? WHERE CODE=?"); //$NON-NLS-1$ TimeTool validFrom = new TimeTool(); while (res.next() == true) { validFrom.set(res.getString("GUELTIG_VON")); String id = res.getString("LNR") + "-" + validFrom.toString(TimeTool.DATE_COMPACT); //$NON-NLS-1$ TarmedLeistung tl = TarmedLeistung.load(id); if (tl.exists()) { continue; } else { tl = new TarmedLeistung(id, res.getString("LNR"), res.getString("KNR"), //$NON-NLS-1$ "0000", convert(res, "QT_DIGNITAET"), convert(res, "Sparte")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } TimeSpan tsValid = new TimeSpan(new TimeTool(res.getString("GUELTIG_VON")), new TimeTool( res.getString("GUELTIG_BIS"))); logger.debug(tsValid.dump()); tl.set(new String[] { "GueltigVon", "GueltigBis" //$NON-NLS-1$ //$NON-NLS-2$ }, tsValid.from.toString(TimeTool.DATE_COMPACT), tsValid.until.toString(TimeTool.DATE_COMPACT)); //$NON-NLS-1$ //$NON-NLS-2$ Stm stmCached = cacheDb.getStatement(); // get QL_DIGNITAET String dqua = ""; ResultSet rsub = stmCached.query(String.format( "SELECT * FROM %sLEISTUNG_DIGNIQUALI WHERE LNR=%s", ImportPrefix, JdbcLink.wrap(tl.getCode()))); //$NON-NLS-1$ List<Map<String, String>> validResults = getValidValueMaps(rsub, validFrom); if (!validResults.isEmpty()) { dqua = getLatestMap(validResults).get("QL_DIGNITAET"); } rsub.close(); // get BEZ_255, MED_INTERPRET, TECH_INTERPRET String kurz = ""; //$NON-NLS-1$ rsub = stmCached.query(String.format( "SELECT * FROM %sLEISTUNG_TEXT WHERE SPRACHE=%s AND LNR=%s", ImportPrefix, lang, JdbcLink.wrap(tl.getCode()))); //$NON-NLS-1$ validResults = getAllValueMaps(rsub); if (!validResults.isEmpty()) { Map<String, String> row = getLatestMap(validResults); kurz = row.get("BEZ_255"); //$NON-NLS-1$ String med = row.get("MED_INTERPRET"); //$NON-NLS-1$ String tech = row.get("TECH_INTERPRET"); //$NON-NLS-1$ preps_extension.setString(1, med); preps_extension.setString(2, tech); preps_extension.setString(3, tl.getId()); preps_extension.execute(); } rsub.close(); tl.set(new String[] { "DigniQuali", "Text"}, dqua, kurz); //$NON-NLS-1$ //$NON-NLS-2$ Hashtable<String, String> ext = tl.loadExtension(); put(ext, res, "LEISTUNG_TYP", "SEITE", "SEX", "ANAESTHESIE", "K_PFL", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "BEHANDLUNGSART", "TP_AL", "TP_ASSI", "TP_TL", "ANZ_ASSI", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "LSTGIMES_MIN", "VBNB_MIN", "BEFUND_MIN", "RAUM_MIN", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "WECHSEL_MIN", "F_AL", "F_TL"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // get LNR_MASTER rsub = stmCached.query(String.format( "SELECT * FROM %sLEISTUNG_HIERARCHIE WHERE LNR_SLAVE=%s", ImportPrefix, JdbcLink.wrap(tl.getCode()))); //$NON-NLS-1$ validResults = getValidValueMaps(rsub, validFrom); if (!validResults.isEmpty()) { // importing all bezugs ziffer will mess up tarmed bill -> just import 1st // StringBuilder sb = new StringBuilder(); // for (Map<String, String> map : validResults) { // if (sb.length() == 0) // sb.append(map.get("LNR_MASTER")); // else // sb.append(", " + map.get("LNR_MASTER")); // } Map<String, String> what = validResults.get(0); if (what != null) { String content = what.get("LNR_MASTER"); //$NON-NLS-1$ if (content != null) ext.put("Bezug", content); //$NON-NLS-1$ } } rsub.close(); // get LNR_SLAVE, TYP rsub = stmCached.query(String.format( "SELECT * FROM %sLEISTUNG_KOMBINATION WHERE LNR_MASTER=%s", ImportPrefix, JdbcLink.wrap(tl.getCode()))); //$NON-NLS-1$ String kombination_and = ""; //$NON-NLS-1$ String kombination_or = ""; //$NON-NLS-1$ validResults = getValidValueMaps(rsub, validFrom); if (!validResults.isEmpty()) { for (Map<String, String> map : validResults) { String typ = map.get("TYP"); String slave = map.get("LNR_SLAVE"); if (typ != null) { if (typ.equals("and")) { //$NON-NLS-1$ kombination_and += slave + ","; //$NON-NLS-1$ } else if (typ.equals("or")) { //$NON-NLS-1$ kombination_or += slave + ","; //$NON-NLS-1$ } } } } rsub.close(); if (!kombination_and.equals("")) { //$NON-NLS-1$ String k = kombination_and.replaceFirst(",$", ""); //$NON-NLS-1$ //$NON-NLS-2$ ext.put("kombination_and", k); //$NON-NLS-1$ } if (!kombination_or.equals("")) { //$NON-NLS-1$ String k = kombination_or.replaceFirst(",$", ""); //$NON-NLS-1$ //$NON-NLS-2$ ext.put("kombination_or", k); //$NON-NLS-1$ } // get LNR_SLAVE, TYP (invalid combinations with other codes) importKumulations(tl.getCode(), stmCached); // get OPERATOR, MENGE, ZR_ANZAHL, PRO_NACH, ZR_EINHEIT rsub = stmCached.query(String.format( "SELECT * FROM %sLEISTUNG_MENGEN_ZEIT WHERE LNR=%s", ImportPrefix, JdbcLink.wrap(tl.getCode()))); //$NON-NLS-1$ String limits = ""; //$NON-NLS-1$ validResults = getValidValueMaps(rsub, validFrom); if (!validResults.isEmpty()) { for (Map<String, String> map : validResults) { StringBuilder sb = new StringBuilder(); sb.append(map.get("OPERATOR")).append(","); //$NON-NLS-1$ //$NON-NLS-2$ sb.append(map.get("MENGE")).append(","); //$NON-NLS-1$ //$NON-NLS-2$ sb.append(map.get("ZR_ANZAHL")).append(","); //$NON-NLS-1$ //$NON-NLS-2$ sb.append(map.get("PRO_NACH")).append(","); //$NON-NLS-1$ //$NON-NLS-2$ sb.append(map.get("ZR_EINHEIT")).append("#"); //$NON-NLS-1$ //$NON-NLS-2$ limits += sb.toString(); } } rsub.close(); if (!limits.equals("")) { //$NON-NLS-1$ ext.put("limits", limits); //$NON-NLS-1$ } tl.flushExtension(); cacheDb.releaseStatement(stmCached); ipm.worked(1); if (ipm.isCanceled()) { return Status.CANCEL_STATUS; } } res.close(); if (updateIDs) { updateExistingIDs(ipm); } if (version == null) { TarmedLeistung.setVersion(new TimeTool().toString(TimeTool.DATE_COMPACT)); } else { TarmedLeistung.setVersion(version.toString()); } ipm.done(); String message = Messages.TarmedImporter_successMessage; if (updateBlockWarning) { message = message + "\n" + Messages.TarmedImporter_updateBlockWarning; } if (showRestartDialog) { SWTHelper.showInfo(Messages.TarmedImporter_successTitle, message); } return Status.OK_STATUS; } catch (Exception ex) { ex.printStackTrace(); ExHandler.handle(ex); } finally { if (source != null) { pj.releaseStatement(source); } if (dest != null) { pj.releaseStatement(dest); } if (deleteCachedAccessTables(ipm) != Status.OK_STATUS) { mdbDB = null; return Status.CANCEL_STATUS; } mdbDB = null; } return Status.CANCEL_STATUS; } /** * Import all the kumulations from the LEISTUNG_KUMULATION table for the given code. The * kumulations contain inclusions, exclusions and exclusives. * * @param code * of a tarmed value * @param stmCached * @throws SQLException */ private void importKumulations(String code, Stm stmCached) throws SQLException{ try(ResultSet res = stmCached.query(String.format("SELECT * FROM %sLEISTUNG_KUMULATION WHERE LNR_MASTER=%s", ImportPrefix, JdbcLink.wrap(code)))) { TimeTool fromTime = new TimeTool(); TimeTool toTime = new TimeTool(); while (res != null && res.next()) { fromTime.set(res.getString("GUELTIG_VON")); toTime.set(res.getString("GUELTIG_BIS")); new TarmedKumulation(code, res.getString("ART_MASTER"), res.getString("LNR_SLAVE"), res.getString("ART_SLAVE"), res.getString("TYP"), res.getString("ANZEIGE"), res.getString("GUELTIG_SEITE"), fromTime.toString(TimeTool.DATE_COMPACT), toTime.toString(TimeTool.DATE_COMPACT)); } } } /** * Import all Access tables (using cache cachedDbTables) */ private IStatus importAllAccessTables(final IProgressMonitor monitor){ String tablename = ""; double weight = 0.1; // a work unit here is much less work than in the final import Iterator<String> iter; int totRows = 0; try { int nrTables = cachedDbTables.size(); iter = cachedDbTables.iterator(); iter = cachedDbTables.iterator(); while (iter.hasNext()) { tablename = iter.next(); totRows += mdbDB.getTable(tablename).getRowCount(); } monitor.beginTask(Messages.TarmedImporter_importLstg, (int) (totRows * weight) + mdbDB.getTable("LEISTUNG").getRowCount() + mdbDB.getTable("KAPITEL_TEXT").getRowCount()); int j = 0; iter = cachedDbTables.iterator(); while (iter.hasNext()) { j++; tablename = iter.next(); String msg = String.format(Messages.TarmedImporter_convertTable, tablename, ImportPrefix + tablename, j, nrTables, mdbDB.getTable(tablename).getRowCount(), mdbFilename); monitor.subTask(msg); try { int nrRows = aw.convertTable(tablename, cacheDb); monitor.worked((int) (nrRows * weight)); } catch (SQLException e) { logger.error("Failed to import table " + tablename, e); return Status.CANCEL_STATUS; } } return Status.OK_STATUS; } catch (IOException e) { logger.error("Failed to process access file " + mdbFilename, e); return Status.CANCEL_STATUS; } } private IStatus openAccessDatabase(final IProgressMonitor monitor, InputStream inputStream){ File file = convertInputStreamToFile(inputStream); if (mdbFilename == null) mdbFilename = file.getName(); try { aw = new AccessWrapper(file); aw.setPrefixForImportedTableNames(ImportPrefix); mdbDB = Database.open(file, true, Database.DEFAULT_AUTO_SYNC); cachedDbTables = mdbDB.getTableNames(); } catch (IOException e) { logger.error("Failed to open access file " + file, e); return Status.CANCEL_STATUS; } return Status.OK_STATUS; } private IStatus deleteCachedAccessTables(final IProgressMonitor monitor){ String tablename = ""; Iterator<String> iter; iter = cachedDbTables.iterator(); while (iter.hasNext()) { tablename = iter.next(); cacheDb.exec("DROP TABLE IF EXISTS " + tablename);//$NON-NLS-1$ } return Status.OK_STATUS; } private void importDefinition(final String... strings) throws IOException, SQLException{ Stm stm = pj.getStatement(); Stm stmCached = cacheDb.getStatement(); PreparedStatement ps = pj.prepareStatement("INSERT INTO TARMED_DEFINITIONEN (Spalte,Kuerzel,Titel) VALUES (?,?,?)"); //$NON-NLS-1$ try { for (String s : strings) { ResultSet res = stmCached.query(String.format( "SELECT * FROM %sCT_" + s + " WHERE SPRACHE=%s", ImportPrefix, lang)); //$NON-NLS-1$ while (res.next()) { ps.setString(1, s); ps.setString(2, res.getString(1)); ps.setString(3, res.getString(3)); ps.execute(); } res.close(); } } catch (Exception ex) { ExHandler.handle(ex); } finally { pj.releaseStatement(stm); cacheDb.releaseStatement(stmCached); } } private String convert(ResultSet res, String field) throws Exception{ Reader reader = res.getCharacterStream(field); if (reader == null) { return ""; } StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(reader); int c; while ((c = br.read()) != -1) { sb.append((char) c); } return sb.toString(); } private void put(final Hashtable<String, String> h, final ResultSet r, final String... vv) throws Exception{ for (String v : vv) { String val = r.getString(v); if (val != null) { h.put(v, val); } } } private Map<String, String> getLatestMap(List<Map<String, String>> list){ TimeTool currFrom = new TimeTool("19000101"); TimeTool from = new TimeTool(); Map<String, String> ret = null; for (Map<String, String> map : list) { from.set(map.get("GUELTIG_VON")); if (from.isAfter(currFrom)) { currFrom.set(from); ret = map; } } return ret; } /** * Get a List of Maps containing the rows of the ResultSet with a matching valid date * information. This is needed as we can not make constraints on a date represented as string in * the db. * * @param input * @param validFrom * @return * @throws SQLException */ private List<Map<String, String>> getValidValueMaps(ResultSet input, TimeTool validFrom) throws Exception{ List<Map<String, String>> ret = new ArrayList<Map<String, String>>(); // build list of column names ArrayList<String> headers = new ArrayList<String>(); ResultSetMetaData meta = input.getMetaData(); int metaLength = meta.getColumnCount(); for (int i = 1; i <= metaLength; i++) { headers.add(meta.getColumnName(i)); } TimeTool from = new TimeTool(); TimeTool to = new TimeTool(); // find rows with matching valid date information while (input.next()) { from.set(input.getString("GUELTIG_VON")); to.set(input.getString("GUELTIG_BIS")); //$NON-NLS-1$ // is this the correct result if (validFrom.isAfterOrEqual(from) && validFrom.isBeforeOrEqual(to)) { HashMap<String, String> valuesMap = new HashMap<String, String>(); // put all the columns with values into valuesMap for (String columnName : headers) { String value = convert(input, columnName); valuesMap.put(columnName, value); } // add map to list of matching maps ret.add(valuesMap); } } return ret; } /** * Get a List of Maps containing the rows of the ResultSet with a matching valid date * information. This is needed as we can not make constraints on a date represented as string in * the db. * * @param input * @param validFrom * @return * @throws SQLException */ private List<Map<String, String>> getAllValueMaps(ResultSet input) throws Exception{ List<Map<String, String>> ret = new ArrayList<Map<String, String>>(); // build list of column names ArrayList<String> headers = new ArrayList<String>(); ResultSetMetaData meta = input.getMetaData(); int metaLength = meta.getColumnCount(); for (int i = 1; i <= metaLength; i++) { headers.add(meta.getColumnName(i)); } // find rows with matching valid date information while (input.next()) { HashMap<String, String> valuesMap = new HashMap<String, String>(); // put all the columns with values into valuesMap for (String columnName : headers) { String value = convert(input, columnName); valuesMap.put(columnName, value); } // add map to list of matching maps ret.add(valuesMap); } return ret; } void updateExistingIDs(final IProgressMonitor monitor){ PreparedStatement ps = null; // update existing ids of Verrechnet try { ps = pj.prepareStatement("UPDATE " + Verrechnet.TABLENAME + " SET leistg_code=? WHERE id=?"); //$NON-NLS-1$ Query<Verrechnet> vQuery = new Query<Verrechnet>(Verrechnet.class); vQuery.add(Verrechnet.CLASS, "=", TarmedLeistung.class.getName()); List<Verrechnet> verrechnete = vQuery.execute(); for (Verrechnet verrechnet : verrechnete) { // make sure code and date of consultation are available String code = verrechnet.get(Verrechnet.LEISTG_CODE); TimeTool date = null; Konsultation kons = verrechnet.getKons(); if (kons != null && kons.getDatum() != null) date = new TimeTool(kons.getDatum()); if (code != null && date != null) { monitor.subTask(Messages.TarmedImporter_updateVerrechnet + " " + code + " " + date.toString(TimeTool.DATE_COMPACT)); TarmedLeistung leistung = (TarmedLeistung) TarmedLeistung.getFromCode(code, date); // update the id if (leistung != null) { ps.setString(1, leistung.getId()); ps.setString(2, verrechnet.getId()); ps.execute(); } } Thread.yield(); } } catch (SQLException e) { e.printStackTrace(); ExHandler.handle(e); } finally { if (ps != null) { try { ps.close(); } catch (SQLException e) { e.printStackTrace(); ExHandler.handle(e); } } } // update existing ids of Leistungsblock try { Query<Leistungsblock> lQuery = new Query<Leistungsblock>(Leistungsblock.class); List<Leistungsblock> blocks = lQuery.execute(); for (Leistungsblock block : blocks) { StringBuilder newCodes = new StringBuilder(); // get blob byte[] compressed = getBinaryRaw(Leistungsblock.FLD_LEISTUNGEN, Leistungsblock.TABLENAME, block.getId()); if (compressed != null) { // get String representing all contained leistungen String storable = new String(CompEx.expand(compressed), "UTF-8"); //$NON-NLS-1$ // rebuild a String containing all leistungen but update TarmedLeistungen for (String p : storable.split(",")) { if (p != null && !p.isEmpty()) { String[] parts = p.split("::"); if (parts[0].equals(TarmedLeistung.class.getName())) { monitor.subTask(Messages.TarmedImporter_updateBlock + " " + parts[1]); TarmedLeistung leistung = (TarmedLeistung) TarmedLeistung.getFromCode(parts[1]); if (leistung != null) { // add new string if (newCodes.length() > 0) newCodes.append(","); newCodes.append(leistung.storeToString()); } else { updateBlockWarning = true; // set string old string if (newCodes.length() > 0) newCodes.append(","); newCodes.append(p); } } else { if (newCodes.length() > 0) newCodes.append(","); newCodes.append(p); } } } // write the updated String back setBinaryRaw(Leistungsblock.FLD_LEISTUNGEN, Leistungsblock.TABLENAME, block.getId(), CompEx.Compress(newCodes.toString(), CompEx.ZIP)); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); ExHandler.handle(e); } // update existing ids in statistics Query<Kontakt> kQuery = new Query<Kontakt>(Kontakt.class); List<Kontakt> kontakte = kQuery.execute(); for (Kontakt kontakt : kontakte) { Map exi = kontakt.getMap(Kontakt.FLD_EXTINFO); String typ = TarmedLeistung.class.getName(); // get list of type List l = (List) exi.get(typ); if (l != null) { // we dont have access to statL.v member so update is not possible // for (Kontakt.statL statL : l) { // String[] ci = statL.v.split("::"); // if (ci.length == 2) { // TarmedLeistung leistung = // (TarmedLeistung) TarmedLeistung.getFromCode(ci[1]); // if (leistung != null) // statL.v = leistung.storeToString(); // } // } // clear existing statistics l.clear(); exi.put(typ, l); kontakt.setMap(Kontakt.FLD_EXTINFO, exi); } } } /** * Copy of method from PersistentObject to get access to a binary field * * @param field * @return */ private byte[] getBinaryRaw(final String field, String tablename, String id){ StringBuilder sql = new StringBuilder(); sql.append("SELECT ").append(field).append(" FROM ").append(tablename) .append(" WHERE ID='").append(id).append("'"); Stm stm = null; try { stm = pj.getStatement(); ResultSet res = stm.query(sql.toString()); if ((res != null) && (res.next() == true)) { return res.getBytes(field); } } catch (Exception ex) { ExHandler.handle(ex); } finally { if (stm != null) { pj.releaseStatement(stm); } } return null; } /** * Copy of method from PersistentObject to get access to a binary field * * @param field * @return */ private void setBinaryRaw(final String field, String tablename, String id, final byte[] value){ StringBuilder sql = new StringBuilder(1000); sql.append("UPDATE ").append(tablename).append(" SET ").append((field)).append("=?") .append(" WHERE ID='").append(id).append("'"); String cmd = sql.toString(); PreparedStatement stm = pj.prepareStatement(cmd); try { stm.setBytes(1, value); stm.executeUpdate(); } catch (Exception ex) { ex.printStackTrace(); ExHandler.handle(ex); } finally { try { stm.close(); } catch (SQLException e) { ExHandler.handle(e); throw new PersistenceException("Could not close statement " + e.getMessage()); } } } private File convertInputStreamToFile(InputStream input){ String prefix = "tarmed_db"; String suffix = "tmp"; File tmpFile = null; try { tmpFile = File.createTempFile(prefix, suffix); tmpFile.deleteOnExit(); FileOutputStream out = new FileOutputStream(tmpFile); IOUtils.copy(input, out); } catch (IOException e) { logger.error("Error reading input stream ...", e); } return tmpFile; } private void setMdbFilename(String filename){ mdbFilename = filename; } }