Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » sql » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.    
   18    */
   19   package org.apache.openjpa.jdbc.sql;
   20   
   21   import java.io.InputStream;
   22   import java.io.Reader;
   23   import java.math.BigDecimal;
   24   import java.math.BigInteger;
   25   import java.sql.Array;
   26   import java.sql.Blob;
   27   import java.sql.Clob;
   28   import java.sql.Connection;
   29   import java.sql.Ref;
   30   import java.sql.ResultSet;
   31   import java.sql.SQLException;
   32   import java.sql.Statement;
   33   import java.sql.Time;
   34   import java.sql.Timestamp;
   35   import java.sql.Types;
   36   import java.util.Calendar;
   37   import java.util.Date;
   38   import java.util.Locale;
   39   import java.util.Map;
   40   
   41   import org.apache.openjpa.jdbc.kernel.JDBCStore;
   42   import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
   43   import org.apache.openjpa.jdbc.schema.Column;
   44   import org.apache.openjpa.meta.JavaTypes;
   45   
   46   import serp.util.Numbers;
   47   
   48   /**
   49    * Base {@link Result} implementation wrapped around a result set.
   50    * Column objects, column names, or column indexes (as <code>Number</code>
   51    * instances) can be used to retrieve result set data.
   52    *
   53    * @author Abe White
   54    */
   55   public class ResultSetResult
   56       extends AbstractResult {
   57   
   58       private final Connection _conn;
   59       private final Statement _stmnt;
   60       private final ResultSet _rs;
   61       private final DBDictionary _dict;
   62       private boolean _closeConn = true;
   63       private int _row = -1;
   64       private int _size = -1;
   65   
   66       // optional; used to deserialize blobs containing refs to persistent objs
   67       private JDBCStore _store = null;
   68   
   69       /**
   70        * Constructor.
   71        */
   72       public ResultSetResult(Connection conn, Statement stmnt,
   73           ResultSet rs, DBDictionary dict) {
   74           if (stmnt == null)
   75               try {
   76                   stmnt = rs.getStatement();
   77               } catch (Throwable t) {
   78               }
   79   
   80           _conn = conn;
   81           _stmnt = stmnt;
   82           _rs = rs;
   83           _dict = dict;
   84       }
   85   
   86       /**
   87        * Constructor.
   88        */
   89       public ResultSetResult(Connection conn, Statement stmnt,
   90           ResultSet rs, JDBCStore store) {
   91           this(conn, stmnt, rs, store.getDBDictionary());
   92           setStore(store);
   93       }
   94   
   95       /**
   96        * Constructor.
   97        */
   98       public ResultSetResult(Connection conn,
   99           ResultSet rs, DBDictionary dict) {
  100           _conn = conn;
  101           _stmnt = null;
  102           _rs = rs;
  103           _dict = dict;
  104       }
  105   
  106       /**
  107        * JDBC 2 constructor. Relies on being able to retrieve the statement
  108        * from the result set, and the connection from the statement.
  109        */
  110       public ResultSetResult(ResultSet rs, DBDictionary dict)
  111           throws SQLException {
  112           _stmnt = rs.getStatement();
  113           _conn = _stmnt.getConnection();
  114           _rs = rs;
  115           _dict = dict;
  116       }
  117   
  118       /**
  119        * JDBC 2 constructor. Relies on being able to retrieve the statement
  120        * from the result set, and the connection from the statement.
  121        */
  122       public ResultSetResult(ResultSet rs, JDBCStore store)
  123           throws SQLException {
  124           this(rs, store.getDBDictionary());
  125           setStore(store);
  126       }
  127   
  128       /**
  129        * Return the statement that produced this result.
  130        */
  131       public Statement getStatement() {
  132           return _stmnt;
  133       }
  134   
  135       /**
  136        * Return the backing result set.
  137        */
  138       public ResultSet getResultSet() {
  139           return _rs;
  140       }
  141   
  142       /**
  143        * Return the dictionary in use.
  144        */
  145       public DBDictionary getDBDictionary() {
  146           return _dict;
  147       }
  148   
  149       /**
  150        * Optional store manager used to deserialize blobs containing
  151        * references to persistent objects.
  152        */
  153       public JDBCStore getStore() {
  154           return _store;
  155       }
  156   
  157       /**
  158        * Optional store manager used to deserialize blobs containing
  159        * references to persistent objects.
  160        */
  161       public void setStore(JDBCStore store) {
  162           _store = store;
  163       }
  164   
  165       /**
  166        * Whether to close the backing connection when this result is closed.
  167        * Defaults to true.
  168        */
  169       public boolean getCloseConnection() {
  170           return _closeConn;
  171       }
  172   
  173       /**
  174        * Whether to close the backing connection when this result is closed.
  175        * Defaults to true.
  176        */
  177       public void setCloseConnection(boolean closeConn) {
  178           _closeConn = closeConn;
  179       }
  180   
  181       public void close() {
  182           super.close();
  183           try {
  184               _rs.close();
  185           } catch (SQLException se) {
  186           }
  187           if (_stmnt != null)
  188               try {
  189                   _stmnt.close();
  190               } catch (SQLException se) {
  191               }
  192           if (_closeConn)
  193               try {
  194                   _conn.close();
  195               } catch (SQLException se) {
  196               }
  197       }
  198   
  199       public boolean supportsRandomAccess()
  200           throws SQLException {
  201           return _rs.getType() != ResultSet.TYPE_FORWARD_ONLY;
  202       }
  203   
  204       protected boolean absoluteInternal(int row)
  205           throws SQLException {
  206           if (row == ++_row)
  207               return _rs.next();
  208   
  209           // random access
  210           _rs.absolute(row + 1);
  211           if (_rs.getRow() == 0) {
  212               _row = -1;
  213               return false;
  214           }
  215           _row = row;
  216           return true;
  217       }
  218   
  219       protected boolean nextInternal()
  220           throws SQLException {
  221           _row++;
  222           return _rs.next();
  223       }
  224   
  225       public int size()
  226           throws SQLException {
  227           if (_size == -1) {
  228               _rs.last();
  229               _size = _rs.getRow();
  230               if (_row == -1)
  231                   _rs.beforeFirst();
  232               else
  233                   _rs.absolute(_row + 1);
  234           }
  235           return _size;
  236       }
  237   
  238       protected boolean containsInternal(Object obj, Joins joins)
  239           throws SQLException {
  240           return ((Number) translate(obj, joins)).intValue() > 0;
  241       }
  242   
  243       protected Array getArrayInternal(Object obj, Joins joins)
  244           throws SQLException {
  245           return _dict.getArray(_rs, ((Number) obj).intValue());
  246       }
  247   
  248       protected InputStream getAsciiStreamInternal(Object obj, Joins joins)
  249           throws SQLException {
  250           return _dict.getAsciiStream(_rs, ((Number) obj).intValue());
  251       }
  252   
  253       protected BigDecimal getBigDecimalInternal(Object obj, Joins joins)
  254           throws SQLException {
  255           return _dict.getBigDecimal(_rs, ((Number) obj).intValue());
  256       }
  257   
  258       protected Number getNumberInternal(Object obj, Joins joins)
  259           throws SQLException {
  260           return _dict.getNumber(_rs, ((Number) obj).intValue());
  261       }
  262   
  263       protected BigInteger getBigIntegerInternal(Object obj, Joins joins)
  264           throws SQLException {
  265           return _dict.getBigInteger(_rs, ((Number) obj).intValue());
  266       }
  267   
  268       protected InputStream getBinaryStreamInternal(Object obj, Joins joins)
  269           throws SQLException {
  270           return _dict.getBinaryStream(_rs, ((Number) obj).intValue());
  271       }
  272   
  273       protected Blob getBlobInternal(Object obj, Joins joins)
  274           throws SQLException {
  275           return _dict.getBlob(_rs, ((Number) obj).intValue());
  276       }
  277   
  278       protected boolean getBooleanInternal(Object obj, Joins joins)
  279           throws SQLException {
  280           return _dict.getBoolean(_rs, ((Number) obj).intValue());
  281       }
  282   
  283       protected byte getByteInternal(Object obj, Joins joins)
  284           throws SQLException {
  285           return _dict.getByte(_rs, ((Number) obj).intValue());
  286       }
  287   
  288       protected byte[] getBytesInternal(Object obj, Joins joins)
  289           throws SQLException {
  290           return _dict.getBytes(_rs, ((Number) obj).intValue());
  291       }
  292   
  293       protected Calendar getCalendarInternal(Object obj, Joins joins)
  294           throws SQLException {
  295           return _dict.getCalendar(_rs, ((Number) obj).intValue());
  296       }
  297   
  298       protected char getCharInternal(Object obj, Joins joins)
  299           throws SQLException {
  300           return _dict.getChar(_rs, ((Number) obj).intValue());
  301       }
  302   
  303       protected Reader getCharacterStreamInternal(Object obj, Joins joins)
  304           throws SQLException {
  305           return _dict.getCharacterStream(_rs, ((Number) obj).intValue());
  306       }
  307   
  308       protected Clob getClobInternal(Object obj, Joins joins)
  309           throws SQLException {
  310           return _dict.getClob(_rs, ((Number) obj).intValue());
  311       }
  312   
  313       protected Date getDateInternal(Object obj, Joins joins)
  314           throws SQLException {
  315           return _dict.getDate(_rs, ((Number) obj).intValue());
  316       }
  317   
  318       protected java.sql.Date getDateInternal(Object obj, Calendar cal,
  319           Joins joins)
  320           throws SQLException {
  321           return _dict.getDate(_rs, ((Number) obj).intValue(), cal);
  322       }
  323   
  324       protected double getDoubleInternal(Object obj, Joins joins)
  325           throws SQLException {
  326           return _dict.getDouble(_rs, ((Number) obj).intValue());
  327       }
  328   
  329       protected float getFloatInternal(Object obj, Joins joins)
  330           throws SQLException {
  331           return _dict.getFloat(_rs, ((Number) obj).intValue());
  332       }
  333   
  334       protected int getIntInternal(Object obj, Joins joins)
  335           throws SQLException {
  336           return _dict.getInt(_rs, ((Number) obj).intValue());
  337       }
  338   
  339       protected Locale getLocaleInternal(Object obj, Joins joins)
  340           throws SQLException {
  341           return _dict.getLocale(_rs, ((Number) obj).intValue());
  342       }
  343   
  344       protected long getLongInternal(Object obj, Joins joins)
  345           throws SQLException {
  346           return _dict.getLong(_rs, ((Number) obj).intValue());
  347       }
  348   
  349       protected Object getStreamInternal(JDBCStore store, Object obj,
  350           int metaTypeCode, Object arg, Joins joins) throws SQLException {
  351           return getLOBStreamInternal(store, obj, joins);
  352       }
  353       
  354       protected Object getObjectInternal(Object obj, int metaTypeCode,
  355           Object arg, Joins joins)
  356           throws SQLException {
  357           if (metaTypeCode == -1 && obj instanceof Column)
  358               metaTypeCode = ((Column) obj).getJavaType();
  359   
  360           Object val = null;
  361           switch (metaTypeCode) {
  362               case JavaTypes.BOOLEAN:
  363               case JavaTypes.BOOLEAN_OBJ:
  364                   val = (getBooleanInternal(obj, joins)) ? Boolean.TRUE
  365                       : Boolean.FALSE;
  366                   break;
  367               case JavaTypes.BYTE:
  368               case JavaTypes.BYTE_OBJ:
  369                   val = new Byte(getByteInternal(obj, joins));
  370                   break;
  371               case JavaTypes.CHAR:
  372               case JavaTypes.CHAR_OBJ:
  373                   val = new Character(getCharInternal(obj, joins));
  374                   break;
  375               case JavaTypes.DOUBLE:
  376               case JavaTypes.DOUBLE_OBJ:
  377                   val = new Double(getDoubleInternal(obj, joins));
  378                   break;
  379               case JavaTypes.FLOAT:
  380               case JavaTypes.FLOAT_OBJ:
  381                   val = new Float(getFloatInternal(obj, joins));
  382                   break;
  383               case JavaTypes.INT:
  384               case JavaTypes.INT_OBJ:
  385                   val = Numbers.valueOf(getIntInternal(obj, joins));
  386                   break;
  387               case JavaTypes.LONG:
  388               case JavaTypes.LONG_OBJ:
  389                   val = Numbers.valueOf(getLongInternal(obj, joins));
  390                   break;
  391               case JavaTypes.SHORT:
  392               case JavaTypes.SHORT_OBJ:
  393                   val = new Short(getShortInternal(obj, joins));
  394                   break;
  395               case JavaTypes.STRING:
  396                   return getStringInternal(obj, joins);
  397               case JavaTypes.OBJECT:
  398                   return _dict
  399                       .getBlobObject(_rs, ((Number) obj).intValue(), _store);
  400               case JavaTypes.DATE:
  401                   return getDateInternal(obj, joins);
  402               case JavaTypes.CALENDAR:
  403                   return getCalendarInternal(obj, joins);
  404               case JavaTypes.BIGDECIMAL:
  405                   return getBigDecimalInternal(obj, joins);
  406               case JavaTypes.NUMBER:
  407                   return getNumberInternal(obj, joins);
  408               case JavaTypes.BIGINTEGER:
  409                   return getBigIntegerInternal(obj, joins);
  410               case JavaTypes.LOCALE:
  411                   return getLocaleInternal(obj, joins);
  412               case JavaSQLTypes.SQL_ARRAY:
  413                   return getArrayInternal(obj, joins);
  414               case JavaSQLTypes.ASCII_STREAM:
  415                   return getAsciiStreamInternal(obj, joins);
  416               case JavaSQLTypes.BINARY_STREAM:
  417                   return getBinaryStreamInternal(obj, joins);
  418               case JavaSQLTypes.BLOB:
  419                   return getBlobInternal(obj, joins);
  420               case JavaSQLTypes.BYTES:
  421                   return getBytesInternal(obj, joins);
  422               case JavaSQLTypes.CHAR_STREAM:
  423                   return getCharacterStreamInternal(obj, joins);
  424               case JavaSQLTypes.CLOB:
  425                   return getClobInternal(obj, joins);
  426               case JavaSQLTypes.SQL_DATE:
  427                   return getDateInternal(obj, (Calendar) arg, joins);
  428               case JavaSQLTypes.SQL_OBJECT:
  429                   return getSQLObjectInternal(obj, (Map) arg, joins);
  430               case JavaSQLTypes.REF:
  431                   return getRefInternal(obj, (Map) arg, joins);
  432               case JavaSQLTypes.TIME:
  433                   return getTimeInternal(obj, (Calendar) arg, joins);
  434               case JavaSQLTypes.TIMESTAMP:
  435                   return getTimestampInternal(obj, (Calendar) arg, joins);
  436               default:
  437                   if (obj instanceof Column) {
  438                       Column col = (Column) obj;
  439                       if (col.getType() == Types.BLOB
  440                           || col.getType() == Types.VARBINARY) {
  441                           return _dict
  442                               .getBlobObject(_rs, col.getIndex(), _store);
  443                       }
  444                   }
  445                   return _dict.getObject(_rs, ((Number) obj).intValue(), null);
  446           }
  447           return (_rs.wasNull()) ? null : val;
  448       }
  449   
  450       protected Object getSQLObjectInternal(Object obj, Map map, Joins joins)
  451           throws SQLException {
  452           return _dict.getObject(_rs, ((Number) obj).intValue(), map);
  453       }
  454   
  455       protected Ref getRefInternal(Object obj, Map map, Joins joins)
  456           throws SQLException {
  457           return _dict.getRef(_rs, ((Number) obj).intValue(), map);
  458       }
  459   
  460       protected short getShortInternal(Object obj, Joins joins)
  461           throws SQLException {
  462           return _dict.getShort(_rs, ((Number) obj).intValue());
  463       }
  464   
  465       protected String getStringInternal(Object obj, Joins joins)
  466           throws SQLException {
  467           if (obj instanceof Column && ((Column) obj).getType() == Types.CLOB)
  468               return _dict.getClobString(_rs, ((Column) obj).getIndex());
  469           return _dict.getString(_rs, ((Number) obj).intValue());
  470       }
  471   
  472       protected Time getTimeInternal(Object obj, Calendar cal, Joins joins)
  473           throws SQLException {
  474           return _dict.getTime(_rs, ((Number) obj).intValue(), cal);
  475       }
  476   
  477       protected Timestamp getTimestampInternal(Object obj, Calendar cal,
  478           Joins joins)
  479           throws SQLException {
  480           return _dict.getTimestamp(_rs, ((Number) obj).intValue(), cal);
  481       }
  482   
  483       public boolean wasNull()
  484           throws SQLException {
  485           return _rs.wasNull();
  486       }
  487   
  488       protected Object translate(Object obj, Joins joins)
  489           throws SQLException {
  490           if (obj instanceof Number)
  491               return obj;
  492           return Numbers.valueOf(findObject(obj, joins));
  493       }
  494   
  495       /**
  496        * Return the 1-based result set index for the given column or id, or a
  497        * non-positive number if the column is not contained in this result.
  498        */
  499       protected int findObject(Object obj, Joins joins)
  500           throws SQLException {
  501           try {
  502               return getResultSet().findColumn(obj.toString());
  503           } catch (SQLException se) {
  504               return 0;
  505           }
  506       }
  507     
  508       protected InputStream getLOBStreamInternal(JDBCStore store, Object obj,
  509           Joins joins) throws SQLException {
  510           return _dict.getLOBStream(store, _rs, ((Number) obj).intValue());
  511       }
  512   }

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » sql » [javadoc | source]