/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.jdbc.data; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.jdbc.JdbcPlugin; import org.teiid.designer.jdbc.JdbcUtil; /** * A class into which results from JDBC methods can be placed. This class is not * thread-safe, so it must not be used simultaneously from multiple threads. * * @since 8.0 */ public class Response { private static final int NUM_COLUMNS_NOT_SET = -1; private final Request request; private final List records; private int numColumns; private ResultsMetadata metadata; /** * Construct an instance of Response * */ public Response( final Request request ) { CoreArgCheck.isNotNull(request); this.request = request; this.records = new LinkedList(); this.numColumns = NUM_COLUMNS_NOT_SET; this.metadata = null; } /** * Return the metadata for this results object. * @return the result metadata; never null */ public ResultsMetadata getMetadata() { return this.metadata; } protected void setResultsMetadata( final ResultsMetadata metadata ) { this.metadata = metadata; } // public void addColumn( final ColumnMetadata metadata ) { // } public void addRecord( final List record ) { // Set the number of columns if ( this.numColumns == NUM_COLUMNS_NOT_SET ) { this.numColumns = record.size(); } else { // Otherwise the number of columns have already been set, // so ensure the record has the same number of columns ... CoreArgCheck.isTrue(record.size() == this.numColumns, JdbcPlugin.Util.getString("Response.Add_error_column_count_mismatch",record,new Integer(this.numColumns))); //$NON-NLS-1$ } this.records.add(record); } public List getRecords() { return this.records; } public int getColumnCount() { return this.numColumns; } /** * @return */ public Request getRequest() { return request; } public static void addResults( final Response results, final ResultSet resultSet, final boolean addMetadata ) throws SQLException { addResults(results, resultSet, addMetadata, null); } public static void addResults( final Response results, final ResultSet resultSet, final boolean addMetadata, TupleValidator validator ) throws SQLException { final ResultSetMetaData metadata = resultSet.getMetaData(); final int numColumns = metadata.getColumnCount(); while ( resultSet.next() ) { final List tuple = new ArrayList(numColumns); for ( int i=1;i<=numColumns;++i ) { final Object cell = resultSet.getObject(i); // index starts at 1!!! tuple.add(cell); } if(validator == null || validator.isTupleValid(tuple)) { results.addRecord(tuple); } } if ( addMetadata ) { // Try to do this, but don't fail if we can't (some drivers have very poor // support for result set metadata, and we'd don't want to stop working // with the actual metadata, so do this in a try/catch ... try { // Put the result set metadata into the Response ... final ResultsMetadata resultsMetadata = ResultsMetadata.create(metadata); results.setResultsMetadata(resultsMetadata); } catch (SQLException e) { // Must not have been able to get the result set metadata ... final IStatus error = JdbcUtil.createIStatus(e); if ( error != null ) { results.getRequest().addProblems(Collections.singletonList(error)); } JdbcPlugin.Util.log(e); } } // If there are warnings, add to the request ... SQLWarning warning = resultSet.getWarnings(); if ( warning != null ) { final List warnings = new ArrayList(); while ( warning != null ) { warnings.add(JdbcUtil.createIStatus(warning)); warning = warning.getNextWarning(); } if ( warnings.size() != 0 ) { results.getRequest().addProblems(warnings); } } } public static void addResults( final Response results, final Object result, final boolean addMetadata ) { // The actual result ... final List tuple = new ArrayList(1); tuple.add(result); results.addRecord(tuple); if ( addMetadata ) { // Put the result set metadata into the Response ... final ResultsMetadata metadata = new ResultsMetadata(); results.setResultsMetadata(metadata); } } }