You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [34/44] - in /incubator/openjpa/trunk: ./
openjpa-jdbc-5/ openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/
openjpa-jdbc-5/src/main/java/ openjpa-jdbc-5/src/main/java/org/
openjpa-jdbc-5/src/main/java/org/apache/ openjpa-jdbc-5/src/main/...
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,572 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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 org.apache.openjpa.jdbc.sql;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.lib.util.Closeable;
+
+/**
+ * A result from the execution of a query or stored procedure. This
+ * interface is aligned closely with the {@link java.sql.ResultSet}, so you
+ * can expect like-named methods to have similar semantics. However, the
+ * interface has been distilled and simplified, so a result object could
+ * easily mask information sources other than a result set.
+ * For more flexible customization of data loading, see the
+ * {@link org.apache.openjpa.kernel.PCResultObjectProvider}.
+ *
+ * @author Abe White
+ * @see ResultSetResult
+ */
+public interface Result
+ extends Closeable {
+
+ /**
+ * The eager result for the given key, or null if none.
+ */
+ public Object getEager(FieldMapping key);
+
+ /**
+ * The eager result for the given key, or null if none.
+ */
+ public void putEager(FieldMapping key, Object res);
+
+ /**
+ * Return a new joins instance to use for traversing to related data.
+ */
+ public Joins newJoins();
+
+ /**
+ * Free the resources used by this result; do <strong>not</strong>
+ * close the SQL connection.
+ */
+ public void close();
+
+ /**
+ * If true, then any results loaded from this Result
+ * will be locked in the database.
+ */
+ public boolean isLocking();
+
+ /**
+ * Return true if the result supports random access.
+ */
+ public boolean supportsRandomAccess()
+ throws SQLException;
+
+ /**
+ * Move to the given <strong>0-based</strong> row in the result, or
+ * return false if the row does not exist. This method will only be
+ * called if the result supports random access.
+ */
+ public boolean absolute(int row)
+ throws SQLException;
+
+ /**
+ * Advance to the next row, or return false if there are no more rows
+ * in the result.
+ */
+ public boolean next()
+ throws SQLException;
+
+ /**
+ * Push back the last result. In other words, just ignore the next call
+ * to {@link #next}. After the first time this method is called,
+ * additional calls before a call to {@link #next} or {@link #absolute}
+ * should have no further affect.
+ */
+ public void pushBack()
+ throws SQLException;
+
+ /**
+ * Return the number of rows in this result.
+ */
+ public int size()
+ throws SQLException;
+
+ /**
+ * Return true if the given id or column is available in the result.
+ */
+ public boolean contains(Object obj)
+ throws SQLException;
+
+ /**
+ * Return true if all the given ids or columns are available in the result.
+ */
+ public boolean containsAll(Object[] objs)
+ throws SQLException;
+
+ /**
+ * Return true if the given column is available in the result.
+ */
+ public boolean contains(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return true if all the given columns are available in the result.
+ */
+ public boolean containsAll(Column[] cols, Joins joins)
+ throws SQLException;
+
+ /**
+ * If this is the result of a UNION used to select a hierarchy of
+ * mappings, the base mapping represented by the current row.
+ * This information is not available after getting any eager results
+ * from the row.
+ */
+ public ClassMapping getBaseMapping();
+
+ /**
+ * If this is the result of a UNION used to select a hierarchy of
+ * mappings, the base mapping represented by the current row.
+ * This information is not available after getting any eager results
+ * from the row.
+ */
+ public void setBaseMapping(ClassMapping mapping);
+
+ /**
+ * The index of the select within the UNION that the current row
+ * corresponds to, or 0.
+ */
+ public int indexOf();
+
+ /**
+ * Load a pc object using the given store manager.
+ */
+ public Object load(ClassMapping mapping, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException;
+
+ /**
+ * Load a pc object using the given store manager.
+ */
+ public Object load(ClassMapping mapping, JDBCStore store,
+ JDBCFetchState fetchState, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Array getArray(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public InputStream getAsciiStream(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public BigDecimal getBigDecimal(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public BigInteger getBigInteger(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public InputStream getBinaryStream(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Blob getBlob(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public boolean getBoolean(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public byte getByte(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public byte[] getBytes(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public Calendar getCalendar(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public char getChar(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Reader getCharacterStream(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Clob getClob(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public Date getDate(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public java.sql.Date getDate(Object obj, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public double getDouble(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public float getFloat(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public int getInt(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public Locale getLocale(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public long getLong(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public Number getNumber(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ *
+ * @param obj the column or id whose data to fetch
+ * @param metaType the type code from {@link org.apache.openjpa.meta.JavaTypes} or
+ * {@link JavaSQLTypes} for the type of the data; if
+ * <code>obj</code> is a column, you may specify -1
+ * to use the column's recorded java type
+ * @param arg some JDBC data access methods use an argument, such
+ * as a {@link Calendar} or {@link Map}
+ */
+ public Object getObject(Object obj, int metaType, Object arg)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Object getSQLObject(Object obj, Map map)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Ref getRef(Object obj, Map map)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public short getShort(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id.
+ */
+ public String getString(Object obj)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Time getTime(Object obj, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column or id; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Timestamp getTimestamp(Object obj, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Array getArray(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public InputStream getAsciiStream(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public BigDecimal getBigDecimal(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public BigInteger getBigInteger(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public InputStream getBinaryStream(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Blob getBlob(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public boolean getBoolean(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public byte getByte(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public byte[] getBytes(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public Calendar getCalendar(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public char getChar(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Reader getCharacterStream(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Clob getClob(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public Date getDate(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public java.sql.Date getDate(Column col, Calendar cal, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public double getDouble(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public float getFloat(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public int getInt(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public Locale getLocale(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public long getLong(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public Number getNumber(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ *
+ * @param col the column whose data to fetch
+ * @param arg some JDBC data access methods use an argument, such
+ * as a {@link Calendar} or {@link Map}
+ */
+ public Object getObject(Column col, Object arg, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Object getSQLObject(Column col, Map map, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Ref getRef(Column col, Map map, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public short getShort(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column.
+ */
+ public String getString(Column col, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Time getTime(Column col, Calendar cal, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return the value stored in the given column; may not be supported
+ * by results that are not backed by a SQL result set.
+ */
+ public Timestamp getTimestamp(Column col, Calendar cal, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return true if the last value fetched was null.
+ */
+ public boolean wasNull()
+ throws SQLException;
+
+ /**
+ * Informs this receiver about the application element for which a
+ * subsequent data request will be made.
+ */
+ public void startDataRequest(Object mapping);
+
+ /**
+ * Ends a data request. Must be called in conjunction with
+ * {@link #startDataRequest}. The calls can be nested as follws<br />
+ * <pre> startDataRequest (relation); startDataRequest (relationsField);
+ * getObject("COLUMN_Y"); endDataRequest (); endDataRequest ();
+ * </pre>
+ */
+ public void endDataRequest();
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Result.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,488 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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 org.apache.openjpa.jdbc.sql;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.meta.JavaTypes;
+import serp.util.Numbers;
+
+/**
+ * Base {@link Result} implementation wrapped around a result set.
+ * Column objects, column names, or column indexes (as <code>Number</code>
+ * instances) can be used to retrieve result set data.
+ *
+ * @author Abe White
+ */
+public class ResultSetResult
+ extends AbstractResult {
+
+ private final Connection _conn;
+ private final Statement _stmnt;
+ private final ResultSet _rs;
+ private final DBDictionary _dict;
+ private boolean _closeConn = true;
+ private int _row = -1;
+ private int _size = -1;
+
+ // optional; used to deserialize blobs containing refs to persistent objs
+ private JDBCStore _store = null;
+
+ /**
+ * Constructor.
+ */
+ public ResultSetResult(Connection conn, Statement stmnt,
+ ResultSet rs, DBDictionary dict) {
+ if (stmnt == null)
+ try {
+ stmnt = rs.getStatement();
+ } catch (Throwable t) {
+ }
+
+ _conn = conn;
+ _stmnt = stmnt;
+ _rs = rs;
+ _dict = dict;
+ }
+
+ /**
+ * Constructor.
+ */
+ public ResultSetResult(Connection conn, Statement stmnt,
+ ResultSet rs, JDBCStore store) {
+ this(conn, stmnt, rs, store.getDBDictionary());
+ setStore(store);
+ }
+
+ /**
+ * JDBC 2 constructor. Relies on being able to retrieve the statement
+ * from the result set, and the connection from the statement.
+ */
+ public ResultSetResult(ResultSet rs, DBDictionary dict)
+ throws SQLException {
+ _stmnt = rs.getStatement();
+ _conn = _stmnt.getConnection();
+ _rs = rs;
+ _dict = dict;
+ }
+
+ /**
+ * JDBC 2 constructor. Relies on being able to retrieve the statement
+ * from the result set, and the connection from the statement.
+ */
+ public ResultSetResult(ResultSet rs, JDBCStore store)
+ throws SQLException {
+ this(rs, store.getDBDictionary());
+ setStore(store);
+ }
+
+ /**
+ * Return the statement that produced this result.
+ */
+ public Statement getStatement() {
+ return _stmnt;
+ }
+
+ /**
+ * Return the backing result set.
+ */
+ public ResultSet getResultSet() {
+ return _rs;
+ }
+
+ /**
+ * Return the dictionary in use.
+ */
+ public DBDictionary getDBDictionary() {
+ return _dict;
+ }
+
+ /**
+ * Optional store manager used to deserialize blobs containing
+ * references to persistent objects.
+ */
+ public JDBCStore getStore() {
+ return _store;
+ }
+
+ /**
+ * Optional store manager used to deserialize blobs containing
+ * references to persistent objects.
+ */
+ public void setStore(JDBCStore store) {
+ _store = store;
+ }
+
+ /**
+ * Whether to close the backing connection when this result is closed.
+ * Defaults to true.
+ */
+ public boolean getCloseConnection() {
+ return _closeConn;
+ }
+
+ /**
+ * Whether to close the backing connection when this result is closed.
+ * Defaults to true.
+ */
+ public void setCloseConnection(boolean closeConn) {
+ _closeConn = closeConn;
+ }
+
+ public void close() {
+ super.close();
+ try {
+ _rs.close();
+ } catch (SQLException se) {
+ }
+ if (_stmnt != null)
+ try {
+ _stmnt.close();
+ } catch (SQLException se) {
+ }
+ if (_closeConn)
+ try {
+ _conn.close();
+ } catch (SQLException se) {
+ }
+ }
+
+ public boolean supportsRandomAccess()
+ throws SQLException {
+ return _rs.getType() != ResultSet.TYPE_FORWARD_ONLY;
+ }
+
+ protected boolean absoluteInternal(int row)
+ throws SQLException {
+ if (row == ++_row)
+ return _rs.next();
+
+ // random access
+ _rs.absolute(row + 1);
+ if (_rs.getRow() == 0) {
+ _row = -1;
+ return false;
+ }
+ _row = row;
+ return true;
+ }
+
+ protected boolean nextInternal()
+ throws SQLException {
+ _row++;
+ return _rs.next();
+ }
+
+ public int size()
+ throws SQLException {
+ if (_size == -1) {
+ _rs.last();
+ _size = _rs.getRow();
+ if (_row == -1)
+ _rs.beforeFirst();
+ else
+ _rs.absolute(_row + 1);
+ }
+ return _size;
+ }
+
+ protected boolean containsInternal(Object obj, Joins joins)
+ throws SQLException {
+ return ((Number) translate(obj, joins)).intValue() > 0;
+ }
+
+ protected Array getArrayInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getArray(_rs, ((Number) obj).intValue());
+ }
+
+ protected InputStream getAsciiStreamInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getAsciiStream(_rs, ((Number) obj).intValue());
+ }
+
+ protected BigDecimal getBigDecimalInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBigDecimal(_rs, ((Number) obj).intValue());
+ }
+
+ protected Number getNumberInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getNumber(_rs, ((Number) obj).intValue());
+ }
+
+ protected BigInteger getBigIntegerInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBigInteger(_rs, ((Number) obj).intValue());
+ }
+
+ protected InputStream getBinaryStreamInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBinaryStream(_rs, ((Number) obj).intValue());
+ }
+
+ protected Blob getBlobInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBlob(_rs, ((Number) obj).intValue());
+ }
+
+ protected boolean getBooleanInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBoolean(_rs, ((Number) obj).intValue());
+ }
+
+ protected byte getByteInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getByte(_rs, ((Number) obj).intValue());
+ }
+
+ protected byte[] getBytesInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getBytes(_rs, ((Number) obj).intValue());
+ }
+
+ protected Calendar getCalendarInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getCalendar(_rs, ((Number) obj).intValue());
+ }
+
+ protected char getCharInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getChar(_rs, ((Number) obj).intValue());
+ }
+
+ protected Reader getCharacterStreamInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getCharacterStream(_rs, ((Number) obj).intValue());
+ }
+
+ protected Clob getClobInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getClob(_rs, ((Number) obj).intValue());
+ }
+
+ protected Date getDateInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getDate(_rs, ((Number) obj).intValue());
+ }
+
+ protected java.sql.Date getDateInternal(Object obj, Calendar cal,
+ Joins joins)
+ throws SQLException {
+ return _dict.getDate(_rs, ((Number) obj).intValue(), cal);
+ }
+
+ protected double getDoubleInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getDouble(_rs, ((Number) obj).intValue());
+ }
+
+ protected float getFloatInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getFloat(_rs, ((Number) obj).intValue());
+ }
+
+ protected int getIntInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getInt(_rs, ((Number) obj).intValue());
+ }
+
+ protected Locale getLocaleInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getLocale(_rs, ((Number) obj).intValue());
+ }
+
+ protected long getLongInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getLong(_rs, ((Number) obj).intValue());
+ }
+
+ protected Object getObjectInternal(Object obj, int metaTypeCode,
+ Object arg, Joins joins)
+ throws SQLException {
+ if (metaTypeCode == -1 && obj instanceof Column)
+ metaTypeCode = ((Column) obj).getJavaType();
+
+ Object val = null;
+ switch (metaTypeCode) {
+ case JavaTypes.BOOLEAN:
+ case JavaTypes.BOOLEAN_OBJ:
+ val = (getBooleanInternal(obj, joins)) ? Boolean.TRUE
+ : Boolean.FALSE;
+ break;
+ case JavaTypes.BYTE:
+ case JavaTypes.BYTE_OBJ:
+ val = new Byte(getByteInternal(obj, joins));
+ break;
+ case JavaTypes.CHAR:
+ case JavaTypes.CHAR_OBJ:
+ val = new Character(getCharInternal(obj, joins));
+ break;
+ case JavaTypes.DOUBLE:
+ case JavaTypes.DOUBLE_OBJ:
+ val = new Double(getDoubleInternal(obj, joins));
+ break;
+ case JavaTypes.FLOAT:
+ case JavaTypes.FLOAT_OBJ:
+ val = new Float(getFloatInternal(obj, joins));
+ break;
+ case JavaTypes.INT:
+ case JavaTypes.INT_OBJ:
+ val = Numbers.valueOf(getIntInternal(obj, joins));
+ break;
+ case JavaTypes.LONG:
+ case JavaTypes.LONG_OBJ:
+ val = Numbers.valueOf(getLongInternal(obj, joins));
+ break;
+ case JavaTypes.SHORT:
+ case JavaTypes.SHORT_OBJ:
+ val = new Short(getShortInternal(obj, joins));
+ break;
+ case JavaTypes.STRING:
+ return getStringInternal(obj, joins);
+ case JavaTypes.OBJECT:
+ return _dict
+ .getBlobObject(_rs, ((Number) obj).intValue(), _store);
+ case JavaTypes.DATE:
+ return getDateInternal(obj, joins);
+ case JavaTypes.CALENDAR:
+ return getCalendarInternal(obj, joins);
+ case JavaTypes.BIGDECIMAL:
+ return getBigDecimalInternal(obj, joins);
+ case JavaTypes.NUMBER:
+ return getNumberInternal(obj, joins);
+ case JavaTypes.BIGINTEGER:
+ return getBigIntegerInternal(obj, joins);
+ case JavaTypes.LOCALE:
+ return getLocaleInternal(obj, joins);
+ case JavaSQLTypes.SQL_ARRAY:
+ return getArrayInternal(obj, joins);
+ case JavaSQLTypes.ASCII_STREAM:
+ return getAsciiStreamInternal(obj, joins);
+ case JavaSQLTypes.BINARY_STREAM:
+ return getBinaryStreamInternal(obj, joins);
+ case JavaSQLTypes.BLOB:
+ return getBlobInternal(obj, joins);
+ case JavaSQLTypes.BYTES:
+ return getBytesInternal(obj, joins);
+ case JavaSQLTypes.CHAR_STREAM:
+ return getCharacterStreamInternal(obj, joins);
+ case JavaSQLTypes.CLOB:
+ return getClobInternal(obj, joins);
+ case JavaSQLTypes.SQL_DATE:
+ return getDateInternal(obj, (Calendar) arg, joins);
+ case JavaSQLTypes.SQL_OBJECT:
+ return getSQLObjectInternal(obj, (Map) arg, joins);
+ case JavaSQLTypes.REF:
+ return getRefInternal(obj, (Map) arg, joins);
+ case JavaSQLTypes.TIME:
+ return getTimeInternal(obj, (Calendar) arg, joins);
+ case JavaSQLTypes.TIMESTAMP:
+ return getTimestampInternal(obj, (Calendar) arg, joins);
+ default:
+ if (obj instanceof Column) {
+ Column col = (Column) obj;
+ if (col.getType() == Types.BLOB
+ || col.getType() == Types.VARBINARY) {
+ return _dict
+ .getBlobObject(_rs, ((Number) obj).intValue(),
+ _store);
+ }
+ }
+ return _dict.getObject(_rs, ((Number) obj).intValue(), null);
+ }
+ return (_rs.wasNull()) ? null : val;
+ }
+
+ protected Object getSQLObjectInternal(Object obj, Map map, Joins joins)
+ throws SQLException {
+ return _dict.getObject(_rs, ((Number) obj).intValue(), map);
+ }
+
+ protected Ref getRefInternal(Object obj, Map map, Joins joins)
+ throws SQLException {
+ return _dict.getRef(_rs, ((Number) obj).intValue(), map);
+ }
+
+ protected short getShortInternal(Object obj, Joins joins)
+ throws SQLException {
+ return _dict.getShort(_rs, ((Number) obj).intValue());
+ }
+
+ protected String getStringInternal(Object obj, Joins joins)
+ throws SQLException {
+ if (obj instanceof Column && ((Column) obj).getType() == Types.CLOB)
+ return _dict.getClobString(_rs, ((Number) obj).intValue());
+ return _dict.getString(_rs, ((Number) obj).intValue());
+ }
+
+ protected Time getTimeInternal(Object obj, Calendar cal, Joins joins)
+ throws SQLException {
+ return _dict.getTime(_rs, ((Number) obj).intValue(), cal);
+ }
+
+ protected Timestamp getTimestampInternal(Object obj, Calendar cal,
+ Joins joins)
+ throws SQLException {
+ return _dict.getTimestamp(_rs, ((Number) obj).intValue(), cal);
+ }
+
+ public boolean wasNull()
+ throws SQLException {
+ return _rs.wasNull();
+ }
+
+ protected Object translate(Object obj, Joins joins)
+ throws SQLException {
+ if (obj instanceof Number)
+ return obj;
+ return Numbers.valueOf(findObject(obj, joins));
+ }
+
+ /**
+ * Return the 1-based result set index for the given column or id, or a
+ * non-positive number if the column is not contained in this result.
+ */
+ protected int findObject(Object obj, Joins joins)
+ throws SQLException {
+ try {
+ return getResultSet().findColumn(obj.toString());
+ } catch (SQLException se) {
+ return 0;
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Row.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Row.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Row.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Row.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,520 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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 org.apache.openjpa.jdbc.sql;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.openjpa.jdbc.meta.RelationId;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Logical representation of a table row for insert/update/delete. The
+ * {@link org.apache.openjpa.jdbc.kernel.UpdateManager} is responsible for implementing
+ * rows to do something useful when the values are set.
+ *
+ * @author Abe White
+ */
+public interface Row {
+
+ /**
+ * Symbolic constant reserved for situations when a row operation
+ * is unknown.
+ */
+ public static final int ACTION_UNKNOWN = -1;
+
+ /**
+ * Mark the row for update.
+ */
+ public static final int ACTION_UPDATE = 0;
+
+ /**
+ * Mark the row for inserttion.
+ */
+ public static final int ACTION_INSERT = 1;
+
+ /**
+ * Mark the row for deletion.
+ */
+ public static final int ACTION_DELETE = 2;
+
+ /**
+ * Return the table for this row.
+ */
+ public Table getTable();
+
+ /**
+ * Return the action for this row.
+ */
+ public int getAction();
+
+ /**
+ * Return the failed object to include in optimistic lock exceptions.
+ */
+ public Object getFailedObject();
+
+ /**
+ * Set the failed object to include in the optimistic lock exception
+ * that will be thrown if this update results in an update count of 0
+ * when executed. Leave null to avoid checking the update count.
+ */
+ public void setFailedObject(Object failed);
+
+ /**
+ * Whether this row has information set on it.
+ */
+ public boolean isValid();
+
+ /**
+ * Whether this row has information set on it.
+ */
+ public void setValid(boolean valid);
+
+ /**
+ * Return the instance that controls this row. The
+ * {@link #setPrimaryKey} method does not necessarily have to be called
+ * to know the owning instance, nor does this row's table have to have
+ * an actual primary key.
+ */
+ public OpenJPAStateManager getPrimaryKey();
+
+ /**
+ * Set the primary key to represent the given object.
+ */
+ public void setPrimaryKey(OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the primary key to represent the given object.
+ *
+ * @param io information on which columns are settable; may be null
+ */
+ public void setPrimaryKey(ColumnIO io, OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the primary key equality criteria for this row.
+ */
+ public void wherePrimaryKey(OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the value of the given foreign key to the given object.
+ * If the related type uses table-per-class mappings, the foreign key may
+ * be targeted at an independent superclass table.
+ */
+ public void setForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the value of the given foreign key to the given object.
+ * If the related type uses table-per-class mappings, the foreign key may
+ * be targeted at an independent superclass table.
+ *
+ * @param io information on which columns are settable; may be null
+ */
+ public void setForeignKey(ForeignKey fk, ColumnIO io,
+ OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the foreign key equality criteria to link to the given object.
+ * If the related type uses table-per-class mappings, the foreign key may
+ * be targeted at an independent superclass table.
+ */
+ public void whereForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setArray(Column col, Array val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setAsciiStream(Column col, InputStream val, int length)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBigDecimal(Column col, BigDecimal val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBigInteger(Column col, BigInteger val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBinaryStream(Column col, InputStream val, int length)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBlob(Column col, Blob val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBoolean(Column col, boolean val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setByte(Column col, byte val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setBytes(Column col, byte[] val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setCalendar(Column col, Calendar val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setChar(Column col, char val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setCharacterStream(Column col, Reader val, int length)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setClob(Column col, Clob val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setDate(Column col, Date val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setDouble(Column col, double val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setFloat(Column col, float val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setInt(Column col, int val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setLong(Column col, long val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setLocale(Column col, Locale val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setNull(Column col)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ *
+ * @param overrideDefault whether to set this column to null even if this
+ * is an insert and the column has a default
+ */
+ public void setNull(Column col, boolean overrideDefault)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setNumber(Column col, Number val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ *
+ * @param col the column being set
+ * @param val the value for the column
+ */
+ public void setObject(Column col, Object val)
+ throws SQLException;
+
+ /**
+ * Set a DB understood value for the given column.
+ * The value will not be parameterized and instead be inserted as raw SQL.
+ */
+ public void setRaw(Column col, String value)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column to the identity of given instance,
+ * using the given callback to create the column value. This method is
+ * used for mappings that store some serialized form of id values, but must
+ * make sure that the related object's id is assigned (which might
+ * require an insert if the instance uses auto-increment) before it is
+ * serialized.
+ */
+ public void setRelationId(Column col, OpenJPAStateManager sm,
+ RelationId rel)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setShort(Column col, short val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setString(Column col, String val)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setTime(Column col, Time val, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Set the value of the given column in this row.
+ */
+ public void setTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereArray(Column col, Array val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereAsciiStream(Column col, InputStream val, int length)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBigDecimal(Column col, BigDecimal val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBigInteger(Column col, BigInteger val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBinaryStream(Column col, InputStream val, int length)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBlob(Column col, Blob val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBoolean(Column col, boolean val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereByte(Column col, byte val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereBytes(Column col, byte[] val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereCalendar(Column col, Calendar val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereChar(Column col, char val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereCharacterStream(Column col, Reader val, int length)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereClob(Column col, Clob val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereDate(Column col, Date val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereDouble(Column col, double val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereFloat(Column col, float val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereInt(Column col, int val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereLong(Column col, long val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereLocale(Column col, Locale val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereNull(Column col)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereNumber(Column col, Number val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ *
+ * @param col the column being set
+ * @param val the value for the column
+ */
+ public void whereObject(Column col, Object val)
+ throws SQLException;
+
+ /**
+ * Set a DB understood where condition for the given column.
+ * The value will not be parameterized and instead be inserted as raw SQL.
+ */
+ public void whereRaw(Column col, String value)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereShort(Column col, short val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereString(Column col, String val)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereTime(Column col, Time val, Calendar cal)
+ throws SQLException;
+
+ /**
+ * Set an equality condition on the value of the given column in this row.
+ */
+ public void whereTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException;
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Row.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,941 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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 org.apache.openjpa.jdbc.sql;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.meta.Joinable;
+import org.apache.openjpa.jdbc.meta.RelationId;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.InternalException;
+import serp.util.Numbers;
+
+/**
+ * Basic {@link Row} implementation.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public class RowImpl
+ implements Row, Cloneable {
+
+ protected static final Object NULL = new Object();
+ protected static final int VALID = 2 << 0;
+
+ private static final int RAW = Integer.MIN_VALUE;
+
+ protected byte flags = 0;
+ private final Table _table;
+ private final int _action;
+ private final Object[] _vals;
+ private final int[] _types;
+
+ private String _sql = null;
+
+ /**
+ * Constructor.
+ *
+ * @param table the table the row is a part of
+ * @param action the action on the row
+ */
+ public RowImpl(Table table, int action) {
+ _table = table;
+ _action = action;
+
+ // we need room for values and types for all columns; if an update or
+ // delete, then we need to double that for where column conditions
+ int len = table.getColumns().length;
+ if (action != ACTION_INSERT)
+ len *= 2;
+ _vals = new Object[len];
+ _types = new int[len];
+ }
+
+ public Table getTable() {
+ return _table;
+ }
+
+ public int getAction() {
+ return _action;
+ }
+
+ public boolean isValid() {
+ return (flags & VALID) != 0;
+ }
+
+ public void setValid(boolean valid) {
+ if (valid)
+ flags |= VALID;
+ else
+ flags &= ~VALID;
+ }
+
+ /**
+ * This implementation does not track primary keys.
+ */
+ public OpenJPAStateManager getPrimaryKey() {
+ return null;
+ }
+
+ /**
+ * This implementation does not track failed objects.
+ */
+ public Object getFailedObject() {
+ return null;
+ }
+
+ /**
+ * This implementation does not track failed objects.
+ */
+ public void setFailedObject(Object failed) {
+ throw new InternalException();
+ }
+
+ /**
+ * Secondary rows cannot be dependent.
+ */
+ public boolean isDependent() {
+ return false;
+ }
+
+ /**
+ * Return the value set for update on the given column.
+ */
+ public Object getSet(Column col) {
+ return _vals[getSetIndex(col)];
+ }
+
+ /**
+ * Return the value set for where on the given column.
+ */
+ public Object getWhere(Column col) {
+ return _vals[getWhereIndex(col)];
+ }
+
+ public void setPrimaryKey(OpenJPAStateManager sm)
+ throws SQLException {
+ setPrimaryKey(null, sm);
+ }
+
+ public void setPrimaryKey(ColumnIO io, OpenJPAStateManager sm)
+ throws SQLException {
+ flushPrimaryKey(sm, io, true);
+ }
+
+ public void wherePrimaryKey(OpenJPAStateManager sm)
+ throws SQLException {
+ flushPrimaryKey(sm, null, false);
+ }
+
+ /**
+ * Flush the primary key values.
+ */
+ private void flushPrimaryKey(OpenJPAStateManager sm, ColumnIO io,
+ boolean set)
+ throws SQLException {
+ ClassMapping mapping = (ClassMapping) sm.getMetaData();
+ while (mapping.getTable() != _table)
+ mapping = mapping.getPCSuperclassMapping();
+ Column[] cols = mapping.getPrimaryKeyColumns();
+ flushJoinValues(sm, cols, cols, io, set);
+ }
+
+ public void setForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException {
+ setForeignKey(fk, null, sm);
+ }
+
+ public void setForeignKey(ForeignKey fk, ColumnIO io,
+ OpenJPAStateManager sm)
+ throws SQLException {
+ flushForeignKey(fk, io, sm, true);
+ }
+
+ public void whereForeignKey(ForeignKey fk, OpenJPAStateManager sm)
+ throws SQLException {
+ flushForeignKey(fk, null, sm, false);
+ }
+
+ /**
+ * Clear a circular foreign key.
+ */
+ public void clearForeignKey(ForeignKey fk)
+ throws SQLException {
+ _sql = null;
+ Column[] cols = fk.getColumns();
+ for (int i = 0; i < cols.length; i++)
+ _vals[getSetIndex(cols[i])] = null;
+ }
+
+ /**
+ * Flush the foreign key values.
+ */
+ private void flushForeignKey(ForeignKey fk, ColumnIO io,
+ OpenJPAStateManager sm, boolean set)
+ throws SQLException {
+ flushJoinValues(sm, fk.getPrimaryKeyColumns(), fk.getColumns(),
+ io, set);
+ if (sm != null) {
+ Column[] cols = fk.getConstantColumns();
+ int len = fk.getColumns().length;
+ Object obj;
+ int type;
+ for (int i = 0; i < cols.length; i++) {
+ obj = fk.getConstant(cols[i]);
+ type = cols[i].getJavaType();
+ if (set && canSet(io, i + len, obj == null))
+ setObject(cols[i], obj, type, false);
+ else if (!set)
+ whereObject(cols[i], obj, type);
+ }
+ }
+ }
+
+ /**
+ * Flush the given instance value to the given columns. Note that
+ * foreign keys may include columns also mapped by simple values. We
+ * use a priority mechanism to ensure that we do not let the nulling
+ * of a foreign key null columns also owned by simple values.
+ *
+ * @param to the instance being joined to
+ * @param toCols the columns being joined to
+ * @param fromCols the columns being joined from
+ * @param io information about I/O capabilities in this context
+ * @param set whether this should be flushed as an update or
+ * as a where condition
+ */
+ private void flushJoinValues(OpenJPAStateManager to, Column[] toCols,
+ Column[] fromCols, ColumnIO io, boolean set)
+ throws SQLException {
+ if (to == null) {
+ for (int i = 0; i < fromCols.length; i++) {
+ if (set && canSet(io, i, true))
+ setNull(fromCols[i]);
+ else if (!set)
+ whereNull(fromCols[i]);
+ }
+ return;
+ }
+ if (set && !canSetAny(io, fromCols.length, false))
+ return;
+
+ ClassMapping toMapping = (ClassMapping) to.getMetaData();
+ Joinable join;
+ Object val;
+ for (int i = 0; i < toCols.length; i++) {
+ // don't even translate join value if unsettable
+ if (set) {
+ if (_action == ACTION_INSERT && fromCols[i].isAutoAssigned())
+ continue;
+ if (!canSet(io, i, false))
+ continue;
+ }
+
+ join = toMapping.assertJoinable(toCols[i]);
+ val = join.getJoinValue(to, toCols[i], (JDBCStore) to.
+ getContext().getStoreManager().getInnermostDelegate());
+ if (set && val == null) {
+ if (canSet(io, i, true))
+ setNull(fromCols[i]);
+ } else if (set && val instanceof Raw)
+ setRaw(fromCols[i], val.toString());
+ else if (set)
+ setObject(fromCols[i], val, toCols[i].getJavaType(), false);
+ else if (val == null)
+ whereNull(fromCols[i]);
+ else if (val instanceof Raw)
+ whereRaw(fromCols[i], val.toString());
+ else
+ whereObject(fromCols[i], val, toCols[i].getJavaType());
+ }
+ }
+
+ /**
+ * Return true if any of the given column indexes are settable.
+ */
+ protected boolean canSetAny(ColumnIO io, int i, boolean nullValue) {
+ if (io == null)
+ return true;
+ if (_action == ACTION_INSERT)
+ return io.isAnyInsertable(i, nullValue);
+ if (_action == ACTION_UPDATE)
+ return io.isAnyUpdatable(i, nullValue);
+ return true;
+ }
+
+ /**
+ * Return true if the given column index is settable.
+ */
+ protected boolean canSet(ColumnIO io, int i, boolean nullValue) {
+ if (io == null)
+ return true;
+ if (_action == ACTION_INSERT)
+ return io.isInsertable(i, nullValue);
+ if (_action == ACTION_UPDATE)
+ return io.isUpdatable(i, nullValue);
+ return true;
+ }
+
+ public void setRelationId(Column col, OpenJPAStateManager sm,
+ RelationId rel)
+ throws SQLException {
+ setObject(col, rel.toRelationDataStoreValue(sm, col),
+ col.getJavaType(), false);
+ }
+
+ /**
+ * Clear a circular relation id.
+ */
+ public void clearRelationId(Column col)
+ throws SQLException {
+ _sql = null;
+ _vals[getSetIndex(col)] = null;
+ }
+
+ public void setArray(Column col, Array val)
+ throws SQLException {
+ setObject(col, val, JavaSQLTypes.ARRAY, false);
+ }
+
+ public void setAsciiStream(Column col, InputStream val, int length)
+ throws SQLException {
+ setObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.ASCII_STREAM, false);
+ }
+
+ public void setBigDecimal(Column col, BigDecimal val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.BIGDECIMAL, false);
+ }
+
+ public void setBigInteger(Column col, BigInteger val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.BIGINTEGER, false);
+ }
+
+ public void setBinaryStream(Column col, InputStream val, int length)
+ throws SQLException {
+ setObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.BINARY_STREAM, false);
+ }
+
+ public void setBlob(Column col, Blob val)
+ throws SQLException {
+ setObject(col, val, JavaSQLTypes.BLOB, false);
+ }
+
+ public void setBoolean(Column col, boolean val)
+ throws SQLException {
+ setObject(col, ((val) ? Boolean.TRUE : Boolean.FALSE),
+ JavaTypes.BOOLEAN, false);
+ }
+
+ public void setByte(Column col, byte val)
+ throws SQLException {
+ setObject(col, new Byte(val), JavaTypes.BYTE, false);
+ }
+
+ public void setBytes(Column col, byte[] val)
+ throws SQLException {
+ setObject(col, val, JavaSQLTypes.BYTES, false);
+ }
+
+ public void setCalendar(Column col, Calendar val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.CALENDAR, false);
+ }
+
+ public void setChar(Column col, char val)
+ throws SQLException {
+ setObject(col, new Character(val), JavaTypes.CHAR, false);
+ }
+
+ public void setCharacterStream(Column col, Reader val, int length)
+ throws SQLException {
+ setObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.CHAR_STREAM, false);
+ }
+
+ public void setClob(Column col, Clob val)
+ throws SQLException {
+ setObject(col, val, JavaSQLTypes.CLOB, false);
+ }
+
+ public void setDate(Column col, Date val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.DATE, false);
+ }
+
+ public void setDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ setObject(col, obj, JavaSQLTypes.SQL_DATE, false);
+ }
+
+ public void setDouble(Column col, double val)
+ throws SQLException {
+ setObject(col, new Double(val), JavaTypes.DOUBLE, false);
+ }
+
+ public void setFloat(Column col, float val)
+ throws SQLException {
+ setObject(col, new Float(val), JavaTypes.FLOAT, false);
+ }
+
+ public void setInt(Column col, int val)
+ throws SQLException {
+ setObject(col, Numbers.valueOf(val), JavaTypes.INT, false);
+ }
+
+ public void setLong(Column col, long val)
+ throws SQLException {
+ setObject(col, Numbers.valueOf(val), JavaTypes.LONG, false);
+ }
+
+ public void setLocale(Column col, Locale val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.LOCALE, false);
+ }
+
+ public void setNull(Column col)
+ throws SQLException {
+ setNull(col, false);
+ }
+
+ public void setNull(Column col, boolean overrideDefault)
+ throws SQLException {
+ setObject(col, null, col.getJavaType(), overrideDefault);
+ }
+
+ public void setNumber(Column col, Number val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.NUMBER, false);
+ }
+
+ public void setRaw(Column col, String val)
+ throws SQLException {
+ setObject(col, val, RAW, false);
+ }
+
+ public void setShort(Column col, short val)
+ throws SQLException {
+ setObject(col, new Short(val), JavaTypes.SHORT, false);
+ }
+
+ public void setString(Column col, String val)
+ throws SQLException {
+ setObject(col, val, JavaTypes.STRING, false);
+ }
+
+ public void setTime(Column col, Time val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ setObject(col, obj, JavaSQLTypes.TIME, false);
+ }
+
+ public void setTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ setObject(col, obj, JavaSQLTypes.TIMESTAMP, false);
+ }
+
+ public void setObject(Column col, Object val)
+ throws SQLException {
+ if (val instanceof Raw)
+ setObject(col, val, RAW, false);
+ else
+ setObject(col, val, col.getJavaType(), false);
+ }
+
+ public void whereArray(Column col, Array val)
+ throws SQLException {
+ whereObject(col, val, JavaSQLTypes.SQL_ARRAY);
+ }
+
+ public void whereAsciiStream(Column col, InputStream val, int length)
+ throws SQLException {
+ whereObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.ASCII_STREAM);
+ }
+
+ public void whereBigDecimal(Column col, BigDecimal val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.BIGDECIMAL);
+ }
+
+ public void whereBigInteger(Column col, BigInteger val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.BIGINTEGER);
+ }
+
+ public void whereBinaryStream(Column col, InputStream val, int length)
+ throws SQLException {
+ whereObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.BINARY_STREAM);
+ }
+
+ public void whereBlob(Column col, Blob val)
+ throws SQLException {
+ whereObject(col, val, JavaSQLTypes.BLOB);
+ }
+
+ public void whereBoolean(Column col, boolean val)
+ throws SQLException {
+ whereObject(col, ((val) ? Boolean.TRUE : Boolean.FALSE),
+ JavaTypes.BOOLEAN);
+ }
+
+ public void whereByte(Column col, byte val)
+ throws SQLException {
+ whereObject(col, new Byte(val), JavaTypes.BYTE);
+ }
+
+ public void whereBytes(Column col, byte[] val)
+ throws SQLException {
+ whereObject(col, val, JavaSQLTypes.BYTES);
+ }
+
+ public void whereCalendar(Column col, Calendar val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.CALENDAR);
+ }
+
+ public void whereChar(Column col, char val)
+ throws SQLException {
+ whereObject(col, new Character(val), JavaTypes.CHAR);
+ }
+
+ public void whereCharacterStream(Column col, Reader val, int length)
+ throws SQLException {
+ whereObject(col, (val == null) ? null : new Sized(val, length),
+ JavaSQLTypes.CHAR_STREAM);
+ }
+
+ public void whereClob(Column col, Clob val)
+ throws SQLException {
+ whereObject(col, val, JavaSQLTypes.CLOB);
+ }
+
+ public void whereDate(Column col, Date val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.DATE);
+ }
+
+ public void whereDate(Column col, java.sql.Date val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ whereObject(col, obj, JavaSQLTypes.SQL_DATE);
+ }
+
+ public void whereDouble(Column col, double val)
+ throws SQLException {
+ whereObject(col, new Double(val), JavaTypes.DOUBLE);
+ }
+
+ public void whereFloat(Column col, float val)
+ throws SQLException {
+ whereObject(col, new Float(val), JavaTypes.FLOAT);
+ }
+
+ public void whereInt(Column col, int val)
+ throws SQLException {
+ whereObject(col, Numbers.valueOf(val), JavaTypes.INT);
+ }
+
+ public void whereLong(Column col, long val)
+ throws SQLException {
+ whereObject(col, Numbers.valueOf(val), JavaTypes.LONG);
+ }
+
+ public void whereLocale(Column col, Locale val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.LOCALE);
+ }
+
+ public void whereNull(Column col)
+ throws SQLException {
+ whereObject(col, null, col.getJavaType());
+ }
+
+ public void whereNumber(Column col, Number val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.NUMBER);
+ }
+
+ public void whereRaw(Column col, String val)
+ throws SQLException {
+ whereObject(col, val, RAW);
+ }
+
+ public void whereShort(Column col, short val)
+ throws SQLException {
+ whereObject(col, new Short(val), JavaTypes.SHORT);
+ }
+
+ public void whereString(Column col, String val)
+ throws SQLException {
+ whereObject(col, val, JavaTypes.STRING);
+ }
+
+ public void whereTime(Column col, Time val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ whereObject(col, obj, JavaSQLTypes.TIME);
+ }
+
+ public void whereTimestamp(Column col, Timestamp val, Calendar cal)
+ throws SQLException {
+ Object obj;
+ if (val == null || cal == null)
+ obj = val;
+ else
+ obj = new Calendard(val, cal);
+ whereObject(col, obj, JavaSQLTypes.TIMESTAMP);
+ }
+
+ public void whereObject(Column col, Object val)
+ throws SQLException {
+ if (val instanceof Raw)
+ whereObject(col, val, RAW);
+ else
+ whereObject(col, val, col.getJavaType());
+ }
+
+ /**
+ * All set column methods delegate to this one. Set the given object
+ * unless this is an insert and the given column is auto-assigned.
+ */
+ protected void setObject(Column col, Object val, int metaType,
+ boolean overrideDefault)
+ throws SQLException {
+ // never set auto increment columns and honor column defaults
+ if (_action == ACTION_INSERT) {
+ if (col.isAutoAssigned())
+ return;
+ if (!overrideDefault && col.getDefaultString() != null)
+ return;
+ }
+ if (val == null && col.isNotNull())
+ val = JavaSQLTypes.getEmptyValue(col.getJavaType());
+ flush(col, val, metaType, true);
+ }
+
+ /**
+ * All where column methods delegate to this one.
+ */
+ protected void whereObject(Column col, Object val, int metaType)
+ throws SQLException {
+ flush(col, val, metaType, false);
+ }
+
+ /**
+ * Flush the given value as a set or where condition.
+ */
+ private void flush(Column col, Object val, int metaType, boolean set) {
+ int idx = (set) ? getSetIndex(col) : getWhereIndex(col);
+ _types[idx] = metaType;
+ if (val == null)
+ _vals[idx] = NULL;
+ else
+ _vals[idx] = val;
+ if (set || _action == ACTION_DELETE)
+ setValid(true);
+ }
+
+ /**
+ * Return the SQL for the operation on this row.
+ */
+ public String getSQL(DBDictionary dict) {
+ if (!isValid())
+ return "";
+ if (_sql == null)
+ _sql = generateSQL(dict);
+ return _sql;
+ }
+
+ /**
+ * Generate the SQL for this row; the result of this method is cached.
+ */
+ protected String generateSQL(DBDictionary dict) {
+ switch (getAction()) {
+ case ACTION_UPDATE:
+ return getUpdateSQL(dict);
+ case ACTION_INSERT:
+ return getInsertSQL(dict);
+ default:
+ return getDeleteSQL(dict);
+ }
+ }
+
+ /**
+ * Return the SQL for a prepared statement update on this row.
+ */
+ private String getUpdateSQL(DBDictionary dict) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("UPDATE ").append(dict.getFullName(getTable(), false)).
+ append(" SET ");
+
+ Column[] cols = getTable().getColumns();
+ boolean hasVal = false;
+ for (int i = 0; i < cols.length; i++) {
+ if (_vals[i] == null)
+ continue;
+
+ if (hasVal)
+ buf.append(", ");
+ buf.append(cols[i]);
+ if (_types[i] == RAW)
+ buf.append(" = ").append(_vals[i]);
+ else
+ buf.append(" = ?");
+ hasVal = true;
+ }
+
+ appendWhere(buf);
+ return buf.toString();
+ }
+
+ /**
+ * Return the SQL for a prepared statement insert on this row.
+ */
+ private String getInsertSQL(DBDictionary dict) {
+ StringBuffer buf = new StringBuffer();
+ StringBuffer vals = new StringBuffer();
+ buf.append("INSERT INTO ").
+ append(dict.getFullName(getTable(), false)).append(" (");
+
+ Column[] cols = getTable().getColumns();
+ boolean hasVal = false;
+ for (int i = 0; i < cols.length; i++) {
+ if (_vals[i] == null)
+ continue;
+
+ if (hasVal) {
+ buf.append(", ");
+ vals.append(", ");
+ }
+ buf.append(cols[i]);
+ if (_types[i] == RAW)
+ vals.append(_vals[i]);
+ else
+ vals.append("?");
+ hasVal = true;
+ }
+
+ buf.append(") VALUES (").append(vals.toString()).append(")");
+ return buf.toString();
+ }
+
+ /**
+ * Return the SQL for a prepared statement delete on this row.
+ */
+ private String getDeleteSQL(DBDictionary dict) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("DELETE FROM ").
+ append(dict.getFullName(getTable(), false));
+ appendWhere(buf);
+ return buf.toString();
+ }
+
+ /**
+ * Appends the where clause onto the given sql buffer.
+ */
+ private void appendWhere(StringBuffer buf) {
+ Column[] cols = getTable().getColumns();
+ boolean hasWhere = false;
+ for (int i = 0; i < cols.length; i++) {
+ if (_vals[getWhereIndex(cols[i])] == null)
+ continue;
+
+ if (!hasWhere)
+ buf.append(" WHERE ");
+ else
+ buf.append(" AND ");
+
+ // sqlserver seems to have problems using null parameters in the
+ // where clause
+ if (_vals[getWhereIndex(cols[i])] == NULL)
+ buf.append(cols[i]).append(" IS NULL");
+ else if (_types[i] == RAW)
+ buf.append(cols[i]).append(" = ").append(_vals[i]);
+ else
+ buf.append(cols[i]).append(" = ?");
+ hasWhere = true;
+ }
+ }
+
+ /**
+ * The number of parameters that will be set for this row.
+ */
+ public int getParameterCount() {
+ return _vals.length;
+ }
+
+ /**
+ * Flush the row's values to the given prepared statement.
+ */
+ public void flush(PreparedStatement stmnt, DBDictionary dict,
+ JDBCStore store)
+ throws SQLException {
+ flush(stmnt, 1, dict, store);
+ }
+
+ /**
+ * Flush the row's values to the given prepared statement.
+ */
+ public void flush(PreparedStatement stmnt, int idx, DBDictionary dict,
+ JDBCStore store)
+ throws SQLException {
+ Column[] cols = getTable().getColumns();
+
+ // this simple method works because the SQL is always prepared
+ // based on the indexing of the columns in the table object -- the
+ // same ordering we use when storing values and meta types. skip
+ // updates when setting params for DELETEs; the updates are just there
+ // to let us eval fk constraints
+ int i = (getAction() == ACTION_DELETE) ? cols.length : 0;
+ Column col;
+ Object val;
+ int half = _vals.length / 2;
+ for (; i < _vals.length; i++) {
+ if (_vals[i] == null)
+ continue;
+
+ // we don't set null params in the WHERE clause; we use the NULL
+ // keyword instead to satisfy sqlserver
+ if (_vals[i] == NULL && getAction() != ACTION_INSERT && i >= half)
+ continue;
+
+ // if this is an update the vals array will be 2 x the cols
+ // array length; it repeats for where values
+ if (i < cols.length)
+ col = cols[i];
+ else
+ col = cols[i - cols.length];
+
+ val = _vals[i];
+ if (val == NULL)
+ val = null;
+
+ if (val == null || _types[i] != RAW) {
+ dict.setTyped(stmnt, idx, val, col, _types[i], store);
+ idx++;
+ }
+ }
+ }
+
+ /**
+ * The array value array index for the given column's value.
+ */
+ private int getSetIndex(Column col) {
+ return col.getIndex();
+ }
+
+ /**
+ * The array value array index for the given column's value.
+ */
+ private int getWhereIndex(Column col) {
+ return col.getIndex() + getTable().getColumns().length;
+ }
+
+ /**
+ * Performs a proper deep clone.
+ */
+ public Object clone() {
+ RowImpl clone = newInstance(getTable(), getAction());
+ copyInto(clone, false);
+ return clone;
+ }
+
+ /**
+ * Return a new row.
+ */
+ protected RowImpl newInstance(Table table, int action) {
+ return new RowImpl(table, action);
+ }
+
+ /**
+ * Copy all values from this row into the given one.
+ *
+ * @param whereOnly if true, only copy where conditions
+ */
+ public void copyInto(RowImpl row, boolean whereOnly) {
+ int action = getAction();
+ int rowAction = row.getAction();
+
+ int start;
+ int len;
+ if (whereOnly) {
+ if (action == ACTION_INSERT || rowAction == ACTION_INSERT)
+ start = len = 0;
+ else
+ start = len = _vals.length / 2;
+ } else {
+ start = 0;
+ if (rowAction == ACTION_INSERT && action != ACTION_INSERT)
+ len = _vals.length / 2;
+ else
+ len = _vals.length;
+ }
+
+ System.arraycopy(_vals, start, row._vals, start, len);
+ System.arraycopy(_types, start, row._types, start, len);
+ if (isValid())
+ row.setValid(true);
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowManager.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowManager.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowManager.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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 org.apache.openjpa.jdbc.sql;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Manages rows during an insert/update/delete process. Row managers
+ * do not have to be threadsafe.
+ *
+ * @author Abe White
+ */
+public interface RowManager {
+
+ /**
+ * Return the row for the given table and owner object, or null if
+ * <code>create</code> is false and the row has not already been created.
+ * The action must be one of {@link Row#ACTION_INSERT},
+ * {@link Row#ACTION_UPDATE}, {@link Row#ACTION_DELETE}.
+ */
+ public Row getRow(Table table, int action, OpenJPAStateManager sm,
+ boolean create);
+
+ /**
+ * Return a row for the given secondary table.
+ * The action must be one of {@link Row#ACTION_INSERT},
+ * {@link Row#ACTION_UPDATE}, {@link Row#ACTION_DELETE}.
+ * Note that secondary rows are not considered when creating the foreign
+ * key dependency graph, with can cause constraint violations when using
+ * the <code>UPDATE</code> action. Only use this action if the secondary
+ * row does not have restrict-action foreign keys. Otherwise use both
+ * a delete and then an insert to perform the update.
+ */
+ public Row getSecondaryRow(Table table, int action);
+
+ /**
+ * Flush the secondary row; after flushing the row is available for reuse.
+ * It will retain all previously set values.
+ */
+ public void flushSecondaryRow(Row row)
+ throws SQLException;
+
+ /**
+ * Return a logical row representing an update that should be made to
+ * all rows of the given table. The action must be one of
+ * {@link Row#ACTION_UPDATE}, {@link Row#ACTION_DELETE}.
+ */
+ public Row getAllRows(Table table, int action);
+
+ /**
+ * Flush the logical row.
+ */
+ public void flushAllRows(Row row)
+ throws SQLException;
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowManager.java
------------------------------------------------------------------------------
svn:executable = *