You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Elifarley Callado Coelho Cruz <el...@gmail.com> on 2005/05/01 02:00:44 UTC

[DBUtils] ResultSetIterator alternative impl.

Some time ago I needed to have an interator view of a ResultSet, and
since I didn't know commons-dbutils by that time, I had to implement
my own ResultSetIterator.

Recently I found out that there's already a class with that exact name
in DBUtils, but with some implementation differences. Let me point out
some of them:

1 - It does not use the method ResultSet.isLast(); It only uses the
method ResultSet.next() to iterate over all rows.

2- It provides an Iterator whose elements are either of type Object[],
Map or Object (a bean), or a user-defined type (thru the use of a
RowImporter);

3- It can selectively close the result set, its statement, and its
connection according to a parameter by the time it detects there are
no more elements to be retrieved, when it gets garbage-collected, or
when its close() method is called.

Please let me know your oppinions / suggestions / criticisms about
these changes.

I have copied it below in case the DBUtils team finds it worthwhile to
include it in the project.

Thank you.

/*
 * Created on Mar 04, 2004
 * $Id: ResultSetIterator.java,v 1.1 2005/04/30 22:49:36 ecc Exp $
 * 
 * Copyright (C) 2005 Elifarley Callado Coelho Cruz <el...@yahoo.com>
 * 
 * This library 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 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
package org.ecc.base.collection;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbutils.DbUtils;
import org.ecc.base.db.RowImporter;
import org.ecc.base.db.RowImporterFactory;

/**
 * Returns an Iterator from a given ResultSet.
 * 
 * @author Elifarley Callado Coelho Cruz
 * @version 1.1, $Revision: 1.1 $, $Date: 2005/04/30 22:49:36 $
 */
public class ResultSetIterator extends DelegationIterator {

  public static final byte CLOSE_NONE = 0;

  public static final byte CLOSE_RESULT_SET = 1;

  public static final byte CLOSE_STATEMENT = 2;

  public static final byte CLOSE_CONNECTION = 3;

  private ResultSet rs;

  private RowImporter importer;

  private byte closePolicy;

  /**
   * Returns an iterator whose elements are object arrays filled with the values
   * found at the corresponding rows from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getArrayInstance(ResultSet rs) {
    return getArrayInstance(rs, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are object arrays filled with the values
   * found at the corresponding rows from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getArrayInstance(ResultSet rs,
      byte closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory.getArrayInstance(),
        closePolicy);
  }

  /**
   * Returns an iterator whose elements are {@link java.util.Map}
instances filled with
   * the column names and its values found at the corresponding rows
from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getMapInstance(ResultSet rs) {
    return getMapInstance(rs, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are {@link java.util.Map}
instances filled with
   * the column names and its values found at the corresponding rows
from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getMapInstance(ResultSet rs, byte
closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory.getMapInstance(),
        closePolicy);
  }

  /**
   * Returns an iterator whose elements are instances of
<tt>beanClass</tt> filled with
   * the values found at the corresponding rows from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param beanClass Class of the elements of the returned iterator.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getBeanInstance(ResultSet rs, Class
beanClass) {
    return getBeanInstance(rs, beanClass, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are instances of
<tt>beanClass</tt> filled with
   * the values found at the corresponding rows from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param beanClass Class of the elements of the returned iterator.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getBeanInstance(ResultSet rs,
      Class beanClass, byte closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory
        .getBeanInstance(beanClass), closePolicy);
  }

  /**
   * Returns an iterator whose elements are object instances returned
by the supplied
   * <tt>importer</tt> corresponding to the rows from <tt>rs</tt>.
   * 
   * @param rs Result set to be wrapped. If <tt>closeWhenDone</tt> is
<code>true</code>, it will be closed when appropriate.
   * @param importer An importer used to process each row from <tt>rs</tt>.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getInstance(ResultSet rs,
      RowImporter importer, byte closePolicy) {
    return new ResultSetIterator(rs, importer, closePolicy);
  }

  /**
   * 
   * @param rs Result set to be wrapped. If <tt>closeWhenDone</tt> is
<code>true</code>, it will be closed when appropriate.
   * @param importer An importer used to process each row from <tt>rs</tt>.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   */
  private ResultSetIterator(ResultSet rs, RowImporter importer, byte
closePolicy) {
    super(closePolicy != CLOSE_NONE);
    this.rs = rs;
    this.importer = importer;
    this.closePolicy = closePolicy;
  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateHasNext()
   */
  protected final boolean delegateHasNext() {

    try {
      return this.rs.next();

    } catch (SQLException e) {
      e.printStackTrace();
      return false;
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateImport()
   */
  protected final Object delegateImport() throws IOException {

    try {
      return this.importer.importFrom(this.rs);
    } catch (SQLException e) {
      IOException ioe = new IOException();
      throw (IOException) ioe.initCause(e);
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateRemove()
   */
  protected final void delegateRemove() throws IOException {

    try {
      this.rs.deleteRow();

    } catch (SQLException e) {
      IOException ioe = new IOException();
      throw (IOException) ioe.initCause(e);
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateClose()
   */
  /**
   * Closes the underlying connection, statement and result set.
   */
  protected final void delegateClose() {

    ResultSet rs = this.rs;
    if (rs == null) return;
    
    try {
      
      switch (this.closePolicy) {

      case CLOSE_NONE:
        break;

      case CLOSE_RESULT_SET:
        DbUtils.closeQuietly(rs);
        break;

      case CLOSE_STATEMENT:
        DbUtils.closeQuietly(rs.getStatement());
        break;

      case CLOSE_CONNECTION:
        Statement stmt = rs.getStatement();
        Connection conn = stmt == null ? null : stmt.getConnection();
        DbUtils.closeQuietly(conn, stmt, rs);
        break;

      default:
        throw new SQLException("Unknown import type: " + this.closePolicy);
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }

  }

}

-- 
There are 10 types of people in the world:
Those who understand binary and those who don't

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Fwd: [DBUtils] ResultSetIterator alternative impl.

Posted by Elifarley Callado Coelho Cruz <el...@gmail.com>.
It seems that this message didn't get to the list, so I am re-sending it.

---------- Forwarded message ----------
From: Elifarley Callado Coelho Cruz <el...@gmail.com>
Date: Apr 30, 2005 9:00 PM
Subject: [DBUtils] ResultSetIterator alternative impl.
To: commons-user@jakarta.apache.org


Some time ago I needed to have an interator view of a ResultSet, and
since I didn't know commons-dbutils by that time, I had to implement
my own ResultSetIterator.

Recently I found out that there's already a class with that exact name
in DBUtils, but with some implementation differences.

Let me point out some of the differing characteristics of my implementation:

1 - It does not use the method ResultSet.isLast(); It only uses the
method ResultSet.next() to iterate over all rows ( ResultSet.isLast()
only appeared at version 1.2, while ResultSet.next() exists since the
first version of ResultSet ).

2- It provides an Iterator whose elements are either of type Object[],
Map or Object (a bean), or anything else (thru the use of a
user-supplied RowImporter);

3- It can selectively close the result set, its statement, and its
connection (according to a parameter) by the time it detects there are
no more elements to be retrieved, when it gets garbage-collected, or
when its close() method is called.

Please let me know your oppinions / suggestions / criticisms about
these changes.

I have copied it below in case the DBUtils team finds it worthwhile to
include it in the project.

Thank you.

/*
 * Created on Mar 04, 2004
 * $Id: ResultSetIterator.java,v 1.1 2005/04/30 22:49:36 ecc Exp $
 *
 * Copyright (C) 2005 Elifarley Callado Coelho Cruz <el...@yahoo.com>
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.ecc.base.collection;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbutils.DbUtils;
import org.ecc.base.db.RowImporter;
import org.ecc.base.db.RowImporterFactory;

/**
 * Returns an Iterator from a given ResultSet.
 *
 * @author Elifarley Callado Coelho Cruz
 * @version 1.1, $Revision: 1.1 $, $Date: 2005/04/30 22:49:36 $
 */
public class ResultSetIterator extends DelegationIterator {

  public static final byte CLOSE_NONE = 0;

  public static final byte CLOSE_RESULT_SET = 1;

  public static final byte CLOSE_STATEMENT = 2;

  public static final byte CLOSE_CONNECTION = 3;

  private ResultSet rs;

  private RowImporter importer;

  private byte closePolicy;

  /**
   * Returns an iterator whose elements are object arrays filled with the values
   * found at the corresponding rows from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getArrayInstance(ResultSet rs) {
    return getArrayInstance(rs, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are object arrays filled with the values
   * found at the corresponding rows from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getArrayInstance(ResultSet rs,
      byte closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory.getArrayInstance(),
        closePolicy);
  }

  /**
   * Returns an iterator whose elements are {@link java.util.Map}
instances filled with
   * the column names and its values found at the corresponding rows
from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getMapInstance(ResultSet rs) {
    return getMapInstance(rs, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are {@link java.util.Map}
instances filled with
   * the column names and its values found at the corresponding rows
from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getMapInstance(ResultSet rs, byte
closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory.getMapInstance(),
        closePolicy);
  }

  /**
   * Returns an iterator whose elements are instances of
<tt>beanClass</tt> filled with
   * the values found at the corresponding rows from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param beanClass Class of the elements of the returned iterator.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getBeanInstance(ResultSet rs, Class
beanClass) {
    return getBeanInstance(rs, beanClass, CLOSE_CONNECTION);
  }

  /**
   * Returns an iterator whose elements are instances of
<tt>beanClass</tt> filled with
   * the values found at the corresponding rows from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. It will be closed when appropriate.
   * @param beanClass Class of the elements of the returned iterator.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getBeanInstance(ResultSet rs,
      Class beanClass, byte closePolicy) {
    return new ResultSetIterator(rs, RowImporterFactory
        .getBeanInstance(beanClass), closePolicy);
  }

  /**
   * Returns an iterator whose elements are object instances returned
by the supplied
   * <tt>importer</tt> corresponding to the rows from <tt>rs</tt>.
   *
   * @param rs Result set to be wrapped. If <tt>closeWhenDone</tt> is
<code>true</code>, it will be closed when appropriate.
   * @param importer An importer used to process each row from <tt>rs</tt>.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   * @return An iterator over the rows from <tt>rs</tt>.
   */
  public static ResultSetIterator getInstance(ResultSet rs,
      RowImporter importer, byte closePolicy) {
    return new ResultSetIterator(rs, importer, closePolicy);
  }

  /**
   *
   * @param rs Result set to be wrapped. If <tt>closeWhenDone</tt> is
<code>true</code>, it will be closed when appropriate.
   * @param importer An importer used to process each row from <tt>rs</tt>.
   * @param closePolicy Tels whether the result set, its statement and
its connection should be closed when apporopriate.
   */
  private ResultSetIterator(ResultSet rs, RowImporter importer, byte
closePolicy) {
    super(closePolicy != CLOSE_NONE);
    this.rs = rs;
    this.importer = importer;
    this.closePolicy = closePolicy;
  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateHasNext()
   */
  protected final boolean delegateHasNext() {

    try {
      return this.rs.next();

    } catch (SQLException e) {
      e.printStackTrace();
      return false;
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateImport()
   */
  protected final Object delegateImport() throws IOException {

    try {
      return this.importer.importFrom(this.rs);
    } catch (SQLException e) {
      IOException ioe = new IOException();
      throw (IOException) ioe.initCause(e);
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateRemove()
   */
  protected final void delegateRemove() throws IOException {

    try {
      this.rs.deleteRow();

    } catch (SQLException e) {
      IOException ioe = new IOException();
      throw (IOException) ioe.initCause(e);
    }

  }

  /* (non-Javadoc)
   * @see org.ecc.base.collection.DelegationIterator#delegateClose()
   */
  /**
   * Closes the underlying connection, statement and result set.
   */
  protected final void delegateClose() {

    ResultSet rs = this.rs;
    if (rs == null) return;

    try {

      switch (this.closePolicy) {

      case CLOSE_NONE:
        break;

      case CLOSE_RESULT_SET:
        DbUtils.closeQuietly(rs);
        break;

      case CLOSE_STATEMENT:
        DbUtils.closeQuietly(rs.getStatement());
        break;

      case CLOSE_CONNECTION:
        Statement stmt = rs.getStatement();
        Connection conn = stmt == null ? null : stmt.getConnection();
        DbUtils.closeQuietly(conn, stmt, rs);
        break;

      default:
        throw new SQLException("Unknown import type: " + this.closePolicy);
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }

  }

}

--
There are 10 types of people in the world:
Those who understand binary and those who don't


-- 
There are 10 types of people in the world:
Those who understand binary and those who don't

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org