package ru.yandex.clickhouse.response; import ru.yandex.clickhouse.ClickHouseStatement; import ru.yandex.clickhouse.settings.ClickHouseProperties; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.*; public class ClickHouseScrollableResultSet extends ClickHouseResultSet { private List<ByteFragment[]> lines; public ClickHouseScrollableResultSet(InputStream is, int bufferSize, String db, String table, boolean usesWithTotals, ClickHouseStatement statement, TimeZone timezone, ClickHouseProperties properties) throws IOException { super(is, bufferSize, db, table, usesWithTotals, statement, timezone, properties); lines = new ArrayList<ByteFragment[]>(); } public boolean hasNext() throws SQLException { if(rowNumber < lines.size()) { return true; } return super.hasNext(); } @Override public boolean next() throws SQLException { if(rowNumber < lines.size()) { values = lines.get(rowNumber); nextLine = null; rowNumber += 1; return true; } if (hasNext()) { super.next(); lines.add(values); return true; } else { rowNumber += 1; values = null; nextLine = null; return false; } } ////// @Override public int getType() throws SQLException { return TYPE_SCROLL_INSENSITIVE; } @Override public int getRow() throws SQLException { return rowNumber; } @Override public boolean isBeforeFirst() throws SQLException { return getRow() == 0; } @Override public boolean isAfterLast() throws SQLException { return getRow() > lines.size(); } @Override public boolean isFirst() throws SQLException { return getRow() == 1; } @Override public void beforeFirst() throws SQLException { absolute(0); } @Override public void afterLast() throws SQLException { absolute(-1); next(); } @Override public boolean first() throws SQLException { return absolute(1); } @Override public boolean last() throws SQLException { return absolute(-1); } @Override public boolean absolute(int row) throws SQLException { if(row == 0) { rowNumber = 0; values = null; return false; } else if(row > 0) { if(row <= lines.size()) { rowNumber = row; values = lines.get(row-1); return true; } absolute(lines.size()); while(getRow() < row && hasNext()) { next(); } if(row == getRow()) { return true; } else { next(); return false; } } else { // We have to check the number of total rows while(hasNext()) { next(); } if(-row > lines.size()) { // there is not so many rows // Put the cursor before the first row return absolute(0); } return absolute(lines.size()+1+row); } } @Override public boolean relative(int rows) throws SQLException { int r = getRow()+rows; if(r < 0) { r = 0; } return absolute(r); } @Override public boolean previous() throws SQLException { return relative(-1); } }