Skip to content

Instantly share code, notes, and snippets.

@imgen
Last active March 11, 2022 09:47
Show Gist options
  • Save imgen/5243577 to your computer and use it in GitHub Desktop.
Save imgen/5243577 to your computer and use it in GitHub Desktop.
A list backed result set
package org.sprocky.util;
import org.apache.commons.lang3.ArrayUtils;
import org.sprocky.NameMappingConvention;
import org.sprocky.ResultSetColumn;
import org.sprocky.ResultSetColumnIgnore;
import org.sprocky.impl.DefaultNameMappingConvention;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.sprocky.util.MiscUtils.*;
/**
* Author: Imgen
*/
public class ListBackedResultSet<T> implements ResultSet {
private List<T> data;
private HashMap<String, Field> columnNameToFieldMap;
private T currentItem;
private int currentIndex = -1;
private Field[] fields;
public ListBackedResultSet(List<T> data,
Class<T> type,
NameMappingConvention nameMappingConvention) {
this.data = data;
buildColumnNameToFieldMap(type, nameMappingConvention);
}
public ListBackedResultSet(List<T> data, Class<T> type) {
this(data, type, null);
}
private void buildColumnNameToFieldMap(Class<?> type, NameMappingConvention nameMappingConvention) {
this.fields = getApplicableFields(type);
nameMappingConvention = nameMappingConvention != null?
nameMappingConvention : new DefaultNameMappingConvention();
this.columnNameToFieldMap = new HashMap<String, Field>(this.fields.length);
for (Field field: this.fields) {
String columnName;
if (field.isAnnotationPresent(ResultSetColumnIgnore.class)) {
continue;
}
if (field.isAnnotationPresent(ResultSetColumn.class)) {
ResultSetColumn resultSetColumn = field.getAnnotation(ResultSetColumn.class);
columnName = resultSetColumn.name();
} else {
columnName = nameMappingConvention.fromFieldToResultSetColumn(field);
}
this.columnNameToFieldMap.put(columnName, field);
}
}
@Override
public boolean next() throws SQLException {
currentIndex++;
if (hasNext()) {
this.currentItem = this.data.get(currentIndex);
}
return hasNext();
}
private boolean hasNext() {
return currentIndex <this.data.size();
}
@Override
public Object getObject(String columnLabel) throws SQLException {
if (!hasNext() || !columnNameToFieldMap.containsKey(columnLabel)) {
return null;
}
Field field = columnNameToFieldMap.get(columnLabel);
return getFieldValue(field);
}
@Override
public Object getObject(int columnIndex) throws SQLException {
if (!hasNext() || columnIndex > this.fields.length) {
return null;
}
Field field = this.fields[columnIndex - 1];
return getFieldValue(field);
}
private Object getFieldValue(Field field) {
try {
field.setAccessible(true);
Object value = field.get(this.currentItem);
Class<?> fieldType = field.getType();
if (value != null) {
if (fieldType == java.util.Date.class) {
// We return java.sql.Date value instead for that that is what a SQL Date type will be
// mapped to shall this be a real ResultSet returned from DB
value = utilDateToSqlDate((java.util.Date)value);
}
if (fieldType == Byte[].class) {
// We return byte[] value instead for that that is what a SQL Date type will be mapped
// to shall this be a real ResultSet returned from DB
value = ArrayUtils.toPrimitive((Byte[]) value);
}
}
return value;
} catch (IllegalAccessException e) {
// We swallow it
return null;
}
}
/**
* The rest of the interface
*/
}
@CarmeloPrimiceri
Copy link

Hello,
I need a ResultSet implementation exactly like the one you made. Can I ask if you want to share all the classes in the sprocky package?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment