/* * Copyright © 2014 Cask Data, Inc. * * 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 co.cask.cdap.explore.jdbc; import co.cask.cdap.explore.client.ExploreExecutionResult; import co.cask.cdap.explore.service.ExploreException; import co.cask.cdap.proto.ColumnDesc; import co.cask.cdap.proto.QueryResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.List; /** * Result set created by an {@link ExploreStatement}, containing the results of a query made to the Explore service. */ public class ExploreResultSet extends BaseExploreResultSet { private static final Logger LOG = LoggerFactory.getLogger(ExploreResultSet.class); private QueryResult currentRow; private int nextRowNb = 1; private ExploreResultSetMetaData metaData; private ExploreStatement statement; private int maxRows = 0; private ExploreExecutionResult executionResult; ExploreResultSet(ExploreExecutionResult executionResult, ExploreStatement statement, int maxRows) throws SQLException { this(executionResult, statement.getFetchSize()); this.statement = statement; this.maxRows = maxRows; } public ExploreResultSet(ExploreExecutionResult executionResult, int fetchSize) throws SQLException { this.executionResult = executionResult; setFetchSize(fetchSize); } @Override public boolean next() throws SQLException { if (isClosed()) { throw new SQLException("ResultSet is closed"); } boolean res = (maxRows <= 0 || nextRowNb <= maxRows) && executionResult.hasNext(); if (res) { nextRowNb++; currentRow = executionResult.next(); } return res; } @Override public void close() throws SQLException { if (isClosed()) { // No-op return; } try { executionResult.close(); if (statement != null) { statement.closeClientOperation(); } } catch (IOException e) { LOG.error("Could not close the query results", e); throw new SQLException(e); } finally { executionResult = null; statement = null; setIsClosed(true); } } @Override public ResultSetMetaData getMetaData() throws SQLException { if (isClosed()) { throw new SQLException("Resultset is closed"); } if (metaData == null) { try { List<ColumnDesc> columnDescs = executionResult.getResultSchema(); metaData = new ExploreResultSetMetaData(columnDescs); } catch (ExploreException e) { LOG.error("Caught exception", e); throw new SQLException(e); } } return metaData; } @Override public Object getObject(int columnIndex) throws SQLException { if (isClosed()) { throw new SQLException("ResultSet is closed"); } if (currentRow == null) { throw new SQLException("No row found."); } List<Object> columns = currentRow.getColumns(); if (columns.isEmpty()) { throw new SQLException("RowSet does not contain any columns!"); } if (columnIndex < 1 || columnIndex > columns.size()) { throw new SQLException("Invalid columnIndex: " + columnIndex); } int columnType = getMetaData().getColumnType(columnIndex); try { Object evaluated = evaluate(columnType, columns.get(columnIndex - 1)); setWasNull(evaluated == null); return evaluated; } catch (Exception e) { e.printStackTrace(); throw new SQLException("Unrecognized column type:" + columnType, e); } } @Override public int findColumn(String name) throws SQLException { if (isClosed()) { throw new SQLException("Resultset is closed"); } if (metaData == null) { getMetaData(); } // Column names are case insensitive, as per the ResultSet interface javadoc return metaData.getColumnPosition(name.toLowerCase()); } @Override public void setFetchSize(int rows) throws SQLException { if (isClosed()) { throw new SQLException("Resultset is closed"); } executionResult.setFetchSize(rows); } @Override public int getFetchSize() throws SQLException { if (isClosed()) { throw new SQLException("Resultset is closed"); } return executionResult.getFetchSize(); } }