Refactor DbUpgradeUtils

- Move database access code to new class DatabaseAccessObject.
    This was done to ease the effort of testing, since
    DbUpgradeUtils has a static API and it is harder to mock
    static things with Mockito.
  - Log exceptions even if ignored
  - Add unit tests for both DbUpgradeUtils and DatabaseAccessObject
  - DbUpgradeUtils.dropTableColumnsIfExist(...) no longer throws
CloudRuntimeException to make it consistent with the other methods in
the class

Signed-off-by: Daan Hoogland <daan@onecht.net>
This commit is contained in:
miguelaferreira 2014-03-04 16:41:20 +01:00 committed by Daan Hoogland
parent 370554e9d9
commit ea0dec77d9
4 changed files with 732 additions and 68 deletions

View File

@ -0,0 +1,99 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.upgrade.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.apache.log4j.Logger;
public class DatabaseAccessObject {
private static Logger s_logger = Logger.getLogger(DatabaseAccessObject.class);
public void dropKey(Connection conn, String tableName, String key, boolean isForeignKey) {
PreparedStatement pstmt = null;
try {
if (isForeignKey) {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + key);
} else {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP KEY " + key);
}
pstmt.executeUpdate();
s_logger.debug("Key " + key + " is dropped successfully from the table " + tableName);
} catch (SQLException e) {
s_logger.warn("Ignored SQL Exception when trying to drop " + (isForeignKey ? "foreign " : "") + "key " + key + " on table " + tableName, e);
} finally {
closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer dropping " + (isForeignKey ? "foreign " : "") + "key " + key
+ " on table " + tableName);
}
}
public void dropPrimaryKey(Connection conn, String tableName) {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP PRIMARY KEY ");
pstmt.executeUpdate();
s_logger.debug("Primary key is dropped successfully from the table " + tableName);
} catch (SQLException e) {
s_logger.warn("Ignored SQL Exception when trying to drop primary key on table " + tableName, e);
} finally {
closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer dropping primary key on table " + tableName);
}
}
public void dropColumn(Connection conn, String tableName, String columnName) {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP COLUMN " + columnName);
pstmt.executeUpdate();
s_logger.debug("Column " + columnName + " is dropped successfully from the table " + tableName);
} catch (SQLException e) {
s_logger.warn("Unable to drop columns using query " + pstmt + " due to exception", e);
} finally {
closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement after dropping column " + columnName + " on table " + tableName);
}
}
public boolean columnExists(Connection conn, String tableName, String columnName) {
boolean columnExists = false;
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement("SELECT " + columnName + " FROM " + tableName);
pstmt.executeQuery();
columnExists = true;
} catch (SQLException e) {
s_logger.warn("Field " + columnName + " doesn't exist in " + tableName, e);
} finally {
closePreparedStatement(pstmt, "Ignored SQL Exception when trying to close PreparedStatement atfer checking if column " + columnName + " existed on table " + tableName);
}
return columnExists;
}
protected static void closePreparedStatement(PreparedStatement pstmt, String errorMessage) {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
s_logger.warn(errorMessage, e);
}
}
}

View File

@ -17,88 +17,28 @@
package com.cloud.upgrade.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.utils.exception.CloudRuntimeException;
public class DbUpgradeUtils {
final static Logger s_logger = Logger.getLogger(DbUpgradeUtils.class);
private static DatabaseAccessObject dao = new DatabaseAccessObject();
public static void dropKeysIfExist(Connection conn, String tableName, List<String> keys, boolean isForeignKey) {
for (String key : keys) {
PreparedStatement pstmt = null;
try {
if (isForeignKey) {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP FOREIGN KEY " + key);
} else {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP KEY " + key);
}
pstmt.executeUpdate();
s_logger.debug("Key " + key + " is dropped successfully from the table " + tableName);
} catch (SQLException e) {
// do nothing here
continue;
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
}
}
dao.dropKey(conn, tableName, key, isForeignKey);
}
}
public static void dropPrimaryKeyIfExists(Connection conn, String tableName) {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP PRIMARY KEY ");
pstmt.executeUpdate();
s_logger.debug("Primary key is dropped successfully from the table " + tableName);
} catch (SQLException e) {
// do nothing here
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
}
}
dao.dropPrimaryKey(conn, tableName);
}
public static void dropTableColumnsIfExist(Connection conn, String tableName, List<String> columns) {
PreparedStatement pstmt = null;
try {
for (String column : columns) {
try {
pstmt = conn.prepareStatement("SELECT " + column + " FROM " + tableName);
pstmt.executeQuery();
} catch (SQLException e) {
// if there is an exception, it means that field doesn't exist, so do nothing here
s_logger.trace("Field " + column + " doesn't exist in " + tableName);
continue;
for (String columnName : columns) {
if (dao.columnExists(conn, tableName, columnName)) {
dao.dropColumn(conn, tableName, columnName);
}
}
}
pstmt = conn.prepareStatement("ALTER TABLE " + tableName + " DROP COLUMN " + column);
pstmt.executeUpdate();
s_logger.debug("Column " + column + " is dropped successfully from the table " + tableName);
}
} catch (SQLException e) {
s_logger.warn("Unable to drop columns using query " + pstmt + " due to exception", e);
throw new CloudRuntimeException("Unable to drop columns due to ", e);
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
}
}
}
}

View File

@ -0,0 +1,463 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.upgrade.dao;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.internal.util.reflection.Whitebox;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class DatabaseAccessObjectTest {
@Mock
private PreparedStatement preparedStatementMock;
@Mock
private Connection connectionMock;
@Mock
private Logger loggerMock;
private final DatabaseAccessObject dao = new DatabaseAccessObject();
@Before
public void setup() {
Whitebox.setInternalState(dao, "s_logger", loggerMock);
}
@Test
public void testDropKey() throws Exception {
when(connectionMock.prepareStatement(contains("DROP KEY"))).thenReturn(preparedStatementMock);
Connection conn = connectionMock;
String tableName = "tableName";
String key = "key";
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).debug(anyString());
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@Test(expected = NullPointerException.class)
public void testDropKeyWhenConnectionIsNull() throws Exception {
Connection conn = null;
String tableName = "tableName";
String key = "key";
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
}
@Test
public void testDropKeyWhenTableNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("null DROP KEY"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
String key = "key";
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropKeyWhenKeyIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("DROP KEY null"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String key = null;
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropKeyWhenKeysAreForeignKeys() throws Exception {
when(connectionMock.prepareStatement(contains("DROP FOREIGN KEY"))).thenReturn(preparedStatementMock);
Connection conn = connectionMock;
String tableName = "tableName";
String key = "key";
boolean isForeignKey = true;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).debug(anyString());
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@Test
public void testDropKeyWhenPrepareStatementResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(any(String.class))).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String key = "key";
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(0)).executeUpdate();
verify(preparedStatementMock, times(0)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropKeyWhenExecuteUpdateResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("DROP KEY"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String key = "key";
boolean isForeignKey = false;
dao.dropKey(conn, tableName, key, isForeignKey);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@SuppressWarnings("static-access")
@Test
public void testClosePreparedStatementWhenPreparedStatementIsNull() throws Exception {
PreparedStatement preparedStatement = null;
String errorMessage = "some message";
dao.closePreparedStatement(preparedStatement, errorMessage);
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@SuppressWarnings("static-access")
@Test
public void testClosePreparedStatementWhenPreparedStatementIsNotNullAndThereIsNoException() throws Exception {
PreparedStatement preparedStatement = preparedStatementMock;
String errorMessage = "some message";
dao.closePreparedStatement(preparedStatement, errorMessage);
verify(preparedStatement, times(1)).close();
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@SuppressWarnings("static-access")
@Test
public void testClosePreparedStatementWhenPreparedStatementIsNotNullAndThereIsException() throws Exception {
SQLException sqlException = new SQLException();
doThrow(sqlException).when(preparedStatementMock).close();
PreparedStatement preparedStatement = preparedStatementMock;
String errorMessage = "some message";
dao.closePreparedStatement(preparedStatement, errorMessage);
verify(preparedStatement, times(1)).close();
verify(loggerMock, times(1)).warn(errorMessage, sqlException);
}
@Test
public void testDropPrimaryKey() throws Exception {
when(connectionMock.prepareStatement(contains("DROP PRIMARY KEY"))).thenReturn(preparedStatementMock);
Connection conn = connectionMock;
String tableName = "tableName";
dao.dropPrimaryKey(conn, tableName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).debug(anyString());
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@Test(expected = NullPointerException.class)
public void testDropPrimaryKeyWhenConnectionIsNull() throws Exception {
Connection conn = null;
String tableName = "tableName";
dao.dropPrimaryKey(conn, tableName);
}
@Test
public void testDropPrimaryKeyWhenTableNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("null DROP PRIMARY KEY"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
dao.dropPrimaryKey(conn, tableName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropPrimaryKeyWhenPrepareStatementResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("DROP PRIMARY KEY"))).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
dao.dropPrimaryKey(conn, tableName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(0)).executeUpdate();
verify(preparedStatementMock, times(0)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropPrimaryKeyWhenExecuteUpdateResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("DROP PRIMARY KEY"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
dao.dropPrimaryKey(conn, tableName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testColumnExists() throws Exception {
when(connectionMock.prepareStatement(contains("SELECT"))).thenReturn(preparedStatementMock);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = "columnName";
dao.columnExists(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeQuery();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@Test(expected = NullPointerException.class)
public void testColumnExistsWhenConnectionIsNull() throws Exception {
Connection conn = null;
String tableName = "tableName";
String columnName = "columnName";
dao.columnExists(conn, tableName, columnName);
}
@Test
public void testColumnExistsWhenTableNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("FROM null"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeQuery()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
String columnName = "columnName";
dao.columnExists(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeQuery();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testColumnExistsWhenColumnNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("SELECT null"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeQuery()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = null;
dao.columnExists(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeQuery();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropColumn() throws Exception {
when(connectionMock.prepareStatement(anyString())).thenReturn(preparedStatementMock);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = "columnName";
dao.dropColumn(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(0)).executeQuery();
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(1)).debug(anyString());
verify(loggerMock, times(0)).warn(anyString(), any(Throwable.class));
}
@Test(expected = NullPointerException.class)
public void testDropColumnWhenConnectionIsNull() throws Exception {
Connection conn = null;
String tableName = "tableName";
String columnName = "columnName";
dao.dropColumn(conn, tableName, columnName);
}
@Test
public void testDropColumnWhenTableNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("ALTER TABLE null"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = null;
String columnName = "columnName";
dao.dropColumn(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropColumnWhenColumnNameIsNull() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(contains("DROP COLUMN null"))).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = null;
dao.dropColumn(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropColumnWhenPrepareStatementResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(anyString())).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = "columnName";
dao.dropColumn(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(0)).executeUpdate();
verify(preparedStatementMock, times(0)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
@Test
public void testDropColumnWhenexecuteUpdateResultsInException() throws Exception {
SQLException sqlException = new SQLException();
when(connectionMock.prepareStatement(anyString())).thenReturn(preparedStatementMock);
when(preparedStatementMock.executeUpdate()).thenThrow(sqlException);
Connection conn = connectionMock;
String tableName = "tableName";
String columnName = "columnName";
dao.dropColumn(conn, tableName, columnName);
verify(connectionMock, times(1)).prepareStatement(anyString());
verify(preparedStatementMock, times(1)).executeUpdate();
verify(preparedStatementMock, times(1)).close();
verify(loggerMock, times(0)).debug(anyString());
verify(loggerMock, times(1)).warn(anyString(), eq(sqlException));
}
}

View File

@ -0,0 +1,162 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 com.cloud.upgrade.dao;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.when;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@RunWith(PowerMockRunner.class)
public class DbUpgradeUtilsTest {
@Mock
private Connection connectionMock;
@Mock
private DatabaseAccessObject daoMock;
@Before
public void setupClass() {
Whitebox.setInternalState(DbUpgradeUtils.class, "dao", daoMock);
}
@Test
public void testDropKeyIfExistWhenNoKeysAreSupplied() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
List<String> keys = new ArrayList<String>();
boolean isForeignKey = false;
DbUpgradeUtils.dropKeysIfExist(conn, tableName, keys, isForeignKey);
verify(daoMock, times(0)).dropKey(eq(conn), eq(tableName), anyString(), eq(isForeignKey));
}
@Test
public void testDropKeyIfExistWhenOneKeysIsSupplied() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
String key = "key";
List<String> keys = Arrays.asList(new String[] {key});
boolean isForeignKey = false;
DbUpgradeUtils.dropKeysIfExist(conn, tableName, keys, isForeignKey);
verify(daoMock, times(1)).dropKey(conn, tableName, key, isForeignKey);
}
@Test
public void testDropKeyIfExistWhenThreeKeysAreSupplied() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
String key1 = "key1";
String key2 = "key2";
List<String> keys = Arrays.asList(new String[] {key1, key2});
boolean isForeignKey = false;
DbUpgradeUtils.dropKeysIfExist(conn, tableName, keys, isForeignKey);
verify(daoMock, times(1)).dropKey(conn, tableName, key1, isForeignKey);
verify(daoMock, times(1)).dropKey(conn, tableName, key2, isForeignKey);
}
@Test
public void testDropPrimaryKey() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
DbUpgradeUtils.dropPrimaryKeyIfExists(conn, tableName);
verify(daoMock, times(1)).dropPrimaryKey(conn, tableName);
}
@Test
public void testDropTableColumnsIfExistWhenNoKeysAreSupplied() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
List<String> columns = new ArrayList<String>();
DbUpgradeUtils.dropTableColumnsIfExist(conn, tableName, columns);
verify(daoMock, times(0)).columnExists(eq(conn), eq(tableName), anyString());
verify(daoMock, times(0)).dropColumn(eq(conn), eq(tableName), anyString());
}
@Test
public void testDropTableColumnsIfExistWhenOneKeysIsSuppliedAndColumnExists() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
String column = "column";
when(daoMock.columnExists(conn, tableName, column)).thenReturn(true);
List<String> columns = Arrays.asList(new String[] {column});
DbUpgradeUtils.dropTableColumnsIfExist(conn, tableName, columns);
verify(daoMock, times(1)).columnExists(conn, tableName, column);
verify(daoMock, times(1)).dropColumn(conn, tableName, column);
}
@Test
public void testDropTableColumnsIfExistWhenOneKeysIsSuppliedAndColumnDoesNotExists() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
String column = "column";
when(daoMock.columnExists(conn, tableName, column)).thenReturn(false);
List<String> columns = Arrays.asList(new String[] {column});
DbUpgradeUtils.dropTableColumnsIfExist(conn, tableName, columns);
verify(daoMock, times(1)).columnExists(conn, tableName, column);
verify(daoMock, times(0)).dropColumn(conn, tableName, column);
}
@Test
public void testDropTableColumnsIfExistWhenThreeKeysAreSuppliedAnOneDoesnotExist() throws Exception {
Connection conn = connectionMock;
String tableName = "tableName";
String column1 = "column1";
String column2 = "column2";
String column3 = "column3";
when(daoMock.columnExists(conn, tableName, column1)).thenReturn(true);
when(daoMock.columnExists(conn, tableName, column2)).thenReturn(false);
when(daoMock.columnExists(conn, tableName, column3)).thenReturn(true);
List<String> keys = Arrays.asList(new String[] {column1, column2, column3});
DbUpgradeUtils.dropTableColumnsIfExist(conn, tableName, keys);
verify(daoMock, times(1)).columnExists(conn, tableName, column1);
verify(daoMock, times(1)).dropColumn(conn, tableName, column1);
verify(daoMock, times(1)).columnExists(conn, tableName, column2);
verify(daoMock, times(0)).dropColumn(conn, tableName, column2);
verify(daoMock, times(1)).columnExists(conn, tableName, column3);
verify(daoMock, times(1)).dropColumn(conn, tableName, column3);
}
}