-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Army wrote:
> Is there a reason why we have the check for missingCodePoint AFTER the
> "switch", instead of before?
The attached patch has this change.
> might as well get it in print--have you run the derbynet and other
> related suites/tests with these changes, to make sure there aren't any
> regressions?
>
>
I ran derbyAll with the previous patch and derbynetmats with this
latest change that only affects network server.
Kathey Marsden wrote:
>> Attached is the updated patch for Network Server XAMGR Level 7 support.
>> I think I am ready to call a vote on whether it is OK to check this in.
>> As soon as I can check it in, I will be able to coordinate the changes
>> to the IBM Universal JDBC Driver. Even though you won't be able to test
>> the XA support until we have the client changes, I'd encourage voters
>> to test these changes with their existing network server applications to
>> ensure no regressions.
>>
>>
>>
Vote will now close end of day Tuesday, December 14.
Apologies for somehow accidentally sending the vote to derby-user
originally. Thanks to Dan for catching that.
See
http://nagoya.apache.org/eyebrowse/[EMAIL PROTECTED]&msgNo=311
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFBuhozG0h36bFmkocRAhxjAJ4/Irxv+7GtADKTuw7tx4VJLyph0gCfXgQw
NtiL3WUX3AoXzXFj6nQCjGA=
=C4iX
-----END PGP SIGNATURE-----
Index: tools/ant/properties/release.properties
===================================================================
--- tools/ant/properties/release.properties (revision 106968)
+++ tools/ant/properties/release.properties (working copy)
@@ -3,7 +3,7 @@
minor=0
maint=2000001
#drdamaint should be reset to 0 with every minor release
-drdamaint=0
+drdamaint=1
beta=false
vendor=The Apache Software Foundation
eversion=10.0
Index: java/tools/org/apache/derby/impl/tools/ij/xaHelper.java
===================================================================
--- java/tools/org/apache/derby/impl/tools/ij/xaHelper.java (revision
106968)
+++ java/tools/org/apache/derby/impl/tools/ij/xaHelper.java (working copy)
@@ -52,18 +52,24 @@
private ConnectionPoolDataSource currentCPDataSource;
private PooledConnection currentPooledConnection;
- private String framework_property;
+ private boolean isJCC;
+ private String framework;
xaHelper()
{
}
- public void setFramework(String framework)
- {
- this.framework_property = framework_property;
- }
+ public void setFramework(String fm)
+ {
+ framework = fm.toUpperCase();
+ if (framework.endsWith("NET") ||
+ framework.equals("DB2JCC"))
+ isJCC = true;
+
+ }
+
private Xid makeXid(int xid)
{
return new ijXid(xid, databaseName.getBytes());
@@ -78,12 +84,39 @@
currentXADataSource = (XADataSource)
getXADataSource();
databaseName = parser.stringValue(dbname.image);
+
+ if (isJCC)
+ {
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"ServerName", "localhost");
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"portNumber", 1527);
+
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"driverType", 4);
+
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"retrieveMessagesFromServerOnGetMessage", true);
+ String user;
+ String password;
+ user = "APP";
+ password = "APP";
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"user", user);
+ xaHelper.setDataSourceProperty(currentXADataSource,
+
"password", password);
+ //xaHelper.setDataSourceProperty(currentXADataSource,
+ //"traceFile", "trace.out." + framework);
+ }
+
xaHelper.setDataSourceProperty(currentXADataSource,
"databaseName", databaseName);
- xaHelper.setDataSourceProperty(currentXADataSource,
"dataSourceName", databaseName);
if (shutdown != null &&
shutdown.toString().toLowerCase(Locale.ENGLISH).equals("shutdown"))
- {
- xaHelper.setDataSourceProperty(currentXADataSource,
"shutdownDatabase", "shutdown");
+ {
+ if (isJCC)
+
xaHelper.setDataSourceProperty(currentXADataSource,"databaseName", databaseName
+ ";shutdown=true");
+ else
+
xaHelper.setDataSourceProperty(currentXADataSource, "shutdownDatabase",
"shutdown");
// do a getXAConnection to shut it down */
currentXADataSource.getXAConnection().getConnection();
@@ -95,13 +128,16 @@
{
if
(create.toLowerCase(java.util.Locale.ENGLISH).equals("create"))
{
+ if (isJCC)
+
xaHelper.setDataSourceProperty(currentXADataSource,"databaseName", databaseName
+ ";create=true");
+ else
xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", "create");
-
- /* do a getXAConnection to create it */
- XAConnection conn =
currentXADataSource.getXAConnection();
- conn.close();
-
-
xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", null);
+
+ /* do a getXAConnection to create it */
+ XAConnection conn =
currentXADataSource.getXAConnection();
+ conn.close();
+
+
xaHelper.setDataSourceProperty(currentXADataSource, "createDatabase", null);
}
}
}
@@ -347,7 +383,6 @@
else // StandardException or run time exception, log it first
{
String info =
LocalizedResource.getMessage("IJ_01SeeClouLog", t.toString(), t.getMessage());
- t.printStackTrace(System.out);
throw new ijException(info);
}
}
@@ -450,7 +485,11 @@
// if we new it directly, then it will the tools.jar file to
bloat.
try
{
- return
(XADataSource)(Class.forName("org.apache.derby.jdbc.EmbeddedXADataSource").newInstance());
+ if (isJCC)
+ return (XADataSource)
+
(Class.forName("com.ibm.db2.jcc.DB2XADataSource").newInstance());
+ else
+ return
(XADataSource)(Class.forName("org.apache.derby.jdbc.EmbeddedXADataSource").newInstance());
}
catch(ClassNotFoundException cnfe) {
throw new
ijException(LocalizedResource.getMessage("IJ_XAClass"));
@@ -462,7 +501,24 @@
}
private static final Class[] STRING_P = { "".getClass() };
private static final Class[] INT_P = { Integer.TYPE };
+ private static final Class[] BOOLEAN_P = {Boolean.TYPE };
+ private static void setDataSourceProperty(Object ds, String property,
int
+
value) throws SQLException
+ {
+ String methodName =
+ "set" + Character.toUpperCase(property.charAt(0)) +
property.substring(1);
+ try {
+ java.lang.reflect.Method m =
ds.getClass().getMethod(methodName, INT_P);
+ m.invoke(ds, new Object[] {new Integer(value)});
+ }
+ catch (Exception e)
+ {
+ throw new SQLException(property + " ???" +
e.getMessage());
+ }
+
+ }
+
private static void setDataSourceProperty(Object ds, String property,
String value) throws SQLException {
String methodName =
@@ -478,8 +534,24 @@
//m.invoke(ds, new Object[] {Integer.valueOf(value)});
}
}
+
+private static void setDataSourceProperty(Object ds, String property, boolean
value) throws SQLException {
+
+ String methodName =
+ "set" + Character.toUpperCase(property.charAt(0)) +
property.substring(1);
+
+ try {
+ java.lang.reflect.Method m =
ds.getClass().getMethod(methodName, BOOLEAN_P);
+ m.invoke(ds, new Object[] {new Boolean(value)});
+ return;
+ } catch (Exception nsme) {
+ throw new SQLException(property + " ???");
+ }
+ }
}
+
+
class ijXid implements Xid, java.io.Serializable
{
private static final long serialVersionUID = 64467452100036L;
Index: java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
===================================================================
--- java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
(revision 106968)
+++ java/engine/org/apache/derby/iapi/jdbc/BrokeredConnection.java
(working copy)
@@ -416,5 +416,42 @@
return new BrokeredCallableStatement(statementControl,
getJDBCLevel(), sql);
}
+ /**
+ * set the DrdaId for this connection. The drdaID prints with the
+ * statement text to the errror log
+ * @param drdaID drdaID to be used for this connection
+ *
+ */
+ public void setDrdaID(String drdaID)
+ {
+ control.setDrdaID(drdaID);
+ }
+
+ /**
+ * Set the internal isolation level to use for preparing statements.
+ * Subsequent prepares will use this isoalation level
+ * @param level - internal isolation level
+ * @throws SQLException
+ * @see EmbedConnection#setPrepareIsolation
+ *
+ */
+ public void setPrepareIsolation(int level) throws SQLException
+ {
+ control.setPrepareIsolation(level);
+ }
+
+ /**
+ * get the isolation level that is currently being used to prepare
+ * statements (used for network server)
+ *
+ * @throws SQLException
+ * @return current prepare isolation level
+ * @see EmbedConnection#getPrepareIsolation
+ */
+ public int getPrepareIsolation() throws SQLException
+ {
+ return control.getPrepareIsolation();
+ }
+
protected int getJDBCLevel() { return 2;}
}
Index: java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
===================================================================
--- java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
(revision 106968)
+++ java/engine/org/apache/derby/iapi/jdbc/BrokeredConnectionControl.java
(working copy)
@@ -88,4 +88,26 @@
Optionally wrap a CallableStatement with an CallableStatement.
*/
public CallableStatement wrapStatement(CallableStatement realStatement,
String sql) throws SQLException;
+
+ /** Set drdaID of underlying connection
+ * @param drdaID - drdaId of connection
+ */
+ public void setDrdaID(String drdaID);
+
+ /**
+ * Set the internal isolation level to use for preparing statements.
+ * used for Network Server
+ * @param level - isolation level for prepared statements
+ */
+ public void setPrepareIsolation(int level) throws SQLException;
+
+ /**
+ * Get the internal isolation level to use for preparing statements.
+ * @return prepare isolation level
+ */
+ public int getPrepareIsolation() throws SQLException;
+
}
+
+
+
Index: java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
===================================================================
--- java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
(revision 106968)
+++ java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
(working copy)
@@ -392,4 +392,41 @@
public CallableStatement wrapStatement(CallableStatement cs, String
sql) throws SQLException {
return cs;
}
+
+ /**
+ * set DrdaId for this connection.
+ * Used by network server to identify connection.
+ * @param drdaID drda connection identifier
+ */
+ public void setDrdaID(String drdaID)
+ {
+ realConnection.setDrdaID(drdaID);
+ }
+
+ /**
+ * Set the internal isolation level to use for preparing statements.
+ * Subsequent prepares will use this isoalation level
+ * @param level internal isolation level
+ *
+ * @throws SQLException
+ * @see BrokeredConnection#setPrepareIsolation
+ *
+ */
+ public void setPrepareIsolation(int level) throws SQLException
+ {
+ realConnection.setPrepareIsolation(level);
+ }
+
+ /**
+ * Get prepare isolation level.
+ * For network server this will be the isolation level at which
statements
+ * will be prepared.
+ * @return isolation level
+ */
+ public int getPrepareIsolation() throws SQLException
+ {
+ return realConnection.getPrepareIsolation();
+ }
+
}
+
Index: java/drda/org/apache/derby/impl/drda/DRDAStatement.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/DRDAStatement.java (revision
106968)
+++ java/drda/org/apache/derby/impl/drda/DRDAStatement.java (working copy)
@@ -38,9 +38,8 @@
import org.apache.derby.iapi.services.info.JVMInfo;
import org.apache.derby.impl.jdbc.Util;
import org.apache.derby.impl.jdbc.EmbedConnection;
+import org.apache.derby.iapi.jdbc.BrokeredConnection;
import org.apache.derby.impl.jdbc.EmbedResultSet;
-import org.apache.derby.impl.jdbc.EmbedPreparedStatement;
-import org.apache.derby.impl.jdbc.EmbedCallableStatement;
import org.apache.derby.impl.jdbc.EmbedParameterSetMetaData;
import org.apache.derby.iapi.services.sanity.SanityManager;
import org.apache.derby.impl.jdbc.EmbedSQLException;
@@ -78,12 +77,13 @@
protected int withHoldCursor = -1; // hold cursor after commit
attribute.
protected int isolationLevel; //JCC isolation level for
Statement
protected String cursorName;
- protected int scrollType; // Sensitive or
Insensitive scroll attribute
- protected int concurType; // Concurency type
+ protected int scrollType = ResultSet.TYPE_FORWARD_ONLY;
// Sensitive or Insensitive scroll attribute
+ protected int concurType = ResultSet.CONCUR_READ_ONLY;;
// Concurency type
protected long rowCount; // Number of rows we
have processed
protected byte [] rslsetflg; // Result Set Flags
protected int maxrslcnt; // Maximum Result set
count
protected PreparedStatement ps; // Prepared statement
+ protected EmbedParameterSetMetaData stmtPmeta; // param metadata
protected boolean isCall;
protected String procName; // callable statement's
method name
private int[] outputTypes; // jdbc type for output
parameter or NOT_OUTPUT_PARAM
@@ -252,7 +252,38 @@
currentDrdaRs.clearExtDtaObjects();
}
+ /**
+ *
+ * get resultSetHoldability with reflection.
+ * We need to use reflection so we can use hold cursors with 1.3.1.
+ * And also since our statement might be a BrokeredStatement.
+ *
+ * @return the resultSet holdability for the prepared statement
+ *
+ */
+ protected int getResultSetHoldability() throws SQLException
+ {
+ Statement rsstmt = null;
+ ResultSet rs = getResultSet();
+ int holdValue = -1;
+ if (rs != null)
+ rsstmt = rs.getStatement();
+ else
+ rsstmt = getPreparedStatement();
+
+ Class[] getResultSetHoldabilityParam = {};
+ try {
+ Method sh =
+
rsstmt.getClass().getMethod("getResultSetHoldability",
getResultSetHoldabilityParam);
+ holdValue = ((Integer) sh.invoke(ps,null)).intValue();
+ }
+ catch (Exception e) {
+ handleReflectionException(e);
+ }
+ return holdValue;
+ }
+
/*
* Is lob object nullable
* @param index - offset starting with 0
@@ -380,6 +411,14 @@
return currentDrdaRs.scrollType;
}
+ /**
+ * is this a scrollable cursor?
+ * return true if this is not a forward only cursor
+ */
+ protected boolean isScrollable()
+ {
+ return (getScrollType() != ResultSet.TYPE_FORWARD_ONLY);
+ }
protected void setConcurType(int scrollType)
{
@@ -461,41 +500,8 @@
return ps;
}
parsePkgidToFindHoldability();
- if (withHoldCursor ==
JDBC30Translation.CLOSE_CURSORS_AT_COMMIT) {
- if (JVMInfo.JDK_ID == 2) {//need to use reflection for
holdability for jdk 1.3
- //prepareStatement takes 4 parameters
- Class[] PREP_STMT_PARAM = { String.class,
Integer.TYPE, Integer.TYPE, Integer.TYPE };
- Object[] PREP_STMT_ARG = { sqlStmt, new
Integer(scrollType),
- new Integer(concurType), new
Integer(JDBC30Translation.CLOSE_CURSORS_AT_COMMIT)};
- try {
- //create a prepared statement with
close cursor at commit using reflection.
- Method sh =
database.getConnection().getClass().getMethod("prepareStatement",
PREP_STMT_PARAM);
- ps = (PreparedStatement)
(sh.invoke(database.getConnection(), PREP_STMT_ARG));
- } catch (InvocationTargetException itex) {
- Throwable e = itex.getTargetException();
- //prepareStatement can only throw
SQLExcepton
- if (e instanceof SQLException)
- {
- throw (SQLException) e;
- }
- else
- throw Util.javaException(e);
- }
- catch (Exception e) {
- // invoke can throw
IllegalAccessException or
- // IllegalArgumentException, but these
should not
- // occur from this code. Just in case
we will throw it
- throw Util.javaException(e);
- }
- } else if (JVMInfo.JDK_ID >= 4)
- ps =
((EmbedConnection)(database.getConnection())).prepareStatement(sqlStmt,
scrollType, concurType, withHoldCursor);
- else //no holdability change support for jdk 12 and less
- ps =
database.getConnection().prepareStatement(sqlStmt);
- } else if (scrollType != 0)
- ps = database.getConnection().prepareStatement(sqlStmt,
scrollType, concurType);
- else
- ps = database.getConnection().prepareStatement(sqlStmt);
-
+ ps = prepareStatementJDBC3(sqlStmt, scrollType, concurType,
+
withHoldCursor);
// beetle 3849 - Need to change the cursor name to what
// JCC thinks it will be, since there is no way in the
// protocol to communicate the actual cursor name. JCC keeps
@@ -552,7 +558,7 @@
}
// For normal selects we are done, but procedures might
// have more resultSets
- }while (isCallable && ((EmbedPreparedStatement)
ps).getMoreResults(JDBC30Translation.KEEP_CURRENT_RESULT));
+ }while (isCallable &&
getMoreResults(JDBC30Translation.KEEP_CURRENT_RESULT));
return hasResultSet;
@@ -928,7 +934,8 @@
return currentDrdaRs.wasExplicitlyClosed();
}
- /** Clean up statements and resultSet
+ /**
+ * Clean up statements and resultSet
*
*/
protected void close() throws SQLException
@@ -943,9 +950,10 @@
resultSetKeyList = null;
numResultSets = 0;
ps = null;
+ stmtPmeta = null;
stmt = null;
- scrollType = 0;
- concurType = 0;
+ scrollType = ResultSet.TYPE_FORWARD_ONLY;
+ concurType = ResultSet.CONCUR_READ_ONLY;;
withHoldCursor = -1;
rowCount = 0;
rslsetflg = null;
@@ -1081,8 +1089,8 @@
{
if (ps != null && ps instanceof CallableStatement)
{
- EmbedParameterSetMetaData pmeta =
((EmbedCallableStatement)
-
ps).getEmbedParameterSetMetaData();
+ EmbedParameterSetMetaData pmeta =
getParameterMetaData();
+
return Math.min(pmeta.getPrecision(index),
FdocaConstants.NUMERIC_MAX_PRECISION);
@@ -1102,8 +1110,7 @@
{
if (ps != null && ps instanceof CallableStatement)
{
- EmbedParameterSetMetaData pmeta =
((EmbedCallableStatement)
-
ps).getEmbedParameterSetMetaData();
+ EmbedParameterSetMetaData pmeta =
getParameterMetaData();
return
Math.min(pmeta.getScale(index),FdocaConstants.NUMERIC_MAX_PRECISION);
}
else
@@ -1215,7 +1222,7 @@
else
{
s += indent + pkgid + sectionNumber ;
- s += "\t" + ((EmbedPreparedStatement) ps).getSQLText();
+ s += "\t" + getSQLText();
}
return s;
}
@@ -1270,7 +1277,7 @@
private void setupCallableStatementParams(CallableStatement cs) throws
SQLException
{
- EmbedParameterSetMetaData pmeta =
((EmbedCallableStatement) cs).getEmbedParameterSetMetaData();
+ EmbedParameterSetMetaData pmeta = getParameterMetaData();
int numElems = pmeta.getParameterCount();
for ( int i = 0; i < numElems; i ++)
@@ -1467,6 +1474,149 @@
}
}
+
+
+ /**
+ * prepare a statement using reflection so that server can run on
jdk131
+ * and still pass holdability.
+ * parameters are passed on to either the EmbedConnection or
+ * BrokeredConnection prepareStatement() method.
+ * @param sqlStmt - SQL statement text
+ * @param scrollType - scroll type
+ * @param concurtype - concurrency type
+ * @param withHoldCursor - holdability
+ *
+ * @throws SQLException
+ * @return Prepared Statement
+ * @see java.sql.Connection#prepareStatement
+ */
+ private PreparedStatement prepareStatementJDBC3(String sqlStmt, int
+
scrollType, int concurType,
+
int withHoldCursor) throws SQLException
+ {
+ PreparedStatement lps = null;
+
+ // If holdability is still uninitialized, default is
HOLD_CURSORS_OVER_COMMIT
+ int resultSetHoldability = (withHoldCursor == -1) ?
+ resultSetHoldability =
JDBC30Translation.HOLD_CURSORS_OVER_COMMIT :
+ withHoldCursor;
+
+ //prepareStatement takes 4 parameters
+ Class[] PREP_STMT_PARAM = { String.class, Integer.TYPE,
Integer.TYPE, Integer.TYPE };
+ Object[] PREP_STMT_ARG = { sqlStmt, new Integer(scrollType),
+ new
Integer(concurType), new Integer(resultSetHoldability)};
+ try {
+ //create a prepared statement with hold cursor over
commit using reflection.
+ Method sh =
database.getConnection().getClass().getMethod("prepareStatement",
PREP_STMT_PARAM);
+ lps = (PreparedStatement)
(sh.invoke(database.getConnection(), PREP_STMT_ARG));
+ } catch (Exception e) {
+ handleReflectionException(e);
+ }
+
+ return lps;
+ }
+
+
+ /**
+ * Get parameter metadata from EmbedPreparedStatement or
+ * BrokeredPreparedStatement. We use reflection because we don't know
which
+ * we have.
+ *
+ * @return EmbedParameterSetMetaData for the prepared statement.
+ * Note: there is no separate BrokeredParameterSetMetaData.
+ */
+ protected EmbedParameterSetMetaData getParameterMetaData() throws
SQLException
+ {
+ if (stmtPmeta != null)
+ return stmtPmeta;
+
+ EmbedParameterSetMetaData pmeta = null;
+ Class[] getParameterMetaDataParam = {};
+ try {
+ Method sh =
+
getPreparedStatement().getClass().getMethod("getParameterMetaData",
getParameterMetaDataParam);
+ pmeta = (EmbedParameterSetMetaData)
+ sh.invoke(getPreparedStatement(),null);
+ stmtPmeta = pmeta;
+ }
+ catch (Exception e) {
+ handleReflectionException(e);
+ }
+ return stmtPmeta;
+ }
+
+ /**
+ * get more results using reflection.
+ * @param current - flag to pass to Statement.getMoreResults(current)
+ * @return true if there are more results.
+ * @throws SQLException
+ * @see java.sql.Statemen#getMoreResults
+ *
+ */
+ protected boolean getMoreResults(int current) throws SQLException
+ {
+ boolean retVal = false;
+ Class[] intPARAM = {Integer.TYPE};
+ Object[] args = {new Integer(current)};
+ try {
+ Method sh =
getPreparedStatement().getClass().getMethod("getMoreResults",intPARAM);
+ Boolean retObj = (Boolean)
sh.invoke(getPreparedStatement(),args);
+ retVal = retObj.booleanValue();
+ }
+ catch (Exception e)
+ {
+ handleReflectionException(e);
+ }
+ return retVal;
+ }
+
+ /**
+ * Use reflection to retrieve SQL Text for EmbedPreparedStatement
+ * or BrokeredPreparedStatement.
+ * @return SQL text
+ */
+ private String getSQLText()
+ {
+ String retVal = null;
+ Class[] emptyPARAM = {};
+ Object[] args = null;
+ try {
+ Method sh =
getPreparedStatement().getClass().getMethod("getSQLText",emptyPARAM);
+ retVal = (String)
sh.invoke(getPreparedStatement(),args);
+ }
+ catch (Exception e)
+ {
+ // do nothing we will just return a null string
+ }
+ return retVal;
+
+ }
+
+ /** helper method to handle exceptions generated by methods invoked
+ * through reflection.
+ * @param e - exception thrown
+ * @throws SQLException - actual exception that occurred
+ */
+ private void handleReflectionException(Exception e) throws SQLException
+ {
+ if (e instanceof InvocationTargetException)
+ {
+ Throwable t = ((InvocationTargetException)
e).getTargetException();
+
+ if (t instanceof SQLException)
+ {
+ throw (SQLException) t;
+ }
+ else
+ throw Util.javaException(t);
+ }
+ else
+ // invoke can throw IllegalAccessException or
+ // IllegalArgumentException, but these should not
+ // occur from this code. Just in case we will throw it
+ throw Util.javaException(e);
+
+ }
}
Index: java/drda/org/apache/derby/impl/drda/Database.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/Database.java (revision 106968)
+++ java/drda/org/apache/derby/impl/drda/Database.java (working copy)
@@ -21,14 +21,16 @@
package org.apache.derby.impl.drda;
import java.sql.Connection;
+import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Enumeration;
+import java.util.Properties;
+import org.apache.derby.iapi.reference.Attribute;
import org.apache.derby.iapi.tools.i18n.LocalizedResource;
-
import org.apache.derby.impl.jdbc.EmbedConnection;
import org.apache.derby.iapi.services.sanity.SanityManager;
/**
@@ -39,6 +41,8 @@
{
protected String dbName; // database name
+ protected String shortDbName; // database name without attributes
+ String attrString=""; // attribute string
protected int securityMechanism; // Security mechanism
protected String userId; // User Id
protected String password; // password
@@ -64,11 +68,12 @@
protected boolean sendTRGDFTRT = false; // Send package target default
value
private Connection conn; // Connection to the
database
- private DRDAStatement defaultStatement; // default statement used
+ DRDAStatement defaultStatement; // default statement used
// for execute imm
private DRDAStatement currentStatement; // current statement we are
working on
- private Hashtable stmtTable; // Hash table for storing
statements
+ Hashtable stmtTable; // Hash table for storing statements
+ boolean forXA = false;
// constructor
/**
@@ -78,10 +83,29 @@
*/
protected Database (String dbName)
{
+ if (dbName != null)
+ {
+ int attrOffset = dbName.indexOf(';');
+ if (attrOffset != -1)
+ {
+ this.attrString =
dbName.substring(attrOffset,dbName.length());
+ this.shortDbName =
dbName.substring(0,attrOffset);
+ }
+ else
+ this.shortDbName = dbName;
+ }
+
this.dbName = dbName;
this.stmtTable = new Hashtable();
+ initializeDefaultStatement();
+ }
+
+
+ private void initializeDefaultStatement()
+ {
this.defaultStatement = new DRDAStatement(this);
}
+
/**
* Set connection and create the SQL statement for the default statement
*
@@ -209,6 +233,39 @@
}
/**
+ * Make a new connection using the database name and set
+ * the connection in the database
+ * @param p Properties for connection attributes to pass to connect
+ * @return new local connection
+ */
+ protected Connection makeConnection(Properties p) throws SQLException
+ {
+ p.put(Attribute.USERNAME_ATTR, userId);
+ p.put(Attribute.PASSWORD_ATTR, password);
+ Connection conn =
DB2jServerImpl.getDriver().connect(Attribute.PROTOCOL
+ + dbName + attrString,
p);
+ conn.setAutoCommit(false);
+ setConnection(conn);
+ return conn;
+ }
+
+ // Create string to pass to DataSource.setConnectionAttributes
+ String appendAttrString(Properties p)
+ {
+ if (p == null)
+ return null;
+
+ Enumeration pKeys = p.propertyNames();
+ while (pKeys.hasMoreElements())
+ {
+ String key = (String) pKeys.nextElement();
+ attrString +=";" + key +"=" + p.getProperty(key);
+ }
+
+ return attrString;
+ }
+
+ /**
* Get result set
*
* @param pkgnamcsn - key to access prepared statement
@@ -287,8 +344,11 @@
defaultStatement.close();
if ((conn != null) && !conn.isClosed())
{
- conn.rollback();
- conn.close();
+ if (! forXA)
+ {
+ conn.rollback();
+ }
+ conn.close();
}
}
finally {
@@ -299,6 +359,12 @@
}
}
+ protected void setDrdaID(String drdaID)
+ {
+ if (conn != null)
+ ((EmbedConnection)conn).setDrdaID(drdaID);
+ }
+
/**
* Set the internal isolation level to use for preparing statements.
* Subsequent prepares will use this isoalation level
Index: java/drda/org/apache/derby/impl/drda/build.xml
===================================================================
--- java/drda/org/apache/derby/impl/drda/build.xml (revision 106968)
+++ java/drda/org/apache/derby/impl/drda/build.xml (working copy)
@@ -20,6 +20,24 @@
<target name="drda" depends="compile"/>
<target name="compile">
+ <javac
+ bootclasspath="${empty}"
+ nowarn="on"
+ debug="${debug}"
+ depend="${depend}"
+ deprecation="${deprecation}"
+ optimize="${optimize}"
+ proceed="${proceed}"
+ verbose="${verbose}"
+ srcdir="${derby.drda.src.dir}"
+ destdir="${out.dir}">
+ <classpath>
+ <pathelement path="${java14compile.classpath}"/>
+ </classpath>
+ <include name="${derby.dir}/impl/drda/DRDAXAProtocol.java"/>
+ <include name="${derby.dir}/impl/drda/DRDAXid.java"/>
+ <include name="${derby.dir}/impl/drda/XADatabase.java"/>
+ </javac>
<javac
bootclasspath="${empty}"
nowarn="on"
@@ -36,6 +54,9 @@
<pathelement path="${java13compile.classpath}"/>
</classpath>
<include name="${derby.dir}/impl/drda/*.java"/>
+ <exclude name="${derby.dir}/impl/drda/DRDAXAProtocol.java"/>
+ <exclude name="${derby.dir}/impl/drda/DRDAXid.java"/>
+ <exclude name="${derby.dir}/impl/drda/XADatabase.java"/>
</javac>
</target>
Index: java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (revision
106968)
+++ java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (working copy)
@@ -1,5 +1,5 @@
/*
- Derby - Class org.apache.derby.impl.drda.DRDAConnThread
+ Derby - Class org.apache.derby.impl.drda.DRDAConnThread
Copyright 2001, 2004 The Apache Software Foundation or its licensors, as
applicable.
@@ -15,8 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
- */
-
+*/
/**
* This class translates DRDA protocol from an application requester to JDBC
* for Cloudscape and then translates the results from Cloudscape to DRDA
@@ -56,7 +55,6 @@
import org.apache.derby.iapi.tools.i18n.LocalizedResource;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.reference.Attribute;
-import org.apache.derby.iapi.reference.DB2Limit;
import org.apache.derby.iapi.error.ExceptionSeverity;
import org.apache.derby.impl.jdbc.Util;
import org.apache.derby.impl.jdbc.EmbedSQLException;
@@ -64,10 +62,8 @@
import org.apache.derby.impl.jdbc.EmbedStatement;
import org.apache.derby.impl.jdbc.EmbedPreparedStatement;
import org.apache.derby.impl.jdbc.EmbedParameterSetMetaData;
-import org.apache.derby.impl.jdbc.EmbedConnection;
import org.apache.derby.iapi.reference.JDBC30Translation;
-
import org.apache.derby.iapi.services.info.JVMInfo;
import org.apache.derby.iapi.services.sanity.SanityManager;
@@ -108,11 +104,14 @@
private OutputStream sockos;
private DDMReader reader;
private DDMWriter writer;
+ private DRDAXAProtocol xaProto;
+
private static int [] ACCRDB_REQUIRED = {CodePoint.RDBACCCL,
CodePoint.CRRTKN,
CodePoint.PRDID,
CodePoint.TYPDEFNAM,
CodePoint.TYPDEFOVR};
+
private static int MAX_REQUIRED_LEN = 5;
private int currentRequiredLength = 0;
@@ -273,6 +272,24 @@
}
/**
+ * get DDMReader
+ * @return DDMReader for this thread
+ */
+ protected DDMReader getReader()
+ {
+ return reader;
+ }
+
+ /**
+ * get DDMWriter
+ * @return DDMWriter for this thread
+ */
+ protected DDMWriter getWriter()
+ {
+ return writer;
+ }
+
+ /**
* Get correlation id
*
* @return correlation id
@@ -784,8 +801,7 @@
}
break;
case CodePoint.EXCSAT:
- parseEXCSAT2();
- writeEXCSATRD();
+ parseDRDAConnection();
break;
/* since we don't support sqlj, we won't get
bind commands from jcc, we
* might get it from ccc; just skip them.
@@ -854,6 +870,11 @@
errorInChain(e);
}
break;
+ case CodePoint.SYNCCTL:
+ if (xaProto == null)
+ xaProto = new
DRDAXAProtocol(this);
+ xaProto.parseSYNCCTL();
+ break;
default:
codePointNotSupported(codePoint);
}
@@ -902,7 +923,6 @@
throws DRDAProtocolException, SQLException
{
int codePoint;
- boolean sessionOK = true;
correlationID = reader.readDssHeader();
if (SanityManager.DEBUG) {
if (correlationID == 0)
@@ -926,6 +946,16 @@
// set up a new Application Requester to store information
about the
// application requester for this session
+
+ return parseDRDAConnection();
+ }
+
+
+ private boolean parseDRDAConnection() throws DRDAProtocolException
+ {
+ int codePoint;
+ boolean sessionOK = true;
+
appRequester = new AppRequester();
parseEXCSAT();
writeEXCSATRD();
@@ -1041,6 +1071,7 @@
session.appRequester = server.getAppRequester(appRequester);
return sessionOK;
}
+
/**
* Write RDB Failure
*
@@ -1105,7 +1136,6 @@
if (endOfName != -1)
realName = realName.substring(0, endOfName);
retSecChkCode = getConnFromDatabaseName();
-
return retSecChkCode;
}
@@ -1122,17 +1152,12 @@
{
Properties p = new Properties();
databaseAccessException = null;
- p.put(Attribute.USERNAME_ATTR, database.userId);
- p.put(Attribute.PASSWORD_ATTR, database.password);
//if we haven't got the correlation token yet, use session
number for drdaID
if (session.drdaID == null)
session.drdaID = leftBrace + session.connNum +
rightBrace;
p.put(Attribute.DRDAID_ATTR, session.drdaID);
try {
- Connection conn =
-
server.cloudscapeDriver.connect(Attribute.PROTOCOL + database.dbName, p);
- conn.setAutoCommit(false);
- database.setConnection(conn);
+ database.makeConnection(p);
} catch (SQLException se) {
String sqlState = se.getSQLState();
// need to set the security check code based on the
reason the connection
@@ -1264,6 +1289,7 @@
codePoint = reader.getCodePoint();
}
}
+
/**
* Parses EXCSAT2 (Exchange Server Attributes)
* Instance variables
@@ -1372,7 +1398,7 @@
else
unknownManagers.addElement(new
Integer(manager));
if (SanityManager.DEBUG)
- trace("Manager = " +
java.lang.Integer.toHexString(manager) +
+ trace("Manager = " +
java.lang.Integer.toHexString(manager) +
" ManagerLevel " + managerLevel);
}
sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM);
@@ -2124,7 +2150,7 @@
// check for required variables
if (pkgnamcsn == null)
missingCodePoint(CodePoint.PKGNAMCSN);
- if (!gotQryblksz)
+ if (!gotQryblksz)
missingCodePoint(CodePoint.QRYBLKSZ);
if (sqlamLevel >= MGRLVL_7 && !gotQryinsid)
missingCodePoint(CodePoint.QRYINSID);
@@ -2315,7 +2341,7 @@
//This is a unique sequence number per session
writer.writeInt(session.qryinsid++);
//Write the scroll attributes if they are set
- if (stmt.getScrollType() != 0)
+ if (stmt.isScrollable())
{
writer.writeScalar1Byte(CodePoint.QRYATTSCR,
CodePoint.TRUE);
//Cloudscape only supports insensitive scroll
cursors
@@ -2698,9 +2724,8 @@
time +
leftBrace + session.connNum + rightBrace;
if (SanityManager.DEBUG)
trace("******************************************drdaID is: " + session.drdaID);
- EmbedConnection conn =
(EmbedConnection)(database.getConnection());
- if (conn != null)
- conn.setDrdaID(session.drdaID);
+ database.setDrdaID(session.drdaID);
+
break;
//required
case CodePoint.RDBNAM:
@@ -3830,9 +3855,10 @@
rtnParam = true;
}
ps = cs;
+ stmt.ps = ps;
}
- pmeta = ((EmbedPreparedStatement)
ps).getEmbedParameterSetMetaData();
+ pmeta = stmt.getParameterMetaData();
reader.readBytes(6); // descriptor
footer
break;
@@ -4822,8 +4848,17 @@
// If it is a real SQL Error write a SQLERRRM first
severity = getExceptionSeverity(e);
- if (sendSQLERRRM || (severity > CodePoint.SVRCOD_ERROR))
+ if (severity > CodePoint.SVRCOD_ERROR)
{
+ // For a session ending error > CodePoint.SRVCOD_ERROR
you cannot
+ // send a SQLERRRM. A CMDCHKRM is required. In XA if
there is a
+ // lock timeout it ends the whole session. I am not
sure this
+ // is the correct behaviour but if it occurs we have to
send
+ // a CMDCHKRM instead of SQLERRM
+ writeCMDCHKRM(severity);
+ }
+ else if (sendSQLERRRM)
+ {
writeSQLERRRM(severity);
}
writeSQLCARD(e,severity, updateCount, 0);
@@ -4896,7 +4931,27 @@
writer.endDdmAndDss ();
}
+
/**
+ * Write CMDCHKRM
+ *
+ * Instance Variables
+ * SVRCOD - Severity Code - required
+ *
+ * @param severity severity of error
+ *
+ * @exception DRDAProtocolException
+ */
+ private void writeCMDCHKRM(int severity) throws DRDAProtocolException
+ {
+ writer.createDssReply();
+ writer.startDdm(CodePoint.CMDCHKRM);
+ writer.writeScalar2Bytes(CodePoint.SVRCOD, severity);
+ writer.endDdmAndDss ();
+
+ }
+
+ /**
* Translate from Cloudscape exception severity to SVRCOD
*
* @param e SQLException
@@ -5385,7 +5440,7 @@
{
PreparedStatement ps = stmt.getPreparedStatement();
ResultSetMetaData rsmeta = ps.getMetaData();
- EmbedParameterSetMetaData pmeta = ((EmbedPreparedStatement)
ps).getEmbedParameterSetMetaData();
+ EmbedParameterSetMetaData pmeta = stmt.getParameterMetaData();
int numElems = 0;
if (e == null || e instanceof SQLWarning)
{
@@ -5440,7 +5495,7 @@
if (!stmt.needsToSendParamData)
rs = stmt.getResultSet();
if (rs == null) // this is a CallableStatement, use
parameter meta data
- pmeta = ((EmbedPreparedStatement)
stmt.ps).getEmbedParameterSetMetaData();
+ pmeta = stmt.getParameterMetaData();
else
rsmeta = rs.getMetaData();
@@ -5616,10 +5671,6 @@
if (!stmt.needsToSendParamData)
rs = stmt.getResultSet();
- if (rs != null)
- rsstmt = (EmbedStatement) rs.getStatement();
- else
- rsstmt = (EmbedStatement) stmt.getPreparedStatement();
if (JVMInfo.JDK_ID < 2) //write null indicator for SQLDHROW
because there is no holdability support prior to jdk1.3
{
@@ -5630,7 +5681,7 @@
writer.writeByte(0); // SQLDHROW INDICATOR
//SQLDHOLD
- writer.writeShort(rsstmt.getResultSetHoldability());
+ writer.writeShort(stmt.getResultSetHoldability());
//SQLDRETURN
writer.writeShort(0);
@@ -5694,6 +5745,7 @@
if ((stmt.getBlksize() - endOffset ) < rowsize)
getMoreData = false;
+ startOffset = endOffset;
}
}
@@ -5729,7 +5781,7 @@
if (rs != null)
{
numCols = stmt.getNumRsCols();
- if (stmt.getScrollType() != 0)
+ if (stmt.isScrollable())
hasdata = positionCursor(stmt, rs);
else
hasdata = rs.next();
@@ -5895,14 +5947,14 @@
}
/*(1) scrollable we return at most a row set; OR (2) no
retrieve data
*/
- else if (stmt.getScrollType() != 0 || noRetrieveRS)
+ else if (stmt.isScrollable() || noRetrieveRS)
moreData=false;
} while (hasdata && rowCount < stmt.getQryrowset());
// add rowCount to statement row count
// for non scrollable cursors
- if (stmt.getScrollType() == 0)
+ if (!stmt.isScrollable())
stmt.rowCount += rowCount;
if (!hasdata)
@@ -5911,7 +5963,7 @@
moreData=false;
}
- if (stmt.getScrollType() == 0)
+ if (!stmt.isScrollable())
stmt.setHasdata(hasdata);
return moreData;
}
@@ -5977,7 +6029,7 @@
int blksize = stmt.getBlksize() > 0 ? stmt.getBlksize() :
CodePoint.QRYBLKSZ_MAX;
if (rs != null)
{
- if (stmt.getScrollType() != 0)
+ if (stmt.isScrollable())
{
// for scrollable cursors - calculate the row
count
// since we may not have gone through each row
@@ -6591,7 +6643,7 @@
*
* @exception DRDAProtocolException
*/
- private void invalidCodePoint(int codePoint) throws
DRDAProtocolException
+ protected void invalidCodePoint(int codePoint) throws
DRDAProtocolException
{
throwSyntaxrm(CodePoint.SYNERRCD_INVALID_CP_FOR_CMD, codePoint);
}
@@ -6601,7 +6653,7 @@
* @param codePoint code point value
* @exception DRDAProtocolException
*/
- private void codePointNotSupported(int codePoint) throws
DRDAProtocolException
+ protected void codePointNotSupported(int codePoint) throws
DRDAProtocolException
{
throw new
DRDAProtocolException(DRDAProtocolException.DRDA_Proto_CMDNSPRM,
@@ -6928,7 +6980,13 @@
*/
private void addDatabase(String dbname)
{
- Database db = new Database(dbname);
+ Database db;
+ if (appRequester.isXARequester())
+ {
+ db = new XADatabase(dbname);
+ }
+ else
+ db = new Database(dbname);
session.addDatabase(db);
session.database = db;
database = db;
@@ -7151,6 +7209,7 @@
return s;
}
+
/**
* Finalize the current DSS chain and send it if
* needed.
@@ -7163,5 +7222,3 @@
}
}
-
-
Index: java/drda/org/apache/derby/impl/drda/AppRequester.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/AppRequester.java (revision
106968)
+++ java/drda/org/apache/derby/impl/drda/AppRequester.java (working copy)
@@ -49,7 +49,7 @@
6, // SQLAM
1, // SUPERVISOR
5, // SYNCPTMGR
-
7 // XAMGR
+
0 // XAMGR
};
// Application requester information
protected String extnam; // External Name -
EXCSAT
@@ -249,4 +249,16 @@
}
+ /**
+ * Is this an AppRequester that supports XA
+ *
+ * return true if XAMGR >= 7, false otherwise
+ **/
+
+ protected boolean isXARequester()
+ {
+ return (getManagerLevel(CodePoint.XAMGR) >= 7);
+
+ }
+
}
Index: java/drda/org/apache/derby/impl/drda/CodePoint.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/CodePoint.java (revision 106968)
+++ java/drda/org/apache/derby/impl/drda/CodePoint.java (working copy)
@@ -754,6 +754,86 @@
static final int OUTOVRFRS = 1; // Output Override allowed on
first CNTQRY
static final int OUTOVRANY = 2; // Output Override allowed on
any CNTQRY
+
+
+ //--------------------------XA code points---------------------------
+
+
+ // Release conversation
+ public static final int RLSCONV = 0x119F;
+
+ // SYNC Point Control Reply
+ public static final int SYNCCRD = 0x1248;
+
+ // XA Return Value
+ public static final int XARETVAL = 0x1904;
+
+ // XA Timeout Value;
+ public static final int TIMEOUT = 0x1907;
+
+ // new unit of work for XA
+ public static final int SYNCTYPE_NEW_UOW = 0x09;
+
+ // End unit of work (Sync type).
+ public static final int SYNCTYPE_END_UOW = 0x0B;
+
+ // Prepare to commit (Sync type).
+ public static final int SYNCTYPE_PREPARE = 0x01;
+
+ // migrate to resync server sync type
+ public static final int SYNCTYPE_MIGRATE = 0x02;
+
+ // commit sync type
+ public static final int SYNCTYPE_COMMITTED = 0x03;
+
+ // request to commit sync type
+ public static final int SYNCTYPE_REQ_COMMIT = 0x05;
+
+ // request to forget sync type
+ public static final int SYNCTYPE_REQ_FORGET = 0x06;
+
+ //rollback sync type
+ public static final int SYNCTYPE_ROLLBACK = 0x04;
+
+ // Request Sync log information (Sync type).
+ static final int SYNCTYPE_REQ_LOG = 0x08;
+
+ // migrated unit of work sync type
+ public static final int SYNCTYPE_MIGRATED = 0x0A;
+
+ //recover sync type
+ public static final int SYNCTYPE_INDOUBT = 0x0C;
+
+
+ // Forget unit of work.
+ public static final int FORGET = 0x1186;
+
+ // SYNC Type Codepoint
+ public static final int SYNCTYPE = 0x1187;
+
+ // XId Codepoint
+ public static final int XID = 0x1801;
+
+ // XA Flag Codepoint
+ public static final int XAFLAGS = 0x1903;
+
+ // Resync Type
+ public static final int RSYNCTYP = 0x11EA;
+
+ // Sync Resync Reply
+ public static final int SYNCRRD = 0x126D;
+
+ // XA Flags
+ public static final int TMNOFLAGS = 0x00000000;
+
+
+ // Prepared and hueristic complete list
+ static final int PRPHRCLST = 0x1905;
+
+ // XID count
+ static final int XIDCNT = 0x1906;
+
+
//-----------------------Manager code points --------------------------
protected static int [] MGR_CODEPOINTS = {
Index: java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (revision
106968)
+++ java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (working copy)
@@ -64,7 +64,7 @@
protected int [] outovr_drdaType; // Output override DRDA type
and length
protected int withHoldCursor; // hold cursor after
commit attribute
- protected int scrollType; // Sensitive or
Insensitive scroll attribute
+ protected int scrollType = ResultSet.TYPE_FORWARD_ONLY;
// Sensitive or Insensitive scroll attribute
protected int concurType; // Concurency type
protected long rowCount; // Number of rows we
have processed
private ResultSet rs; // Current ResultSet
@@ -354,7 +354,7 @@
rs = null;
gotPrctyp = false;
outovr_drdaType = null;
- scrollType = 0;
+ scrollType = ResultSet.TYPE_FORWARD_ONLY;
concurType = 0;
rowCount = 0;
rsLens = null;
Index: java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java (revision 0)
+++ java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java (revision 0)
@@ -0,0 +1,661 @@
+/*
+
+ Derby - Class org.apache.derby.impl.drda.DRDAXAProtocol.java
+
+ Copyright 2004 The Apache Software Foundation or its licensors, as
applicable.
+
+ 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.
+
+ */
+
+/**
+ * This class translates DRDA XA protocol from an application requester to XA
+ * calls for Derby and then translates the results from Derby to DRDA
+ * for return to the application requester.
+ * This class requires the use of javax.transaction.xa classes from j2ee,
+ * so is separated from DRDAConnThread, because of the additional
+ * library requirements
+ * @author [EMAIL PROTECTED]
+ */
+
+
+package org.apache.derby.impl.drda;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import javax.transaction.xa.*;
+
+
+public class DRDAXAProtocol {
+
+ private DRDAConnThread connThread;
+ private DDMReader reader;
+ private DDMWriter writer;
+
+
+ public DRDAXAProtocol(DRDAConnThread connThread)
+ {
+ this.connThread = connThread;
+ reader = connThread.getReader();
+ writer = connThread.getWriter();
+
+ }
+
+
+
+ /**
+ * Parse SYNCCTL - Parse SYNCCTL command for XAMGR lvl 7
+ *
+ */
+ protected void parseSYNCCTL() throws DRDAProtocolException
+ {
+
+ reader.markCollection();
+
+ int codePoint = reader.getCodePoint(CodePoint.SYNCTYPE);
+ int syncType = parseSYNCTYPE();
+
+ int xaflags = 0;
+ boolean readXAFlags = false;
+ Xid xid = null;
+
+ codePoint = reader.getCodePoint();
+ while (codePoint != -1)
+ {
+ switch(codePoint)
+ {
+ case CodePoint.XID:
+ xid = parseXID();
+ break;
+ case CodePoint.XAFLAGS:
+ xaflags = parseXAFlags();
+ readXAFlags =true;
+ break;
+ case CodePoint.TIMEOUT:
+ // optional/ignorable.
+ reader.skipBytes();
+ break;
+ case CodePoint.RLSCONV:
+
connThread.codePointNotSupported(codePoint);
+ default:
+ connThread.invalidCodePoint(codePoint);
+ }
+
+ codePoint = reader.getCodePoint();
+ }
+
+
+ {
+ connThread.trace("syncType = " +
syncTypeToString(syncType));
+ connThread.trace("xid = " + xid);
+ connThread.trace("xaflags =" +
xaflagsToString(xaflags));
+ }
+
+ switch (syncType)
+ {
+ case CodePoint.SYNCTYPE_NEW_UOW:
+ // new unit of work for XA
+ // formatId -1 is just a local connection
+ startXATransaction(xid,xaflags);
+ break;
+ case CodePoint.SYNCTYPE_END_UOW:
+ // End unit of work
+ endXA(xid,xaflags);
+ break;
+ case CodePoint.SYNCTYPE_PREPARE:
+ prepareXATransaction(xid);
+ // Prepare to commit
+ break;
+ case CodePoint.SYNCTYPE_MIGRATE:
+ // migrate to resync server sync type
+ connThread.codePointNotSupported(codePoint);
+ break;
+ case CodePoint.SYNCTYPE_REQ_COMMIT:
+ // request to commit sync type
+ commitTransaction(xid,xaflags);
+ break;
+ case CodePoint.SYNCTYPE_COMMITTED:
+ // commit sync type
+ commitTransaction(xid, xaflags);
+ break;
+ case CodePoint.SYNCTYPE_REQ_FORGET:
+ // request to forget sync type
+ forgetXATransaction(xid);
+ break;
+ case CodePoint.SYNCTYPE_ROLLBACK:
+ //rollback sync type
+ rollbackTransaction(xid);
+ break;
+ case CodePoint.SYNCTYPE_INDOUBT:
+ //recover sync type
+ recoverXA();
+ break;
+ default:
+ connThread.invalidCodePoint(codePoint);
+ }
+ if (syncType != CodePoint.SYNCTYPE_INDOUBT)
+ {
+ if (xid == null)
+ connThread.missingCodePoint(CodePoint.XID);
+
+ if (! readXAFlags)
+ if (SanityManager.DEBUG)
+
connThread.missingCodePoint(CodePoint.XAFLAGS);
+ }
+ }
+
+ /**
+ * parse SYNCTYPE for XAMGR lvl 7
+ * return synctype value
+ * CodePoint.SYNCTYPE_NEW_UOW -> XAResource.start()
+ * CodePoint.SYNCTYPE_END_UOW -> XAResource.end()
+ * CodePoint.SYNCTYPE_PREPARE -> XAResource.prepare()
+ * CodePoint.SYNCTYPE_MIGRATE -> not supported //SYNCPT MGR LEVEL 5
+ * CodePoint.SYNCTYPE_REQ_COMMIT -> not supported //SYNCPT MGR LEVEL 5
+ * CodePoint.SYNCTYPE_COMMITTED -> XAResource.commit()
+ * or local commit for null XID
+ * CodePoint.SYNCTYPE_REQ_LOG -> not supported
+ * CodePoint.SYNCTYPE_REQ_FORGET -> XAResource.forget()
+ * CodePoint.SYNCTYPE_ROLLBACK -> XAResource.rollback()
+ * CodePoint.SYNCTYPE_MIGRATED -> not supported
+ * CodePoint.SYNCTYPE_INDOUBT -> XAResource.recover();
+ *
+ */
+ protected int parseSYNCTYPE() throws DRDAProtocolException
+ {
+ return reader.readUnsignedByte();
+
+ }
+
+
+ /** Parse XID
+ * formatId -1 translates into a null XID and a local transaction
+ */
+ private Xid parseXID () throws DRDAProtocolException
+ {
+ int formatId = reader.readNetworkInt();
+ byte[] gtrid = null;
+ byte[] bqual = null;
+ if (formatId != -1)
+ {
+ int gtridLen = reader.readNetworkInt();
+ int bqualLen = reader.readNetworkInt();
+
+ gtrid = reader.readBytes(gtridLen);
+ bqual = reader.readBytes(bqualLen);
+ }
+ return new DRDAXid(formatId, gtrid, bqual);
+ }
+
+
+ /**
+ * parse XIDSHR
+ *
+ * @return XIDSHR value
+ * @throws DRDAProtocolException
+ */
+ private int parseXIDSHR() throws DRDAProtocolException
+ {
+ return reader.readUnsignedByte();
+ }
+
+ /**
+ * parse XAFlags
+ *
+ * @return XAFlags value
+ * @throws DRDAProtocolException
+ */
+ private int parseXAFlags() throws DRDAProtocolException
+ {
+ return reader.readNetworkInt();
+ }
+
+
+ /**
+ * Start the xa transaction. Send SYNCRRD response
+ *
+ * @param xid - XID (formatId = -1 for local transaction)
+ * @param xaflags - xaflags
+ * @throws DRDAProtocolException
+ */
+ private void startXATransaction(Xid xid, int xaflags) throws
DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+
+ try {
+ if (xid.getFormatId() != -1)
+ xaResource.start(xid,xaflags);
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_NEW_UOW,
+ xaRetVal, null);
+
+ }
+
+
+ /**
+ * Commit the xa transaction. Send SYNCCRD response
+ *
+ * @param xid - XID (formatId = -1 for local transaction)
+ * @param xaflags - xaflags
+ * @throws DRDAProtocolException
+ */
+ private void commitTransaction(Xid xid, int xaflags) throws
DRDAProtocolException
+ {
+ boolean local = ( xid.getFormatId() == -1);
+ if (local)
+ commitLocalTransaction();
+ else
+ commitXATransaction(xid, xaflags);
+ }
+
+ /**
+ * Commit local transaction. Send SYNCCRD response.
+ *
+ * @throws DRDAProtocolException
+ */
+ private void commitLocalTransaction() throws DRDAProtocolException
+ {
+ int xaRetVal = XAResource.XA_OK;
+ try {
+ connThread.getDatabase().commit();
+ }
+ catch (Exception e)
+ {
+ xaRetVal = XAException.XAER_RMFAIL;
+ if (SanityManager.DEBUG)
+ {
+ connThread.getServer().consoleExceptionPrint(e);
+ }
+
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
+ xaRetVal, null);
+
+ }
+
+
+ /**
+ * Commit the xa transaction. Send SYNCCRD response.
+ *
+ * @param xid - XID
+ * @param xaflags - xaflags
+ * @throws DRDAProtocolException
+ */
+ private void commitXATransaction(Xid xid, int xaflags) throws
DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+ // check this
+ boolean isOnePhase = (xaflags & XAResource.TMONEPHASE) != 0;
+ try {
+ xaResource.commit(xid, isOnePhase);
+ if (SanityManager.DEBUG)
+ connThread.trace("committed XA transaction:
xaRetVal=" + xaRetVal);
+
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
+ xaRetVal, null);
+
+ }
+
+ /**
+ * Rollback transaction
+ * @param xid Xid for rollback for global transaction.
+ * If xid formatid is -1 it represents a local transaction
+ */
+ private void rollbackTransaction(Xid xid) throws DRDAProtocolException
+ {
+ boolean local = ( xid.getFormatId() == -1);
+ if (local)
+ rollbackLocalTransaction();
+ else
+ rollbackXATransaction(xid);
+ }
+
+ /**
+ * Rollback a local transaction
+ *
+ */
+ private void rollbackLocalTransaction() throws DRDAProtocolException
+ {
+ int xaRetVal = XAResource.XA_OK;
+ try {
+ connThread.getDatabase().rollback();
+ }
+ catch (Exception e)
+ {
+ xaRetVal = XAException.XAER_RMFAIL;
+ if (SanityManager.DEBUG)
+ {
+ connThread.getServer().consoleExceptionPrint(e);
+ }
+
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_COMMITTED,
+ xaRetVal, null);
+
+ }
+
+ /**
+ * Rollback the xa transaction. Send SYNCCRD response.
+ *
+ * @param xid - XID
+ * @throws DRDAProtocolException
+ */
+ private void rollbackXATransaction(Xid xid) throws DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+
+ try {
+ xaResource.rollback(xid);
+ if (SanityManager.DEBUG)
+ {
+ connThread.trace("rollback XA transaction:
xaRetVal=" + xaRetVal);
+ }
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_ROLLBACK,
+ xaRetVal, null);
+
+ }
+
+ /**
+ * End the xa transaction. Send SYNCRRD response
+ *
+ * @param xid - XID
+ * @param xaflags - xaflags
+ * @throws DRDAProtocolException
+ */
+ private void endXA(Xid xid, int xaflags) throws DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+
+ try {
+ xaResource.end(xid,xaflags);
+ if (SanityManager.DEBUG)
+ {
+ connThread.trace("ended XA transaction. xid =
" + xid +
+ " xaflags =" +
xaflags +
+ "xaRetVal=" +
xaRetVal);
+ }
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_END_UOW,
+ xaRetVal, null);
+ }
+
+
+ /**
+ * Prepare the xa transaction. Send SYNCCRD response.
+ *
+ * @param xid - XID
+ * @throws DRDAProtocolException
+ */
+ private void prepareXATransaction(Xid xid) throws DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+
+ try {
+ xaResource.prepare(xid);
+ if (SanityManager.DEBUG)
+ {
+ connThread.trace("prepared xa transaction:
xaRetVal=" +
+ xaRetVal);
+ }
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_PREPARE,
+ xaRetVal, null);
+ }
+
+ /**
+ * Forget the xa transaction. Send SYNCCRD response.
+ *
+ * @param xid - XID
+ * @throws DRDAProtocolException
+ */
+ private void forgetXATransaction(Xid xid) throws DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+
+ try {
+ xaResource.forget(xid);
+ if (SanityManager.DEBUG)
+ {
+ connThread.trace("forgot xa transaction:
xaRetVal=" + xaRetVal);
+ }
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_REQ_FORGET,
+ xaRetVal, null);
+ }
+
+
+ /**
+ * Call recover. Send SYNCCRD response with indoubt list
+ *
+ * @throws DRDAProtocolException
+ */
+ private void recoverXA() throws DRDAProtocolException
+ {
+ XAResource xaResource = getXAResource();
+ int xaRetVal = xaResource.XA_OK;
+ Xid[] indoubtXids = null;
+ try {
+ indoubtXids =
xaResource.recover(XAResource.TMSTARTRSCAN);
+ } catch (XAException xe)
+ {
+ xaRetVal = processXAException(xe);
+ }
+ writeSYNCCRD(CodePoint.SYNCTYPE_INDOUBT,
+ xaRetVal, indoubtXids);
+ }
+
+ /** Write SYNCCRD (SYNCCTL response)
+ * @param synctype - XA Command to send response for see parseSYNCTYPE
+ * @param xaRetVal - return value from XA command
+ * @param xids - list of xids to return for recover.
+ * null for other commands
+ * @throws DRDAProtocolException
+ */
+ private void writeSYNCCRD (int synctype, int xaRetVal, Xid[] xids)
throws DRDAProtocolException
+ {
+ writer.createDssReply();
+ writer.startDdm(CodePoint.SYNCCRD);
+ writer.startDdm(CodePoint.XARETVAL);
+ writer.writeInt(xaRetVal);
+ writer.endDdm();
+ if (xids != null)
+ writePRPHRCLST(xids);
+ writer.endDdmAndDss();
+ }
+
+ /** write PRPHRCLST (indoubt list)
+ *
+ * @param xids - list of indoubt xa transactions obtained from recover
+ * @throws DRDAProtocolException
+ */
+ private void writePRPHRCLST(Xid[] xids) throws DRDAProtocolException
+ {
+ int xidcnt = (xids == null ? 0 : xids.length);
+ writer.startDdm(CodePoint.PRPHRCLST);
+ writer.writeScalar2Bytes(CodePoint.XIDCNT, xidcnt);
+ for (int i = 0; i < xidcnt; i++)
+ writeXID(xids[i]);
+ writer.endDdm();
+ }
+
+ /** write XID
+ *
+ * @param xid - XID to write
+ * @throws DRDAProtocolException
+ */
+
+ private void writeXID(Xid xid) throws DRDAProtocolException
+ {
+ writer.startDdm(CodePoint.XID);
+ int formatId = xid.getFormatId();
+ byte[] gtrid = xid.getGlobalTransactionId();
+ byte[] bqual = xid.getBranchQualifier();
+
+ writer.writeInt(formatId);
+ writer.writeInt(gtrid.length);
+ writer.writeInt(bqual.length);
+ writer.writeBytes(gtrid);
+ writer.writeBytes(bqual);
+ writer.endDdm();
+ }
+
+
+ /** get XAResource for the connection
+ *
+ * @return XAResource
+ */
+ private XAResource getXAResource()
+ {
+ return ((XADatabase) connThread.getDatabase()).getXAResource();
+
+ }
+
+ /** printable syncType for debug output
+ * @param syncType
+ * @return - sync type meaning
+ */
+ private String syncTypeToString(int syncType)
+ {
+ switch (syncType)
+ {
+ case CodePoint.SYNCTYPE_NEW_UOW:
+ return "SYNCTYPE_NEW_UOW";
+
+ case CodePoint.SYNCTYPE_END_UOW:
+ return "SYNCTYPE_END_UOW";
+
+ case CodePoint.SYNCTYPE_PREPARE:
+ return "SYNCTYPE_PREPARE";
+
+ case CodePoint.SYNCTYPE_MIGRATE:
+ return "SYNCTYPE_MIGRATE";
+
+ case CodePoint.SYNCTYPE_REQ_COMMIT:
+ return "SYNCTYPE_REQ_COMMIT";
+
+ case CodePoint.SYNCTYPE_COMMITTED:
+ return "SYNCTYPE_COMMITTED";
+
+ case CodePoint.SYNCTYPE_REQ_FORGET:
+ return "SYNCTYPE_FORGET";
+
+ case CodePoint.SYNCTYPE_ROLLBACK:
+ return "SYNCTYPE_ROLLBACK";
+
+ case CodePoint.SYNCTYPE_REQ_LOG:
+ return "SYNCTYPE_REQ_LOG";
+
+ case CodePoint.SYNCTYPE_MIGRATED:
+ return "SYNCTYPE_MIGRATED";
+
+ case CodePoint.SYNCTYPE_INDOUBT:
+ return "SYNCTYPE_INDOUBT";
+
+ default:
+ return "UNKNOWN SYNCTYPE";
+ }
+ }
+
+ /**
+ * printable xaflags
+ * @param - xaflags
+ * @return - printable xaflags for debug output
+ */
+ private String xaflagsToString(int xaflags)
+ {
+ switch (xaflags)
+ {
+ case XAResource.TMENDRSCAN :
+ return "XAResource.TMENDRSCAN";
+
+ case XAResource.TMFAIL:
+ return "XAResource.TMFAIL";
+
+ case XAResource.TMNOFLAGS:
+ return "XAResource.TMNOFLAGS";
+
+ case XAResource.TMJOIN:
+ return "XAResource.TMJOIN";
+
+ case XAResource.TMONEPHASE:
+ return "XAResource.TMONEPHASE";
+
+ case XAResource.TMRESUME:
+ return "XAResource.TMRESUME";
+
+ case XAResource.TMSTARTRSCAN:
+ return "XAResource.TMSTARTRSCAN";
+
+ case XAResource.TMSUCCESS:
+ return "XAResource.TMSUCCESS";
+
+ case XAResource.TMSUSPEND:
+ return "XAResource.TMSUSPEND";
+
+ default:
+ return "UNRECOGNIZED flags:" + xaflags;
+
+ }
+ }
+
+ /**
+ * return xa exception errorCode.
+ * print to console for debug output.
+ * @param xe - XA Exception
+ */
+ private int processXAException(XAException xe)
+ {
+ int xaRetVal = xe.errorCode;
+ if (SanityManager.DEBUG)
+ {
+ connThread.getServer().consoleExceptionPrint(xe);
+ }
+ return xaRetVal;
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
Property changes on: java/drda/org/apache/derby/impl/drda/DRDAXAProtocol.java
___________________________________________________________________
Name: svn:eol
+ native
Index: java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java (revision
106968)
+++ java/drda/org/apache/derby/impl/drda/DB2jServerImpl.java (working copy)
@@ -187,13 +187,13 @@
7, // SQLAM
0, // SUPERVISOR
0, // SYNCPTMGR
-
0 // XAMGR
+
7 // XAMGR
};
protected PrintWriter logWriter; // console
protected PrintWriter cloudscapeLogWriter; // derby.log
- protected Driver cloudscapeDriver;
+ private static Driver cloudscapeDriver;
// error types
private final static int ERRTYPE_SEVERE = 1;
@@ -382,6 +382,13 @@
else
return null;
}
+
+ protected static Driver getDriver()
+ {
+ return cloudscapeDriver;
+ }
+
+
/********************************************************************************
* Implementation of NetworkServerControl API
* The server commands throw exceptions for errors, so that users can
handle
Index: java/drda/org/apache/derby/impl/drda/XADatabase.java
===================================================================
--- java/drda/org/apache/derby/impl/drda/XADatabase.java (revision 0)
+++ java/drda/org/apache/derby/impl/drda/XADatabase.java (revision 0)
@@ -0,0 +1,144 @@
+/*
+
+ Derby - Class org.apache.derby.impl.drda.XADatabase.java
+
+ Copyright 2004 The Apache Software Foundation or its licensors, as
applicable.
+
+ 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.
+
+ */
+
+/**
+ * This class contains database state specific to XA,
+ * specifically the XAResource that will be used for XA commands.
+ * @author [EMAIL PROTECTED]
+ */
+
+package org.apache.derby.impl.drda;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.transaction.xa.XAResource;
+import javax.sql.XADataSource;
+import javax.sql.XAConnection;
+
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Enumeration;
+
+
+import org.apache.derby.jdbc.EmbeddedXADataSource;
+import org.apache.derby.impl.drda.DRDAXid;
+import org.apache.derby.iapi.jdbc.BrokeredConnection;
+
+class XADatabase extends Database {
+
+
+ // XA Datasource used by all the XA connection requests
+ private EmbeddedXADataSource xaDataSource;
+
+ private XAResource xaResource;
+ private XAConnection xaConnection;
+
+
+ protected XADatabase (String dbName)
+ {
+ super(dbName);
+ forXA = true;
+ }
+
+ /**
+ * Make a new connection using the database name and set
+ * the connection in the database
+ **/
+ protected synchronized Connection makeConnection(Properties p) throws
+ SQLException
+ {
+ if (xaDataSource == null)
+ {
+ xaDataSource = new EmbeddedXADataSource();
+ }
+
+ xaDataSource.setDatabaseName(shortDbName);
+ appendAttrString(p);
+ if (attrString != null)
+ xaDataSource.setConnectionAttributes(attrString);
+ xaConnection = xaDataSource.getXAConnection(userId,password);
+ xaResource = xaConnection.getXAResource();
+
+ Connection conn = xaConnection.getConnection();
+ setConnection(conn);
+ return conn;
+
+ }
+
+ /** SetXAResource
+ * @param resource XAResource for this connection
+ */
+ protected void setXAResource (XAResource resource)
+ {
+ this.xaResource = resource;
+ }
+
+ /** Set DRDA id for this connection
+ * @param drdaId
+ */
+ protected void setDrdaID(String drdaID)
+ {
+ if (getConnection() != null)
+ ((BrokeredConnection)
getConnection()).setDrdaID(drdaID);
+ }
+
+
+ /**
+ * Set the internal isolation level to use for preparing statements.
+ * Subsequent prepares will use this isoalation level
+ * @param level internal isolation level
+ *
+ * @throws SQLException
+ * @see BrokeredConnection#setPrepareIsolation
+ *
+ */
+ protected void setPrepareIsolation(int level) throws SQLException
+ {
+ ((BrokeredConnection)
getConnection()).setPrepareIsolation(level);
+ }
+
+ /** get prepare isolation level for this connection.
+ *
+ */
+ protected int getPrepareIsolation() throws SQLException
+ {
+ return ((BrokeredConnection)
getConnection()).getPrepareIsolation();
+ }
+
+ /**
+ * get XA Resource for this connection
+ */
+ protected XAResource getXAResource ()
+ {
+ return this.xaResource;
+ }
+
+
+}
+
+
+
+
+
+
+
+
+
Property changes on: java/drda/org/apache/derby/impl/drda/XADatabase.java
___________________________________________________________________
Name: svn:eol
+ native