in old/dekaf-core/src/main/java/org/jetbrains/dekaf/jdbc/JdbcIntermediateCursor.java [104:227]
private static <R> JdbcRowsCollector<R> createRowsCollector(final ResultLayout<R> resultLayout,
final ResultSet resultSet,
final String statementText) throws SQLException{
RowLayout<?> rowLayout = resultLayout.row;
int n;
switch (rowLayout.kind) {
case EXISTENCE:
n = 0;
break;
case ONE_VALUE:
n = 1;
break;
default:
n = rowLayout.components.length;
}
final ResultSetMetaData metaData = resultSet.getMetaData();
final int m = metaData.getColumnCount();
final JdbcValueGetter<?>[] getters;
if (n > 0 && rowLayout.kind != RowLayout.Kind.TUPLE && rowLayout.kind != RowLayout.Kind.STRUCT) {
// array with specified components
getters = new JdbcValueGetter[n];
if (n > m && rowLayout.kind == RowLayout.Kind.ARRAY) {
throw new DBPreparingException(format("Query returns too few columns: %d when expected %d (row type is %s).",
m, n, resultLayout.row.rowClass),
statementText);
}
for (int i = 0; i < min(m,n); i++) {
int jdbcType = metaData.getColumnType(i + 1);
getters[i] = JdbcValueGetters.of(jdbcType, rowLayout.components[i].clazz);
}
}
else if (n == 0 && rowLayout.commonComponentClass == Object.class) {
// raw array
getters = new JdbcValueGetter[m];
for (int i = 0; i < m; i++) {
int jdbcType = metaData.getColumnType(i + 1);
getters[i] = JdbcValueGetters.of(jdbcType, Object.class);
}
}
else {
// TODO log somehow?
getters = null;
}
final JdbcRowFetcher<?> fetcher;
switch (rowLayout.kind) {
case EXISTENCE:
fetcher = NOTHING_FETCHER;
break;
case ONE_VALUE:
assert getters != null && getters.length > 0;
fetcher = JdbcRowFetchers.createOneValueFetcher(1, getters[0]);
break;
case ARRAY:
if (rowLayout.commonComponentClass == int.class) {
fetcher = JdbcRowFetchers.createIntArrayFetcher(1);
}
else if (rowLayout.commonComponentClass == long.class) {
fetcher = JdbcRowFetchers.createLongArrayFetcher(1);
}
else {
fetcher = JdbcRowFetchers.createArrayFetcher(1, rowLayout.commonComponentClass, getters);
}
break;
case TUPLE:
fetcher = JdbcRowFetchers.createTupleFetcher(rowLayout.components);
break;
case STRUCT:
fetcher = JdbcRowFetchers.createStructFetcher(rowLayout.rowClass, rowLayout.components);
break;
default:
throw new DBPreparingException(format("Unknown how to handle the row layout %s", rowLayout.kind.toString()),
statementText);
}
final JdbcRowsCollector<?> collector;
switch (resultLayout.kind) {
case EXISTENCE:
collector = JdbcRowsCollectors.createExistenceCollector();
break;
case SINGLE_ROW:
collector = JdbcRowsCollectors.createSingleRowCollector(fetcher);
break;
case ARRAY:
collector = JdbcRowsCollectors.createArrayCollector(fetcher);
break;
case ARRAY_OF_PRIMITIVES:
Class<?> componentClass = resultLayout.row.commonComponentClass;
if (componentClass == int.class) {
collector = JdbcRowsCollectors.createArrayOfIntsCollector(resultLayout.initialCapacity);
}
else if (componentClass == long.class) {
collector = JdbcRowsCollectors.createArrayOfLongsCollector(resultLayout.initialCapacity);
}
else {
throw new DBPreparingException("Primitive array of "+componentClass.getName()+" is not supported",
statementText);
}
break;
case LIST:
collector = JdbcRowsCollectors.createListCollector(fetcher);
break;
case MAP:
if (resultLayout.sorted) {
collector = JdbcRowsCollectors.createHashMapCollector(getters[0], getters[1]);
}
else {
JdbcValueGetter keyGetter = getters[0];
collector = JdbcRowsCollectors.createSortedMapCollector(keyGetter, getters[1]);
}
break;
default:
throw new DBPreparingException(format("Unknown how to handle the result layout %s", resultLayout.kind.toString()),
statementText);
}
//noinspection unchecked
return (JdbcRowsCollector<R>) collector;
}