/** * junit-rules: JUnit Rules Library * * Copyright (c) 2009-2011 by Alistair A. Israel. * This software is made available under the terms of the MIT License. * * Created May 5, 2011 */ package junit.rules.derby; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import junit.rules.TestFixture; import junit.rules.jdbc.support.DriverManagerDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * It's a JUnit {@link org.junit.Rule} that also masquerades as a JDBC {@link DataSource}. * * @author Alistair.Israel * @since 0.5 */ public class DerbyDataSourceRule extends TestFixture implements DataSource { private static final Logger logger = LoggerFactory.getLogger(DerbyDataSourceRule.class); private final String databaseName; private DataSource dataSource; /** * Instantiates a new Derby DataSource rule. * * @param databaseName * the database name */ public DerbyDataSourceRule(final String databaseName) { this.databaseName = databaseName; } /** * Instantiates a new Derby DataSource rule with the default name ({@code "test"}). */ public DerbyDataSourceRule() { this("test"); } /** * Setup Derby * * @throws Throwable * if setup fails */ @Override protected final void setUp() throws Throwable { logger.debug("setUp()"); final String jdbcUrl = constructJdbcUrl(); logger.debug("Using JDBC URL: " + jdbcUrl); DriverManager.getConnection(jdbcUrl); final DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setJdbcUrl(jdbcUrl); dataSource = ds; logger.info("Initialized Derby database at \"" + jdbcUrl + "\""); } /** * @return the JDBC URL to use */ private String constructJdbcUrl() { return "jdbc:derby:memory:" + databaseName + ";create=true"; } /** * {@inheritDoc} * * @see javax.sql.DataSource#getConnection() */ @Override public final Connection getConnection() throws SQLException { return dataSource.getConnection(); } /** * {@inheritDoc} * * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String) */ @Override public final Connection getConnection(final String username, final String password) throws SQLException { return dataSource.getConnection(username, password); } /** * {@inheritDoc} * * @see javax.sql.CommonDataSource#getLogWriter() */ @Override public final PrintWriter getLogWriter() throws SQLException { return dataSource.getLogWriter(); } /** * {@inheritDoc} * * @see javax.sql.CommonDataSource#getLoginTimeout() */ @Override public final int getLoginTimeout() throws SQLException { return dataSource.getLoginTimeout(); } /** * {@inheritDoc} * * @see javax.sql.CommonDataSource#setLogWriter(java.io.PrintWriter) */ @Override public final void setLogWriter(final PrintWriter out) throws SQLException { dataSource.setLogWriter(out); } /** * {@inheritDoc} * * @see javax.sql.CommonDataSource#setLoginTimeout(int) */ @Override public final void setLoginTimeout(final int seconds) throws SQLException { dataSource.setLoginTimeout(seconds); } /** * {@inheritDoc} * * @see java.sql.Wrapper#isWrapperFor(java.lang.Class) */ @Override public final boolean isWrapperFor(final Class<?> iface) throws SQLException { return dataSource.isWrapperFor(iface); } /** * {@inheritDoc} * * @see java.sql.Wrapper#unwrap(java.lang.Class) */ @Override public final <T> T unwrap(final Class<T> iface) throws SQLException { return dataSource.unwrap(iface); } /** * @param sql * the SQL to execute * @return the number of rows affected * @since 0.5.1 */ public final int execute(final String sql) { try { final Connection conn = dataSource.getConnection(); try { final Statement statement = conn.createStatement(); try { return statement.executeUpdate(sql); } finally { statement.close(); } } finally { conn.close(); } } catch (final SQLException e) { throw new AssertionError(e); } } /** * Don't know where else to put it for now. * * @param tableName * the table name to count * @return the count * @since 0.5.1 */ public final int count(final String tableName) { try { final Connection conn = dataSource.getConnection(); try { final PreparedStatement ps = conn.prepareStatement("SELECT count(*) FROM " + tableName); try { final ResultSet rs = ps.executeQuery(); try { rs.next(); return rs.getInt(1); } finally { rs.close(); } } finally { ps.close(); } } finally { conn.close(); } } catch (final SQLException e) { throw new AssertionError(e); } } }