/* * Copyright (C) 2013 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.common.dao.empiredb; import cz.cas.lib.proarc.common.dao.Transaction; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.apache.empire.db.DBCommand; import org.dbunit.DatabaseUnitException; import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatDtdDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory; import org.dbunit.operation.DatabaseOperation; import org.junit.Assert; import org.junit.Assume; /** * * @author Jan Pokorsky */ public class DbUnitSupport { private final EmpireConfiguration emireCfg; private static String dtdSchema; public DbUnitSupport() { Assume.assumeNotNull(System.getProperty("proarc-common.DbUnitSupport.jdbc.user")); emireCfg = new EmpireConfiguration( System.getProperty("proarc-common.DbUnitSupport.jdbc.driver"), System.getProperty("proarc-common.DbUnitSupport.jdbc.url"), System.getProperty("proarc-common.DbUnitSupport.jdbc.user"), System.getProperty("proarc-common.DbUnitSupport.jdbc.passwd"), System.getProperty("proarc-common.DbUnitSupport.empiredb.driver"), null ); } public EmpireConfiguration getEmireCfg() { return emireCfg; } public IDatabaseConnection getConnection(Transaction tx) throws DatabaseUnitException, SQLException { return getConnection(getSqlConnection(tx)); } public IDatabaseConnection getConnection() throws DatabaseUnitException, SQLException { return getConnection(emireCfg.getConnection()); } public IDatabaseConnection getConnection(Connection c) throws DatabaseUnitException, SQLException { return createProgresConnection(c); } public Connection getSqlConnection(Transaction tx) { return ((SqlTransaction) tx).getConnection(); } private IDatabaseConnection createProgresConnection(Connection c) throws DatabaseUnitException { DatabaseConnection dbc = new DatabaseConnection(c); DatabaseConfig config = dbc.getConfig(); config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new PostgresqlDataTypeFactory()); // Progress cannot handle columns names like XML thus we have to escape them. config.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, "\"?\""); config.setProperty(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, false); return dbc; } public IDataSet loadFlatXmlDataStream(Class<?> c, String resource) throws Exception { return loadFlatXmlDataStream(c, resource, false); } public IDataSet loadFlatXmlDataStream(Class<?> c, String resource, boolean resetDtdSchema) throws Exception { FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); builder.setMetaDataSetFromDtd(getDtdSchema(resetDtdSchema)); // builder.setMetaDataSet(getConnection().createDataSet()); FlatXmlDataSet fds = builder.build(getResourceStream(c, resource)); return fds; } /** initializes sequences after DBUnit inserts */ public void initSequences(Transaction tx, int startWith, String... sqnName) throws Exception { initSequences(getSqlConnection(tx), startWith, sqnName); } public void initSequences(Connection c, int startWith, String... sqnName) throws Exception { Statement stmt = c.createStatement(); for (String name : sqnName) { String sql = String.format("ALTER SEQUENCE %s RESTART WITH %s", name, startWith); System.out.println(sql); stmt.execute(sql); } } public void cleanInsert(IDatabaseConnection c, IDataSet dataset) throws Exception { prepareForDelete(c.getConnection()); DatabaseOperation.CLEAN_INSERT.execute(c, dataset); } /** * Removes all constrained values that cannot be resolved with proper delete table order. */ public void prepareForDelete(Connection c) { ProarcDatabase schema = getEmireCfg().getSchema(); DBCommand cmd = schema.createCommand(); cmd.set(schema.tableUser.defaultGroup.to(null)); cmd.set(schema.tableUser.userGroup.to(null)); schema.executeUpdate(cmd, c); } private InputStream getResourceStream(Class<?> c, String resource) { InputStream stream = c.getResourceAsStream(resource); Assert.assertNotNull("stream.name: " + resource + ", class: " + c, stream); return stream; } public void clearDtdSchema() { dtdSchema = null; } private Reader getDtdSchema(boolean resetDtdSchema) throws Exception { if (resetDtdSchema || dtdSchema == null) { Connection c = getEmireCfg().getConnection(); try { IDatabaseConnection dc = createProgresConnection(c); StringWriter sw = new StringWriter(); FlatDtdDataSet.write(dc.createDataSet(), sw); dtdSchema = sw.toString(); // System.out.println(dtdSchema); } finally { c.close(); } } return new StringReader(dtdSchema); } }