package org.hibernate.tools.test.util; import java.io.File; import java.io.FileWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.URL; import java.net.URLClassLoader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.util.Properties; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class JdbcUtilTest { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { clearConnectionTable(); createHibernateProperties("sa", "", "jdbc:h2:mem:test"); setUpClassLoader(); } @After public void tearDown() throws Exception { clearConnectionTable(); restoreClassLoader(); } @Test public void testGetConnectionProperties() throws Exception { Properties properties = JdbcUtil.getConnectionProperties(); Assert.assertEquals("jdbc:h2:mem:test", properties.get("url")); Assert.assertEquals("sa", properties.get("user")); Assert.assertEquals("", properties.get("password")); } @Test public void testEstablishJdbcConnection() throws Exception { Assert.assertNull(JdbcUtil.CONNECTION_TABLE.get(this)); JdbcUtil.establishJdbcConnection(this); Connection connection = JdbcUtil.CONNECTION_TABLE.get(this); Assert.assertFalse(connection.isClosed()); } @Test public void testReleaseJdbcConnection() throws Exception { Connection connection = DriverManager.getConnection("jdbc:h2:mem:test;USER=sa"); JdbcUtil.CONNECTION_TABLE.put(this, connection); Assert.assertNotNull(JdbcUtil.CONNECTION_TABLE.get(this)); Assert.assertFalse(connection.isClosed()); JdbcUtil.releaseJdbcConnection(this); Assert.assertNull(JdbcUtil.CONNECTION_TABLE.get(this)); Assert.assertTrue(connection.isClosed()); } @Test public void testExecuteDDL() throws Exception { Connection connection = DriverManager .getConnection("jdbc:h2:mem:test;USER=sa"); JdbcUtil.CONNECTION_TABLE.put(this, connection); ResultSet resultSet = connection .getMetaData() .getTables(null, null, "FOO", null); Assert.assertFalse(resultSet.next()); String[] sqls = new String[] { "CREATE TABLE FOO (BAR INT)" }; JdbcUtil.executeSql(this, sqls); resultSet = connection .getMetaData() .getTables(null, null, "FOO", null); Assert.assertTrue(resultSet.next()); } @Test public void testToIdentifier() throws Exception { MetaDataInvocationHandler metaDataInvocationHandler = new MetaDataInvocationHandler(); ConnectionInvocationHandler connectionInvocationHandler = new ConnectionInvocationHandler(); connectionInvocationHandler.metaDataInvocationHandler = metaDataInvocationHandler; Connection connection = (Connection)Proxy.newProxyInstance( getClass().getClassLoader(), new Class[] { Connection.class }, connectionInvocationHandler ); JdbcUtil.CONNECTION_TABLE.put(this, connection); metaDataInvocationHandler.whichCase = "MIXED"; Assert.assertEquals("Foo", JdbcUtil.toIdentifier(this, "Foo")); metaDataInvocationHandler.whichCase = "UPPER"; Assert.assertEquals("FOO", JdbcUtil.toIdentifier(this, "Foo")); metaDataInvocationHandler.whichCase = "LOWER"; Assert.assertEquals("foo", JdbcUtil.toIdentifier(this, "Foo")); } @Test public void testIsDatabaseOnline() throws Exception { Assert.assertTrue(JdbcUtil.isDatabaseOnline()); new File(temporaryFolder.getRoot(), "hibernate.properties").delete(); createHibernateProperties("foo", "bar", "jdbc:sqlserver://org.foo.bar:1433"); Assert.assertFalse(JdbcUtil.isDatabaseOnline()); } private void clearConnectionTable() throws Exception { for (Connection c : JdbcUtil.CONNECTION_TABLE.values()) { c.close(); } JdbcUtil.CONNECTION_TABLE.clear(); } private void createHibernateProperties( String user, String password, String url) throws Exception { Properties properties = new Properties(); properties.put("hibernate.connection.username", user); properties.put("hibernate.connection.password", password); properties.put("hibernate.connection.url", url); File outputFolder = temporaryFolder.getRoot(); File propertiesFile = new File(outputFolder, "hibernate.properties"); FileWriter writer = new FileWriter(propertiesFile); properties.store(writer, null); writer.close(); } private void setUpClassLoader() throws Exception { ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader( new URLClassLoader( new URL[] { temporaryFolder.getRoot().toURI().toURL() }, currentClassLoader)); } private void restoreClassLoader() { URLClassLoader currentClassLoader = (URLClassLoader)Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(currentClassLoader.getParent()); } private static class MetaDataInvocationHandler implements InvocationHandler { String whichCase; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if ("storesLowerCaseIdentifiers".equals(methodName)) { return "LOWER".equals(whichCase); } else if ("storesUpperCaseIdentifiers".equals(methodName)) { return "UPPER".equals(whichCase); } else { return false; } } } private static class ConnectionInvocationHandler implements InvocationHandler { InvocationHandler metaDataInvocationHandler; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("getMetaData")) { return (DatabaseMetaData)Proxy.newProxyInstance( getClass().getClassLoader(), new Class[] { DatabaseMetaData.class } , metaDataInvocationHandler); } else { return null; } } } }