
scriptella.jdbc.ResultSetAdapter Maven / Gradle / Ivy
/*
* Copyright 2006-2012 The Scriptella Project Team.
*
* 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 scriptella.jdbc;
import scriptella.spi.ParametersCallback;
import scriptella.util.ColumnsMap;
import scriptella.util.IOUtils;
import java.io.Closeable;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* Represents SQL query result set as {@link ParametersCallback}.
* This class exposes pseudo column rownum
-current row number starting at 1.
*
* @author Fyodor Kupolov
* @version 1.0
*/
public class ResultSetAdapter implements ParametersCallback, Closeable {
private ResultSet resultSet;
private ColumnsMap columnsMap;
private ParametersCallback params; //parent parameters callback to use
private JdbcTypesConverter converter;
private int columnsCount;
private int[] jdbcTypes;
/**
* Instantiates an adapter, prepares a cache and builds a map of column names.
*
* @param resultSet resultset to adapt.
* @param parametersCallback parent parameter callback.
* @param converter type converter to use for getting column values as object.
*/
public ResultSetAdapter(ResultSet resultSet,
ParametersCallback parametersCallback, JdbcTypesConverter converter) {
this.params = parametersCallback;
this.resultSet = resultSet;
this.converter = converter;
}
private void initMetaData() {
columnsMap = new ColumnsMap();
try {
final ResultSetMetaData m = resultSet.getMetaData();
columnsCount = m.getColumnCount();
jdbcTypes = new int[columnsCount];
for (int i = 1; i <= columnsCount; i++) {
columnsMap.registerColumn(m.getColumnName(i), i);
columnsMap.registerColumn(m.getColumnLabel(i), i);
jdbcTypes[i-1]=m.getColumnType(i); //Store column types for converter
}
} catch (SQLException e) {
throw new JdbcException("Unable to process result set ", e);
}
}
/**
* @return true if the new current row is valid; false if there are no more rows
* @see java.sql.ResultSet#next()
*/
public boolean next() {
try {
converter.close();
return resultSet.next();
} catch (SQLException e) {
throw new JdbcException("Unable to move cursor to the next row", e);
}
}
public Object getParameter(final String name) {
if (columnsMap==null) { //if first time access
initMetaData();
}
try {
Integer index = columnsMap.find(name);
int ind = index==null?-1:index - 1;
if (ind >= 0 && ind < columnsCount) { //if index found and in range
return converter.getObject(resultSet, ind + 1, jdbcTypes[ind]);
} else { //otherwise call uppper level params
return params.getParameter(name);
}
} catch (SQLException e) {
throw new JdbcException("Unable to get parameter " + name, e);
}
}
/**
* Closes the underlying resultset.
*
This method should operate without raising exceptions.
*/
public void close() {
if (resultSet != null) {
JdbcUtils.closeSilent(resultSet);
IOUtils.closeSilently(converter);
resultSet = null;
params = null;
columnsMap = null;
jdbcTypes=null;
}
}
}