Java tutorial
/* * Copyright 2013 Marcelo Morales me@marcelomorales.name * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package name.marcelomorales.siqisiqi.bonecp; import com.google.inject.*; import com.google.inject.name.Names; import com.jolbox.bonecp.Statistics; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.junit.Test; import javax.inject.Inject; import javax.inject.Named; import javax.sql.DataSource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import static org.junit.Assert.*; /** * @author Marcelo Morales */ public class DataSourceProviderTest { @Test public void testOneDatabase() throws Exception { Config config = ConfigFactory.load(); DataSourceProvider dsp = new DataSourceProvider(config); dsp.getBoneCPConfig().setAcquireRetryDelayInMs(2000); DataSource dataSource = dsp.get(); Connection connection = dataSource.getConnection(); DatabaseMetaData metaData = connection.getMetaData(); assertEquals("Apache Derby", metaData.getDatabaseProductName()); connection.close(); dsp.close(); } @Test public void testRobustAgainstMisuse() throws Exception { Config config = ConfigFactory.load(); DataSourceProvider dsp = new DataSourceProvider(config); assertSame(dsp.get(), dsp.get()); dsp.close(); } @Test public void testStatistics() throws Exception { Config config = ConfigFactory.parseString("bonecp.url=\"jdbc:derby:memory:dbstats;create=true\"") .withFallback(ConfigFactory.load()); DataSourceProvider dsp = new DataSourceProvider(config); assertNull(dsp.getStatistics()); DataSource dataSource = dsp.get(); Connection connection = dataSource.getConnection(); connection.createStatement().execute("CREATE TABLE TABLETEST1 (ACOLUMN VARCHAR(10))"); connection.commit(); QueryRunner queryRunner = new QueryRunner(); queryRunner.update(connection, "INSERT INTO TABLETEST1 VALUES ('AAA')"); queryRunner.update(connection, "INSERT INTO TABLETEST1 VALUES (?)", "BBB"); queryRunner.update(connection, "INSERT INTO TABLETEST1 VALUES (?)", "CCC"); connection.commit(); List<String> values = queryRunner.query(connection, "SELECT * FROM TABLETEST1 ORDER BY ACOLUMN ASC", new ColumnListHandler<String>()); connection.commit(); connection.close(); assertEquals("AAA", values.get(0)); assertEquals("BBB", values.get(1)); assertEquals("CCC", values.get(2)); Statistics statistics = dsp.getStatistics(); assertTrue(statistics.getCacheHits() > 0); assertTrue(statistics.getCacheMiss() > 0); assertEquals(1, statistics.getConnectionsRequested()); assertEquals(4, statistics.getStatementsPrepared()); dsp.close(); } @Test public void testWithDependencyInjector() throws Exception { Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bind(Config.class).toInstance(ConfigFactory.load()); bind(DataSourceProvider.class).in(Scopes.SINGLETON); bind(DataSource.class).toProvider(DataSourceProvider.class).in(Scopes.SINGLETON); } }); DataSource dataSource = injector.getInstance(DataSource.class); Connection connection = dataSource.getConnection(); DatabaseMetaData metaData = connection.getMetaData(); assertEquals("Apache Derby", metaData.getDatabaseProductName()); connection.close(); injector.getInstance(DataSourceProvider.class).close(); } @Test public void testTwoDatabasesWithDependencyInjection() throws Exception { class SpecificDatabase extends PrivateModule { private final String db; public SpecificDatabase(String db) { this.db = db; } @Override protected void configure() { // note there is a database2.conf in the classpath pointing to two different databases Config config = ConfigFactory.load("database2").withFallback(ConfigFactory.load()); Config specificDbConf = config.getConfig(db).withFallback(config); bind(Config.class).toInstance(specificDbConf); bind(DataSourceProvider.class).in(Scopes.SINGLETON); bind(DataSourceProvider.class).annotatedWith(Names.named(db)).to(DataSourceProvider.class); bind(DataSource.class).annotatedWith(Names.named(db)).toProvider(DataSourceProvider.class) .in(Scopes.SINGLETON); expose(DataSourceProvider.class).annotatedWith(Names.named(db)); expose(DataSource.class).annotatedWith(Names.named(db)); } } Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { install(new SpecificDatabase("db1")); install(new SpecificDatabase("db2")); } }); injector.getInstance(DoWithTwoDatabases.class).doIt(); injector.getInstance(Key.get(DataSourceProvider.class, Names.named("db1"))).close(); injector.getInstance(Key.get(DataSourceProvider.class, Names.named("db2"))).close(); } public static class DoWithTwoDatabases { private final DataSource dataSource1; private final DataSource dataSource2; @Inject public DoWithTwoDatabases(@Named("db1") DataSource dataSource1, @Named("db2") DataSource dataSource2) { this.dataSource1 = dataSource1; this.dataSource2 = dataSource2; } public void doIt() throws SQLException { Connection connection1 = dataSource1.getConnection(); connection1.createStatement().execute("CREATE TABLE TABLETEST1 (ACOLUMN VARCHAR(10))"); connection1.commit(); connection1.close(); // Now one database has the table while the other does not. Connection connection2 = dataSource2.getConnection(); ResultSet tableTest2 = connection2.getMetaData().getTables(null, null, "TABLETEST1", null); assertFalse(tableTest2.next()); tableTest2.close(); connection2.commit(); connection2.close(); Connection connection3 = dataSource1.getConnection(); ResultSet tableTest3 = connection3.getMetaData().getTables(null, null, "TABLETEST1", null); assertTrue(tableTest3.next()); tableTest3.close(); connection3.commit(); connection3.close(); } } }