mkalen 2005/04/06 06:29:33
Modified: src/java/org/apache/ojb/broker/accesslayer Tag:
OJB_1_0_RELEASE JdbcAccessImpl.java
StatementManager.java StatementsForClassImpl.java
src/java/org/apache/ojb/broker/platforms Tag:
OJB_1_0_RELEASE Platform.java
PlatformDefaultImpl.java PlatformHsqldbImpl.java
PlatformOracle9iImpl.java PlatformOracleImpl.java
Log:
OJB-6: Patch by Vadim Gritsenko - support for stored procedures returning
ResultSet. Add reflection lookup of Oracle-specific JDBC types.
Revision Changes Path
No revision
No revision
1.22.2.4 +67 -15
db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
Index: JdbcAccessImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java,v
retrieving revision 1.22.2.3
retrieving revision 1.22.2.4
diff -u -r1.22.2.3 -r1.22.2.4
--- JdbcAccessImpl.java 4 Mar 2005 22:39:05 -0000 1.22.2.3
+++ JdbcAccessImpl.java 6 Apr 2005 13:29:33 -0000 1.22.2.4
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.accesslayer;
-/* Copyright 2003-2004 The Apache Software Foundation
+/* Copyright 2003-2005 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.
@@ -35,6 +35,7 @@
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.ProcedureDescriptor;
import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
+import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -83,6 +84,16 @@
}
/**
+ * Helper Platform accessor method
+ *
+ * @return Platform for the current broker connection manager.
+ */
+ private Platform getPlatform()
+ {
+ return this.broker.serviceConnectionManager().getSupportedPlatform();
+ }
+
+ /**
* performs a DELETE operation against RDBMS.
* @param cld ClassDescriptor providing mapping information.
* @param obj The object to be deleted.
@@ -305,14 +316,31 @@
String sql =
broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
PreparedStatement stmt =
broker.serviceStatementManager().getPreparedStatement(cld, sql, scrollable);
- broker.serviceStatementManager().bindStatement(stmt, query, cld,
1);
- if (logger.isDebugEnabled())
- logger.debug("executeQuery: " + stmt);
+ ResultSet rs;
+ if (getPlatform().isCallableStatement(stmt))
+ {
+ // Query implemented as a stored procedure, which must
return a result set.
+ // Query sytax is: { ?= call PROCEDURE_NAME(?,...,?)}
+ getPlatform().registerOutResultSet((CallableStatement) stmt,
1);
+ broker.serviceStatementManager().bindStatement(stmt, query,
cld, 2);
+
+ if (logger.isDebugEnabled())
+ logger.debug("executeQuery: " + stmt);
+
+ stmt.execute();
+ rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
+ }
+ else
+ {
+ broker.serviceStatementManager().bindStatement(stmt, query,
cld, 1);
- ResultSet rs = stmt.executeQuery();
+ if (logger.isDebugEnabled())
+ logger.debug("executeQuery: " + stmt);
+
+ rs = stmt.executeQuery();
+ }
- retval = new ResultSetAndStatement(
-
broker.serviceConnectionManager().getSupportedPlatform(), stmt, rs);
+ retval = new ResultSetAndStatement(getPlatform(), stmt, rs);
return retval;
}
catch (PersistenceBrokerException e)
@@ -377,12 +405,26 @@
try
{
PreparedStatement stmt = stmtMan.getPreparedStatement(cld,
sqlStatement, scrollable);
- stmtMan.bindValues(stmt, values, 1);
- ResultSet rs = stmt.executeQuery();
+
+ ResultSet rs;
+ if (getPlatform().isCallableStatement(stmt))
+ {
+ // Query implemented as a stored procedure, which must
return a result set.
+ // Query sytax is: { ?= call PROCEDURE_NAME(?,...,?)}
+ getPlatform().registerOutResultSet((CallableStatement) stmt,
1);
+ stmtMan.bindValues(stmt, values, 2);
+ stmt.execute();
+ rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
+ }
+ else
+ {
+ stmtMan.bindValues(stmt, values, 1);
+ rs = stmt.executeQuery();
+ }
+
// as we return the resultset for further operations, we cannot
release the statement yet.
// that has to be done by the JdbcAccess-clients (i.e.
RsIterator, ProxyRsIterator and PkEnumeration.)
- retval = new ResultSetAndStatement(
-
broker.serviceConnectionManager().getSupportedPlatform(), stmt, rs);
+ retval = new ResultSetAndStatement(getPlatform(), stmt, rs);
return retval;
}
catch (PersistenceBrokerException e)
@@ -583,7 +625,18 @@
throw new PersistenceBrokerException("getSelectByPKStatement
returned a null statement");
}
broker.serviceStatementManager().bindSelect(stmt, oid, cld);
- rs = stmt.executeQuery();
+
+ if (getPlatform().isCallableStatement(stmt))
+ {
+ // If this is a stored procedure call, first argument is
ResultSet
+ stmt.execute();
+ rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
+ }
+ else
+ {
+ rs = stmt.executeQuery();
+ }
+
// data available read object, else return null
if (rs.next())
{
@@ -655,10 +708,9 @@
PreparedStatement stmt)
throws PersistenceBrokerSQLException
{
-
// If the procedure descriptor is null or has no return values or
// if the statement is not a callable statment, then we're done.
- if ((proc == null) || (!proc.hasReturnValues()) || (!(stmt
instanceof CallableStatement)))
+ if ((proc == null) || (!proc.hasReturnValues()) ||
(!getPlatform().isCallableStatement(stmt)))
{
return;
}
1.47.2.3 +14 -6
db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
Index: StatementManager.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
retrieving revision 1.47.2.2
retrieving revision 1.47.2.3
diff -u -r1.47.2.2 -r1.47.2.3
--- StatementManager.java 2 Mar 2005 20:32:35 -0000 1.47.2.2
+++ StatementManager.java 6 Apr 2005 13:29:33 -0000 1.47.2.3
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.accesslayer;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -449,12 +449,13 @@
}
/**
- * binds the Identities Primary key values to the statement
+ * Binds the Identities Primary key values to the statement.
*/
public void bindSelect(PreparedStatement stmt, Identity oid,
ClassDescriptor cld) throws SQLException
{
ValueContainer[] values = null;
int i = 0;
+ int j = 0;
if (cld == null)
{
@@ -462,10 +463,17 @@
}
try
{
+ if (m_platform.isCallableStatement(stmt))
+ {
+ // First argument is the result set
+ m_platform.registerOutResultSet((CallableStatement) stmt, 1);
+ j++;
+ }
+
values = getKeyValues(m_broker, cld, oid);
- for (i = 0; i < values.length; i++)
+ for (/*void*/; i < values.length; i++, j++)
{
- setObjectForStatement(stmt, i + 1, values[i].getValue(),
values[i].getJdbcType().getType());
+ setObjectForStatement(stmt, j + 1, values[i].getValue(),
values[i].getJdbcType().getType());
}
}
catch (SQLException e)
@@ -699,7 +707,7 @@
// Figure out if we are using a callable statement. If we are, then
we
// will need to register one or more output parameters.
CallableStatement callable = null;
- if (stmt instanceof CallableStatement)
+ if (m_platform.isCallableStatement(stmt))
{
callable = (CallableStatement) stmt;
}
1.22.2.2 +8 -4
db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassImpl.java
Index: StatementsForClassImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementsForClassImpl.java,v
retrieving revision 1.22.2.1
retrieving revision 1.22.2.2
diff -u -r1.22.2.1 -r1.22.2.2
--- StatementsForClassImpl.java 13 Jan 2005 15:50:05 -0000 1.22.2.1
+++ StatementsForClassImpl.java 6 Apr 2005 13:29:33 -0000 1.22.2.2
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.accesslayer;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -44,6 +44,8 @@
{
private Logger log =
LoggerFactory.getLogger(StatementsForClassImpl.class);
+ private static final String CALL = "{ ?= call";
+
/**
* sets the escape processing mode
*/
@@ -175,7 +177,8 @@
PreparedStatement stmt = null;
try
{
- stmt = prepareStatement(con, sql, scrollable);
+ // TODO: Vadim Gritsenko FIXME: Improve check for stored
procedure call syntax
+ stmt = prepareStatement(con, sql, scrollable,
!sql.toLowerCase().startsWith(CALL));
}
catch (java.sql.SQLException ex)
{
@@ -193,7 +196,8 @@
}
try
{
- return prepareStatement(con, selectByPKSql,
Query.NOT_SCROLLABLE);
+ // TODO: mkalen: review unconditional
createPreparedStatement=true:
+ return prepareStatement(con, selectByPKSql,
Query.NOT_SCROLLABLE, true);
}
catch (SQLException ex)
{
No revision
No revision
1.24.2.1 +21 -3
db-ojb/src/java/org/apache/ojb/broker/platforms/Platform.java
Index: Platform.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/Platform.java,v
retrieving revision 1.24
retrieving revision 1.24.2.1
diff -u -r1.24 -r1.24.2.1
--- Platform.java 4 Apr 2004 23:53:35 -0000 1.24
+++ Platform.java 6 Apr 2005 13:29:33 -0000 1.24.2.1
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.platforms;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -224,5 +224,23 @@
* @return
*/
public String getEscapeClause(LikeCriteria aCriteria);
-
+
+ /**
+ * Determines whether statement is [EMAIL PROTECTED] CallableStatement}
or not.
+ *
+ * @param stmt the statement
+ * @return true if statement is [EMAIL PROTECTED] CallableStatement}.
+ */
+ public boolean isCallableStatement(PreparedStatement stmt);
+
+ /**
+ * Registers call argument at <code>position</code> as returning
+ * a [EMAIL PROTECTED] ResultSet} value.
+ *
+ * @param stmt the statement
+ * @param position argument position
+ */
+ public void registerOutResultSet(CallableStatement stmt, int position)
+ throws SQLException;
+
}
1.27.2.2 +26 -3
db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java
Index: PlatformDefaultImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java,v
retrieving revision 1.27.2.1
retrieving revision 1.27.2.2
diff -u -r1.27.2.1 -r1.27.2.2
--- PlatformDefaultImpl.java 19 Aug 2004 08:12:38 -0000 1.27.2.1
+++ PlatformDefaultImpl.java 6 Apr 2005 13:29:33 -0000 1.27.2.2
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.platforms;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -219,7 +219,7 @@
public void setObjectForStatement(PreparedStatement ps, int index,
Object value, int sqlType)
throws SQLException
{
- if ((value instanceof String) && (sqlType == Types.LONGVARCHAR))
+ if ((sqlType == Types.LONGVARCHAR) && (value instanceof String))
{
String s = (String) value;
ps.setCharacterStream(index, new StringReader(s), s.length());
@@ -246,6 +246,11 @@
}
else
{
+ if (log.isDebugEnabled()) {
+ log.debug("Default setObjectForStatement, sqlType=" +
sqlType +
+ ", value class=" + (value == null ? "NULL!" :
value.getClass().getName())
+ + ", value=" + value);
+ }
ps.setObject(index, value, sqlType);
}
}
@@ -405,4 +410,22 @@
return "";
}
}
+
+ /**
+ * @see
org.apache.ojb.broker.platforms.Platform#isCallableStatement(java.sql.PreparedStatement)
+ */
+ public boolean isCallableStatement(PreparedStatement stmt)
+ {
+ return stmt instanceof CallableStatement;
+ }
+
+ /**
+ * @see
org.apache.ojb.broker.platforms.Platform#registerOutResultSet(java.sql.CallableStatement,
int)
+ */
+ public void registerOutResultSet(CallableStatement stmt, int position)
+ throws SQLException
+ {
+ stmt.registerOutParameter(position, Types.OTHER);
+ }
+
}
1.7.2.1 +12 -3
db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java
Index: PlatformHsqldbImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -r1.7 -r1.7.2.1
--- PlatformHsqldbImpl.java 4 Apr 2004 23:53:35 -0000 1.7
+++ PlatformHsqldbImpl.java 6 Apr 2005 13:29:33 -0000 1.7.2.1
@@ -1,7 +1,6 @@
package org.apache.ojb.broker.platforms;
-
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -16,6 +15,7 @@
* limitations under the License.
*/
+import java.sql.PreparedStatement;
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific
@@ -65,5 +65,14 @@
return true;
}
+ /**
+ * HSQLDB does not implement CallableStatement.
+ *
+ * @see
org.apache.ojb.broker.platforms.Platform#isCallableStatement(java.sql.PreparedStatement)
+ */
+ public boolean isCallableStatement(PreparedStatement stmt)
+ {
+ return false;
+ }
}
1.13.2.8 +8 -4
db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java
Index: PlatformOracle9iImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracle9iImpl.java,v
retrieving revision 1.13.2.7
retrieving revision 1.13.2.8
diff -u -r1.13.2.7 -r1.13.2.8
--- PlatformOracle9iImpl.java 17 Mar 2005 23:45:05 -0000 1.13.2.7
+++ PlatformOracle9iImpl.java 6 Apr 2005 13:29:33 -0000 1.13.2.8
@@ -165,11 +165,10 @@
/**
* Default constructor.
- * Runs static init needed for Oracle-extensions and large BLOB/CLOB
support to function.
*/
public PlatformOracle9iImpl()
{
- initOracleReflectedVars();
+ super();
}
/**
@@ -542,7 +541,12 @@
return null;
}
- protected static void initOracleReflectedVars() {
+ /**
+ * Initializes static variables needed for Oracle-extensions and large
BLOB/CLOB support.
+ */
+ protected void initOracleReflectedVars()
+ {
+ super.initOracleReflectedVars();
try
{
/*
1.20.2.3 +53 -2
db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java
Index: PlatformOracleImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java,v
retrieving revision 1.20.2.2
retrieving revision 1.20.2.3
diff -u -r1.20.2.2 -r1.20.2.3
--- PlatformOracleImpl.java 2 Mar 2005 16:25:28 -0000 1.20.2.2
+++ PlatformOracleImpl.java 6 Apr 2005 13:29:33 -0000 1.20.2.3
@@ -1,6 +1,6 @@
package org.apache.ojb.broker.platforms;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -17,6 +17,7 @@
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.ojb.broker.util.ClassHelper;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
@@ -48,9 +49,24 @@
protected static final int THIN_BLOB_MAX_SIZE = 2000;
// Oracle:thin handles direct CLOB insert and update <= 4000
protected static final int THIN_CLOB_MAX_SIZE = 4000;
+
+ /**
+ * Field value of <code>oracle.jdbc.OracleTypes.CURSOR</code>.
+ * @see #initOracleReflectedVars
+ */
+ protected static int ORACLE_JDBC_TYPE_CURSOR = -10;
+
private Logger logger =
LoggerFactory.getLogger(PlatformOracleImpl.class);
/**
+ * Default constructor.
+ */
+ public PlatformOracleImpl()
+ {
+ initOracleReflectedVars();
+ }
+
+ /**
* Method prepareNextValProcedureStatement implementation
* is simply copied over from PlatformMsSQLServerImpl class.
* @see
org.apache.ojb.broker.platforms.Platform#prepareNextValProcedureStatement(java.sql.Connection,
java.lang.String, java.lang.String)
@@ -224,6 +240,15 @@
}
/**
+ * @see
org.apache.ojb.broker.platforms.Platform#registerOutResultSet(java.sql.CallableStatement,
int)
+ */
+ public void registerOutResultSet(CallableStatement stmt, int position)
+ throws SQLException
+ {
+ stmt.registerOutParameter(position, ORACLE_JDBC_TYPE_CURSOR);
+ }
+
+ /**
* Checks if the supplied connection is using the Oracle thin driver.
*
* @param conn database connection for which to check JDBC-driver
@@ -254,4 +279,30 @@
return false;
}
+ /**
+ * Initializes static variables needed for getting Oracle-specific JDBC
types.
+ */
+ protected void initOracleReflectedVars()
+ {
+ try
+ {
+ // Check for Oracle-specific Types class
+ final Class oracleTypes =
ClassHelper.getClass("oracle.jdbc.OracleTypes", false);
+ final Field cursorField = oracleTypes.getField("CURSOR");
+ ORACLE_JDBC_TYPE_CURSOR = cursorField.getInt(null);
+ }
+ catch (ClassNotFoundException e)
+ {
+ log.warn("PlatformOracleImpl could not find Oracle JDBC
classes");
+ }
+ catch (NoSuchFieldException e)
+ {
+ log.warn("PlatformOracleImpl could not find Oracle JDBC type
fields");
+ }
+ catch (IllegalAccessException e)
+ {
+ log.warn("PlatformOracleImpl could not get Oracle JDBC type
values");
+ }
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]