name.marcelomorales.siqisiqi.bonecp.DataSourceProviderTest.java Source code

Java tutorial

Introduction

Here is the source code for name.marcelomorales.siqisiqi.bonecp.DataSourceProviderTest.java

Source

/*
 * 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();
        }
    }
}