private static JdbcRowsCollector createRowsCollector()

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;
  }