package org.realityforge.jeo.geolatte.jpa; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; final class DatabaseTestUtil { private static final String URL_KEY = "javax.persistence.jdbc.url"; private static final String DRIVER_KEY = "javax.persistence.jdbc.driver"; private static final String USER_KEY = "javax.persistence.jdbc.user"; private static final String PASSWORD_KEY = "javax.persistence.jdbc.password"; private DatabaseTestUtil() { } private static Properties initDatabaseProperties( final boolean postgres, final boolean control ) { final Properties properties = new Properties(); final String defaultURL; if ( postgres ) { properties.put( DRIVER_KEY, "org.postgresql.Driver" ); defaultURL = "jdbc:postgresql://127.0.0.1:5432"; } else { properties.put( DRIVER_KEY, "net.sourceforge.jtds.jdbc.Driver" ); properties.put( "eclipselink.ddl-generation", "drop-and-create-tables" ); defaultURL = "jdbc:jtds:sqlserver://127.0.0.1:1432/"; } final String baseURL = System.getProperty( "test.db.base_url", defaultURL ); final String databaseUrl = baseURL + "/" + ( control ? ( postgres ? "postgres" : "master" ) : "geolatte_test" ); setProperty( properties, URL_KEY, "test.db.url", databaseUrl ); setProperty( properties, USER_KEY, "test.db.user", "postgres" ); setProperty( properties, PASSWORD_KEY, "test.db.password", null ); return properties; } private static void setProperty( final Properties properties, final String key, final String systemPropertyKey, final String defaultValue ) { final String value = System.getProperty( systemPropertyKey, defaultValue ); if ( null != value ) { properties.put( key, value ); } } static EntityManager createEntityManager( final boolean postgres, final String persistenceUnitName ) { final Properties properties = initDatabaseProperties( postgres, false ); final EntityManagerFactory factory = Persistence.createEntityManagerFactory( persistenceUnitName, properties ); return factory.createEntityManager(); } static void setupDatabase( final boolean postgres ) throws Exception { try { tearDownDatabase( postgres ); } catch ( Exception e ) { //Ignore } final Connection connection = initConnection( postgres, true ); try { execute( connection, "CREATE DATABASE geolatte_test" ); } finally { disposeConnection( connection ); } if ( postgres ) { final Connection connection2 = initConnection( postgres, false ); try { execute( connection2, "CREATE EXTENSION postgis" ); } finally { disposeConnection( connection2 ); } } } static void tearDownDatabase( final boolean postgres ) throws Exception { final Connection connection = initConnection( postgres, true ); try { if ( "PostgreSQL Native Driver".equals( connection.getMetaData().getDriverName() ) ) { // Post 9.1 terminate option final int majorVersion = connection.getMetaData().getDatabaseMajorVersion(); final int minorVersion = connection.getMetaData().getDatabaseMinorVersion(); final int version = majorVersion * 100 + minorVersion; if ( version >= 902 ) { execute( connection, "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'geolatte_test'" ); } else { execute( connection, "SELECT pg_terminate_backend(pg_stat_activity.procpid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'geolatte_test'" ); } } execute( connection, "DROP DATABASE geolatte_test" ); } finally { disposeConnection( connection ); } } private static void execute( final Connection connection, final String sql ) throws SQLException { final Statement statement = connection.createStatement(); statement.execute( sql ); statement.close(); } private static void disposeConnection( final Connection connection ) { if ( null != connection ) { try { connection.close(); } catch ( final Exception e ) { throw new IllegalStateException( e.getMessage(), e ); } } } private static Connection initConnection( final boolean postgres, final boolean control ) { final Properties properties = initDatabaseProperties( postgres, control ); try { Class.forName( properties.getProperty( DRIVER_KEY ) ); } catch ( final Exception e ) { throw new IllegalStateException( e.getMessage(), e ); } try { return DriverManager.getConnection( properties.getProperty( URL_KEY ), properties.getProperty( USER_KEY ), properties.getProperty( PASSWORD_KEY ) ); } catch ( final Exception e ) { throw new IllegalStateException( e.getMessage(), e ); } } }