package org.togglz.core.repository.jdbc; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.togglz.core.activation.UsernameActivationStrategy; import org.togglz.core.repository.util.DefaultMapSerializer; import org.togglz.core.util.DbUtils; public class SchemaUpdaterTest { @Test public void shouldDetectMissingTable() throws SQLException { Connection connection = createConnection(); try { SchemaUpdater updater = new SchemaUpdater(connection, "TOGGLZ", DefaultMapSerializer.multiline()); assertFalse(updater.doesTableExist()); } finally { DbUtils.closeQuietly(connection); } } @Test public void shouldMigrateToVersion1() throws SQLException { Connection connection = createConnection(); try { SchemaUpdater updater = new SchemaUpdater(connection, "TOGGLZ", DefaultMapSerializer.multiline()); assertFalse(updater.doesTableExist()); updater.migrateToVersion1(); assertTrue(updater.doesTableExist()); assertTrue(querySucceeds(connection, "SELECT FEATURE_NAME FROM TOGGLZ")); } finally { DbUtils.closeQuietly(connection); } } @Test public void shouldDetectVersion1() throws SQLException { Connection connection = createConnection(); try { SchemaUpdater updater = new SchemaUpdater(connection, "TOGGLZ", DefaultMapSerializer.multiline()); assertFalse(updater.doesTableExist()); assertFalse(updater.isSchemaVersion1()); updater.migrateToVersion1(); assertTrue(updater.isSchemaVersion1()); } finally { DbUtils.closeQuietly(connection); } } @Test public void shouldMigrateToVersion2() throws SQLException { Connection connection = createConnection(); try { // create schema version 1 SchemaUpdater updater = new SchemaUpdater(connection, "TOGGLZ", DefaultMapSerializer.multiline()); assertFalse(updater.doesTableExist()); updater.migrateToVersion1(); assertTrue(updater.isSchemaVersion1()); // insert two feature states update(connection, "INSERT INTO TOGGLZ VALUES ('F1', 1, 'ck, admin')"); update(connection, "INSERT INTO TOGGLZ VALUES ('F2', 1, '')"); update(connection, "INSERT INTO TOGGLZ VALUES ('F3', 1, NULL)"); List<Object[]> dataBefore = query(connection, "SELECT FEATURE_NAME, FEATURE_USERS FROM TOGGLZ ORDER BY FEATURE_NAME"); assertEquals(3, dataBefore.size()); assertEquals("F1", dataBefore.get(0)[0]); assertEquals("ck, admin", dataBefore.get(0)[1]); // migrate the schema updater.migrateToVersion2(); // check the new columns are present assertTrue(querySucceeds(connection, "SELECT FEATURE_NAME,STRATEGY_ID,STRATEGY_PARAMS FROM TOGGLZ")); // check the old users column is deleted assertFalse(querySucceeds(connection, "SELECT FEATURE_USERS FROM TOGGLZ")); // check 3 features are there after the migration List<Object[]> dataAfter = query(connection, "SELECT FEATURE_NAME, STRATEGY_ID, STRATEGY_PARAMS FROM TOGGLZ ORDER BY FEATURE_NAME"); assertEquals(3, dataBefore.size()); // first feature is migrated assertEquals("F1", dataAfter.get(0)[0]); assertEquals(UsernameActivationStrategy.ID, dataAfter.get(0)[1]); assertEquals("users=ck, admin", dataAfter.get(0)[2].toString().trim()); // second feature didn't change assertEquals("F2", dataAfter.get(1)[0]); assertEquals(null, dataAfter.get(1)[1]); assertEquals(null, dataAfter.get(1)[2]); // second feature didn't change assertEquals("F3", dataAfter.get(2)[0]); assertEquals(null, dataAfter.get(2)[1]); assertEquals(null, dataAfter.get(2)[2]); } finally { DbUtils.closeQuietly(connection); } } private int update(Connection connection, String sql) throws SQLException { Statement statement = null; try { statement = connection.createStatement(); return statement.executeUpdate(sql); } finally { DbUtils.closeQuietly(statement); } } private List<Object[]> query(Connection connection, String sql) throws SQLException { Statement statement = null; try { statement = connection.createStatement(); ResultSet resultSet = null; try { resultSet = statement.executeQuery(sql); List<Object[]> result = new ArrayList<Object[]>(); while (resultSet.next()) { List<Object> row = new ArrayList<Object>(); for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) { row.add(resultSet.getObject(i + 1)); } result.add(row.toArray()); } return result; } finally { DbUtils.closeQuietly(resultSet); } } finally { DbUtils.closeQuietly(statement); } } private boolean querySucceeds(Connection connection, String sql) { try { query(connection, sql); return true; } catch (SQLException e) { return false; } } private Connection createConnection() throws SQLException { return DriverManager.getConnection("jdbc:h2:mem:", "sa", ""); } }