All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xdev.db.jdbc.JDBCResult Maven / Gradle / Ivy

/*
 * XDEV Application Framework - XDEV Application Framework
 * Copyright © 2003 XDEV Software (https://xdev.software)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */
package xdev.db.jdbc;


import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import xdev.db.ColumnMetaData;
import xdev.db.DBException;
import xdev.db.DataType;
import xdev.db.Result;


/*
 * Modified 2010-02-22 by Thomas Muenz
 * - added a constructor with additional parameter Integer maxRowCount and implemented apropriate logic for it.
 * - added JavaDoc
 * - changed all "throws Exception" to "throws SQLException" 
 *   (completely backward-compatible with existing "catch(Exception e)" calls of this class' methods.
 */
public class JDBCResult extends Result
{
	private final ResultSet		rs;
	
	private int					colCount;
	private ColumnMetaData[]	metadata;
	
	private int					currentRow	= 0;
	
	
	/**
	 * @param rs
	 * @throws SQLException
	 */
	public JDBCResult(final ResultSet rs) throws SQLException
	{
		this(rs,0);
	}
	
	
	// FIXME workaround for SQLite, there is a bug in rsmd.getScale(col). check
	// new driver versions! if bug is fixed delete this constructor and also
	// SQLiteJDBCConnection.query(String sql, Integer offset, Integer
	// maxRowCount, Object... params). issue 13769
	/**
	 * @param rs
	 * @param scale
	 * @throws SQLException
	 */
	public JDBCResult(int scale, final ResultSet rs) throws SQLException
	{
		
		this.rs = rs;
		this.colCount = rs.getMetaData().getColumnCount() - 0;
		setMaxRowCount(null);
		
		final ResultSetMetaData rsmd = rs.getMetaData();
		this.metadata = new ColumnMetaData[this.colCount];
		
		for(int i = 0, col = 1; i < this.colCount; i++, col++)
		{
			metadata[i] = new ColumnMetaData(rsmd.getTableName(col),rsmd.getColumnName(col),
					rsmd.getColumnLabel(col),DataType.get(rsmd.getColumnType(col)),
					rsmd.getPrecision(col),scale,null,
					rsmd.isNullable(col) != ResultSetMetaData.columnNoNulls,
					rsmd.isAutoIncrement(col));
			metadata[i].setTypeName(rsmd.getColumnTypeName(col));
		}
	}
	
	
	/**
	 * @param rs
	 * @param skip
	 * @throws SQLException
	 */
	public JDBCResult(final ResultSet rs, final int skip) throws SQLException
	{
		this(rs,skip,0,null);
	}
	
	
	/**
	 * @param rs
	 * @param skip
	 * @param discardTrailingCols
	 * @throws SQLException
	 */
	public JDBCResult(final ResultSet rs, final int skip, final int discardTrailingCols)
			throws SQLException
	{
		this(rs,skip,discardTrailingCols,null);
	}
	
	
	/**
	 * Creates ColumnMetadata information for all accounted columns
	 * and skips rows (scrolls forward in rs) if specified.
	 * 
	 * @param rs
	 *            the ResultSet instance that shall be wrapped by
	 *            this JDBCResult instance. if rs is null, a
	 *            NullPointerException is thrown.
	 * @param skip
	 *            the number of rows to skip (scroll forward) of rs. Note that
	 *            skipping causes repeated calls of
	 *            ResultSet.next(), so DB network traffic is NOT
	 *            spared.
	 * @param discardTrailingCols
	 *            the number of columns that will be discarded from the end of
	 *            the column list.
	 * @param maxRowCount
	 *            the upmost number of rows to be returned. May be null
	 *            to disable row count limitation (return all rows the resultSet
	 *            provides).
	 * 
	 * @throws SQLException
	 *             SQLExceptions thrown by the ResultSet
	 *             implementation.
	 */
	public JDBCResult(final ResultSet rs, final int skip, final int discardTrailingCols,
			final Integer maxRowCount) throws SQLException
	{
		this.rs = rs;
		this.colCount = rs.getMetaData().getColumnCount() - discardTrailingCols;
		setMaxRowCount(maxRowCount);
		
		final ResultSetMetaData rsmd = rs.getMetaData();
		this.metadata = new ColumnMetaData[this.colCount];
		
		for(int i = 0, col = 1; i < this.colCount; i++, col++)
		{
			metadata[i] = new ColumnMetaData(rsmd.getTableName(col),rsmd.getColumnName(col),
					rsmd.getColumnLabel(col),DataType.get(rsmd.getColumnType(col)),
					rsmd.getPrecision(col),rsmd.getScale(col),null,
					rsmd.isNullable(col) != ResultSetMetaData.columnNoNulls,
					rsmd.isAutoIncrement(col));
			metadata[i].setTypeName(rsmd.getColumnTypeName(col));
		}
		
		if(skip > 0)
		{
			skipImpl(skip);
		}
	}
	
	
	public ResultSet getJdbcResultSet()
	{
		return rs;
	}
	
	
	/**
	 * @return the current count of already scrolled rows.
	 */
	public int getCurrentRow()
	{
		return currentRow;
	}
	
	
	/**
	 * This method is an alias for ResultSet.next() called on the
	 * ResultSet instance that was provided when creating this
	 * JDBCResult instance EXCEPT the following exceptions:
*
    *
  • The ResultSet instance provided when creating this * JDBCResult instance was null, then false is * returned. *
  • A maxRowCount value has been provided (not null) and the limit has * already been reached, then false is returned. *
* * @return true if there is another row to be returned, otherwise * false. * @throws SQLException * any SQLException that can be thrown by * ResultSet.next() */ /* * (22.02.2010 TM)NOTE: next() is synchronized now E.g.: If multiple threads * call this method simultaneously it can happen that currentRow becomes * larger than maxRowCount and too much rows are returned. */ @Override public synchronized boolean next() throws DBException { try { Integer maxRowCount = getMaxRowCount(); if(maxRowCount != null && this.currentRow >= maxRowCount) { return false; } if(rs.next()) { this.currentRow++; return true; } return false; } catch(SQLException e) { throw new DBException(getDataSource(),e); } } @Override public synchronized int skip(int count) throws DBException { try { return skipImpl(count); } catch(SQLException e) { throw new DBException(getDataSource(),e); } } private int skipImpl(int count) throws SQLException { int skipped = 0; while(skipped < count) { if(rs.next()) { skipped++; } else { break; } } return skipped; } /** * Alias for ResultSet.getObject(col + 1) called on the * ResultSet instance that was provided when creating this * JDBCResult instance. * * @param col * col the index of the column whose value shall be returned, * starting at 0 * @return the returned value of the * ResultSet.getObject(col + 1) call. * @throws SQLException * any SQLExecption that can be thrown by * ResultSet.getObject() */ @Override public Object getObject(int col) throws DBException { try { try { DataType type = metadata[col].getType(); if(type.isBlob()) { return rs.getBlob(col + 1); } else if(type == DataType.CLOB) { return rs.getClob(col + 1); } } catch(SQLException e) { } return rs.getObject(col + 1); } catch(SQLException e) { throw new DBException(getDataSource(),e); } } /** * @return the column count of this JDBCResult instance */ @Override public int getColumnCount() { return colCount; } @Override public ColumnMetaData getMetadata(int col) { return metadata[col]; } /** * Returns the column name with index col by calling
* rs.getMetaData().getColumnName(col + 1).
*

* If an SQLExceptions occurs, the return value is "COL" + col *

* Note that col starts with 0 for the first column. * * @param col * the index of the column whose name shall be returned, starting * at 0 * @return the column name of column with index col or * "COL"+col on any exception. */ public String getColName(int col) { try { return rs.getMetaData().getColumnName(col + 1); } catch(SQLException e) { return "COL" + col; } } /** * Closes the ResultSet. */ @Override public void close() throws DBException { JDBCUtils.closeSilent(rs); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy