package org.ovirt.engine.core.dao;
import java.sql.Array;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
import javax.inject.Inject;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.CustomMapSqlParameterSource;
import org.ovirt.engine.core.dal.dbbroker.DbEngineDialect;
import org.ovirt.engine.core.dal.dbbroker.SimpleJdbcCallsHandler;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public abstract class BaseDao {
protected static final String SEPARATOR = ",";
@Inject
private JdbcTemplate jdbcTemplate;
@Inject
private DbEngineDialect dbEngineDialect;
@Inject
private SimpleJdbcCallsHandler callsHandler;
public BaseDao() {
}
protected JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
protected DbEngineDialect getDialect() {
return dbEngineDialect;
}
protected CustomMapSqlParameterSource getCustomMapSqlParameterSource() {
return new CustomMapSqlParameterSource(getDialect());
}
protected Array createArrayOf(String typeName, Object[] array) {
try (Connection connection = getJdbcTemplate().getDataSource().getConnection()) {
return connection.createArrayOf(typeName, array);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
protected Array createArrayOfUUIDs(Collection<Guid> guids) {
UUID[] uuids = guids.stream().map(Guid::getUuid).toArray(UUID[]::new);
return createArrayOf("uuid", uuids);
}
/**
* @return A generic {@link Guid} result mapper which always takes the {@link Guid} result, regardless of how it's
* column is called.
*/
protected RowMapper<Guid> createGuidMapper() {
return (rs, rowNum) -> new Guid((UUID) rs.getObject(1));
}
protected SimpleJdbcCallsHandler getCallsHandler() {
return callsHandler;
}
/**
* Returns a Double or a null if the column was NULL.
* @param resultSet the ResultSet to extract the result from
* @return a Double or null
*/
public static Double getDouble(ResultSet resultSet, String columnName) throws SQLException {
if (resultSet.getDouble(columnName) == 0 && resultSet.wasNull()) {
return null;
} else {
return resultSet.getDouble(columnName);
}
}
/**
* Returns a Long or a null if the column was NULL.
* @param resultSet the ResultSet to extract the result from
* @return a Long or null
*/
public static Long getLong(ResultSet resultSet, String columnName) throws SQLException {
if (resultSet.getLong(columnName) == 0 && resultSet.wasNull()) {
return null;
} else {
return resultSet.getLong(columnName);
}
}
/**
* Returns a Integer or a null if the column was NULL.
* @param resultSet the ResultSet to extract the result from
* @return a Integer or null
*/
protected static Integer getInteger(ResultSet resultSet, String columnName) throws SQLException {
Integer value = resultSet.getInt(columnName);
return resultSet.wasNull() ? null : value;
}
/**
* Returns a {@link Guid} representing the column's value or a default value if the column was {@code null}.
*
* <b>Note:</b> Postgres' driver returns a {@link UUID} when {@link ResultSet#getObject(String)} is called on a
* uuid column. This behavior is trusted to work with Postgres 8.x and above and is used to achieve the best
* performance. If it is ever broken on Postgres' side, this method should be rewritten.
*
* @param resultSet the ResultSet to extract the result from.
* @param columnName the name of the column.
* @param defaultValue The value to return if the column is {@code null}.
* @return a {@link Guid} representing the UUID in the column, or the default value if it was {@code null}.
* @throws SQLException If resultSet does not contain columnName or its value cannot be cast to {@link UUID}.
*/
private static Guid getGuid(ResultSet resultSet, String columnName, Guid defaultValue) throws SQLException {
UUID uuid = (UUID) resultSet.getObject(columnName);
if (uuid == null || resultSet.wasNull()) {
return defaultValue;
}
return new Guid(uuid);
}
/**
* Returns a {@link Guid} representing the column's value or a {@code null}
* if the column was {@code null}.
*
* @param resultSet the ResultSet to extract the result from.
* @param columnName the name of the column.
* @return a {@link Guid} representing the UUID in the column, or the default value if it was {@code null}.
* @throws SQLException If resultSet does not contain columnName or its value cannot be cast to {@link UUID}.
*/
protected static Guid getGuid(ResultSet resultSet, String columnName) throws SQLException {
return getGuid(resultSet, columnName, null);
}
/**
* Returns a {@link Guid} representing the column's value or a {@link Guid#Empty}
* if the column was {@code null}.
*
* @param resultSet the ResultSet to extract the result from.
* @param columnName the name of the column.
* @return a {@link Guid} representing the UUID in the column, or the default value if it was {@code null}.
* @throws SQLException If resultSet does not contain columnName or its value cannot be cast to {@link UUID}.
*/
protected static Guid getGuidDefaultEmpty(ResultSet resultSet, String columnName) throws SQLException {
return getGuid(resultSet, columnName, Guid.Empty);
}
/**
* Returns a {@link Guid} representing the column's value or a {@link Guid#newGuid()}
* if the column was {@code null}.
*
* @param resultSet the ResultSet to extract the result from.
* @param columnName the name of the column.
* @return a {@link Guid} representing the UUID in the column, or the default value if it was {@code null}.
* @throws SQLException If resultSet does not contain columnName or its value cannot be cast to {@link UUID}.
*/
protected static Guid getGuidDefaultNewGuid(ResultSet resultSet, String columnName) throws SQLException {
return getGuid(resultSet, columnName, Guid.newGuid());
}
protected static ArrayList<String> split(String str) {
if (StringUtils.isEmpty(str)) {
return null;
}
return new ArrayList<>(Arrays.asList(str.split(SEPARATOR)));
}
}