All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.unitils.database.sqlassert.SqlAssert Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2011, Unitils.org
 * 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 org.unitils.database.sqlassert;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.unitils.core.Unitils;
import org.unitils.core.UnitilsException;
import org.unitils.database.DataSourceWrapper;
import org.unitils.database.DatabaseModule;
import org.unitils.database.SQLUnitils;
import org.unitils.reflectionassert.ReflectionAssert;
import org.unitils.reflectionassert.ReflectionComparatorMode;

import static org.unitils.thirdparty.org.apache.commons.dbutils.DbUtils.closeQuietly;

/**
 * Assertion class to verify content in the database, by specifying your own SQL and checking the result.
 * todo td refactor
 *
 * @author Jeroen Horemans
 */
public abstract class SqlAssert {

    /* The logger instance for this class */
    private static Logger logger = LoggerFactory.getLogger(SqlAssert.class);

    /**
     * To be succesfull the result of the SQL should only return one row, this row should be identical to the given parameter. The sequence
     * of the values is not important.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertSingleRowSqlResult(String sql, String[] row) {
        assertSingleRowSqlResult(sql, "", row);
    }

    /**
     * To be succesfull the result of the SQL should only return one row, this row should be identical to the given parameter. The sequence
     * of the values is not important.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertSingleRowSqlResult(String sql, String databaseName, String[] row) {
        assertSingleRowSqlResult(sql, getDataSourceFromUnitils(databaseName), row);
    }

    /**
     * To be succesfull the result of the SQL should return as many rows as the two dimensional arrey has, each row should be identical to
     * the given parameter. The sequence of the values is not important nor is the order of the rows.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertMultipleRowSqlResult(String sql, String databaseName, String[]... rows) {
        assertMultipleRowSqlResult(sql, getDataSourceFromUnitils(databaseName), rows);
    }

    /**
     * To be succesfull the result of the SQL should return as many rows as the two dimensional arrey has, each row should be identical to
     * the given parameter. The sequence of the values is not important nor is the order of the rows.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertMultipleRowSqlResult(String sql, String[]... rows) {
        assertMultipleRowSqlResult(sql, "", rows);
    }

    /**
     * The SQL given should only return one row with one column, this column should be a number (preferred a count(*)). The result is
     * asserted with the countResult parameter.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertCountSqlResult(String sql, Long countResult) {
        assertCountSqlResult(sql, countResult, "");
    }

    /**
     * The SQL given should only return one row with one column, this column should be a number (preferred a count(*)). The result is
     * asserted with the countResult parameter.
     * The datasource will be fetched from the database module of unitils ({@link DatabaseModule}).
     */
    public static void assertCountSqlResult(String sql, Long countResult, String databaseName) {
        assertCountSqlResult(sql, getDataSourceFromUnitils(databaseName), countResult);
    }

    /**
     * To be successful the result of the SQL should only return one row, this row should be identical to the given parameter. The sequence
     * of the values is not important.
     */
    public static void assertSingleRowSqlResult(String sql, DataSource dataSource, String[] row) {
        assertMultipleRowSqlResult(sql, dataSource, new String[][] {
            row
        });
    }

    /**
     * To be successful the result of the SQL should return as many rows as the two dimensional array has, each row should be identical to
     * the given parameter. The sequence of the values is not important nor the order of the rows.
     */
    public static void assertMultipleRowSqlResult(String sql, DataSource dataSource, String[]... rows) {
        String[][] itemAsString = getItemAsString(sql, dataSource, rows[0].length);
        ReflectionAssert.assertReflectionEquals(rows, itemAsString, ReflectionComparatorMode.LENIENT_ORDER);
    }

    /**
     * The SQL given should only return one row with one column, this column should be a number (preferred a count(*)). The result is
     * asserted with the countResult parameter.
     */
    public static void assertCountSqlResult(String sql, DataSource dataSource, Long countResult) {
        Long itemAsLong = SQLUnitils.getItemAsLong(sql, dataSource);
        // we use the reflection assert because it would throw the same error ass the other functions of this class. When using the default
        // assertion from junit a assertion error from a different package is thrown
        ReflectionAssert.assertReflectionEquals(countResult, itemAsLong);
    }

    /**
     * Returns the value extracted from the result of the given query. If no value is found, a {@link UnitilsException} is thrown.
     *
     * @param sql
     *     The sql string for retrieving the items
     * @param dataSource
     *     The data source, not null
     * @return The string item value
     */
    protected static String[][] getItemAsString(String sql, DataSource dataSource, Integer columnCount) {
        logger.debug(sql);

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = dataSource.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            ArrayList resultList = new ArrayList<>();

            while (resultSet.next()) {
                String[] row = new String[columnCount];
                for (int i = 1; i <= columnCount; i++) {
                    row[i - 1] = resultSet.getString(i);
                }
                resultList.add(row);
            }
            return resultList.toArray(new String[][] {
                {}
            });
        } catch (Exception e) {
            throw new UnitilsException("Error while executing statement: " + sql, e);
        } finally {
            closeQuietly(connection, statement, resultSet);
        }
    }

    /**
     * Returns the {@link DataSource} fetched from the unitils {@link DatabaseModule}
     *
     * @return DataSource
     */
    private static DataSource getDataSourceFromUnitils(String databaseName) {
        Unitils unitils = Unitils.getInstance();
        DataSourceWrapper wrapper = unitils.getModulesRepository().getModuleOfType(DatabaseModule.class).getWrapper(databaseName);
        DataSource dataSource = wrapper.getTransactionalDataSourceAndActivateTransactionIfNeeded(unitils.getTestContext().getTestObject());
        return dataSource;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy