You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ba...@apache.org on 2005/04/28 21:05:45 UTC
svn commit: r165178 [18/26] - in /incubator/derby/code/trunk: ./
java/client/ java/client/org/ java/client/org/apache/
java/client/org/apache/derby/ java/client/org/apache/derby/client/
java/client/org/apache/derby/client/am/
java/client/org/apache/derby/client/net/
java/client/org/apache/derby/client/resources/
java/client/org/apache/derby/jdbc/ tools/ant/properties/
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,635 @@
+/*
+
+ Derby - Class org.apache.derby.client.net.NetConnectionRequest
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where 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.
+
+*/
+
+package org.apache.derby.client.net;
+
+
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.Utils;
+import javax.transaction.xa.Xid;
+
+public class NetConnectionRequest extends Request implements ConnectionRequestInterface
+{
+ NetConnectionRequest (NetAgent netAgent, CcsidManager ccsidManager, int bufferSize)
+ {
+ super (netAgent, ccsidManager, bufferSize);
+ }
+ //----------------------------- entry points ---------------------------------
+
+ void writeExchangeServerAttributes (String externalName,
+ int targetAgent,
+ int targetSqlam,
+ int targetRdb,
+ int targetSecmgr,
+ int targetCmntcpip,
+ int targetCmnappc,
+ int targetXamgr,
+ int targetSyncptmgr,
+ int targetRsyncmgr) throws SqlException
+ {
+ // send the exchange server attributes command to the server.
+ // no other commands will be chained to the excsat because
+ // the manager levels are needed before anything else is attempted.
+ buildEXCSAT (externalName,
+ targetAgent,
+ targetSqlam,
+ targetRdb,
+ targetSecmgr,
+ targetCmntcpip,
+ targetCmnappc,
+ targetXamgr,
+ targetSyncptmgr,
+ targetRsyncmgr);
+
+ }
+
+ void writeDummyExchangeServerAttributes () throws SqlException
+ {
+ // send the exchange server attributes command to the server,
+ // without any parameters
+ buildDummyEXCSAT ();
+ }
+
+ void writeAccessSecurity (int securityMechanism,
+ String databaseName,
+ byte[] publicKey) throws SqlException
+ {
+ buildACCSEC (securityMechanism, databaseName, publicKey);
+ }
+
+ void writeSecurityCheck (int securityMechanism,
+ String databaseName,
+ String userid,
+ String password,
+ byte[] encryptedUserid,
+ byte[] encryptedPassword) throws SqlException
+
+
+ {
+ buildSECCHK (securityMechanism,
+ databaseName,
+ userid,
+ password,
+ encryptedUserid,
+ encryptedPassword);
+ }
+
+ void writeAccessDatabase (String rdbnam,
+ boolean readOnly,
+ byte[] correlationToken,
+ byte[] productData,
+ Typdef typdef) throws SqlException
+ {
+ buildACCRDB (rdbnam,
+ readOnly,
+ correlationToken,
+ productData,
+ typdef);
+ }
+
+
+
+ public void writeCommitSubstitute (NetConnection connection) throws SqlException
+ {
+ buildDummyEXCSAT();
+ }
+
+ public void writeLocalCommit (NetConnection connection) throws SqlException
+ {
+ buildRDBCMM ();
+ }
+
+ public void writeLocalRollback (NetConnection connection) throws SqlException
+ {
+ buildRDBRLLBCK ();
+ }
+
+ public void writeLocalXAStart(NetConnection connection) throws SqlException
+ {
+ }
+
+
+ //Build the SYNNCTL commit command
+ public void writeLocalXACommit (NetConnection conn) throws SqlException
+ {
+ }
+
+ //Build the SYNNCTL rollback command
+ public void writeLocalXARollback (NetConnection conn) throws SqlException
+ {
+ }
+
+ public void writeXaStartUnitOfWork(NetConnection conn) throws SqlException
+ {
+ }
+
+ public void writeXaEndUnitOfWork(NetConnection conn) throws SqlException
+ {
+ }
+
+ protected void writeXaPrepare(NetConnection conn) throws SqlException
+ {
+ }
+
+ protected void writeXaCommit(NetConnection conn, Xid xid) throws SqlException
+ {
+ }
+
+ protected void writeXaRollback(NetConnection conn, Xid xid) throws SqlException
+ {
+ }
+
+ protected void writeXaRecover(NetConnection conn, int flag) throws SqlException
+ {
+ }
+
+ protected void writeXaForget(NetConnection conn, Xid xid) throws SqlException
+ {
+ }
+
+ public void writeSYNCType(int codepoint, int syncType)
+ {
+ writeScalar1Byte (codepoint, syncType);
+ }
+
+ public void writeForget(int codepoint, int value)
+ {
+ }
+
+ public void writeReleaseConversation(int codepoint, int value)
+ {
+ }
+
+ void writeNullXID(int codepoint)
+ {
+ }
+
+ void writeXID(int codepoint, Xid xid) throws SqlException
+ {
+ }
+
+
+ void writeXAFlags(int codepoint, int xaFlags)
+ {
+ }
+
+
+ //----------------------helper methods----------------------------------------
+ // These methods are "private protected", which is not a recognized java privilege,
+ // but means that these methods are private to this class and to subclasses,
+ // and should not be used as package-wide friendly methods.
+
+ // RDB Commit Unit of Work (RDBCMM) Command commits all work performed
+ // for the current unit of work.
+ //
+ // The Relational Database Name (RDBNAM) is an optional parameter
+ // which will not be sent by this command to reduce size, building,
+ // and parsing.
+ void buildRDBCMM () throws SqlException
+ {
+ createCommand ();
+ writeLengthCodePoint (0x04, CodePoint.RDBCMM);
+ }
+
+ // RDB Rollback Unit of Work(RDBRLLBCK) Command rolls back
+ // all work performed for the current unit of work.
+ //
+ // The Relational Database Name (RDBNAM) is an optional parameter
+ // which will not be sent by this command to reduce size, building,
+ // and parsing.
+ void buildRDBRLLBCK () throws SqlException
+ {
+ createCommand ();
+ writeLengthCodePoint (0x04, CodePoint.RDBRLLBCK);
+ }
+
+ // build the Exchange Server Attributes Command.
+ // This command sends the following information to the server.
+ // - this driver's server class name
+ // - this driver's level of each of the manager's it supports
+ // - this driver's product release level
+ // - this driver's external name
+ // - this driver's server name
+ void buildEXCSAT (String externalName,
+ int targetAgent,
+ int targetSqlam,
+ int targetRdb,
+ int targetSecmgr,
+ int targetCmntcpip,
+ int targetCmnappc,
+ int targetXamgr,
+ int targetSyncptmgr,
+ int targetRsyncmgr) throws SqlException
+ {
+ createCommand ();
+
+ // begin excsat collection by placing the 4 byte llcp in the buffer.
+ // the length of this command will be computed later and "filled in"
+ // with the call to request.updateLengthBytes().
+ markLengthBytes (CodePoint.EXCSAT);
+
+ // place the external name for the client into the buffer.
+ // the external name was previously calculated before the call to this method.
+ buildEXTNAM (externalName);
+
+ // place the server name for the client into the buffer.
+ buildSRVNAM ("Derby");
+
+ // place the server release level for the client into the buffer.
+ // this is a hard coded value for the driver.
+ buildSRVRLSLV();
+
+ // the managers supported by this driver and their levels will
+ // be sent to the server. the variables which store these values
+ // were initialized during object constrcution to the highest values
+ // supported by the driver.
+
+ // for the case of the manager levels object, there is no
+ // need to have the length of the ddm object dynamically calculated
+ // because this method knows exactly how many will be sent and can set
+ // this now.
+ // each manager level class and level are 4 bytes long and
+ // right now 5 are being sent for a total of 20 bytes or 0x14 bytes.
+ // writeScalarHeader will be called to insert the llcp.
+ buildMGRLVLLS (targetAgent,
+ targetSqlam,
+ targetRdb,
+ targetSecmgr,
+ targetXamgr,
+ targetSyncptmgr,
+ targetRsyncmgr);
+
+
+ // place the server class name into the buffer.
+ // this value is hard coded for the driver.
+ buildSRVCLSNM();
+
+ // the excsat command is complete so the updateLengthBytes method
+ // is called to dynamically compute the length for this command and insert
+ // it into the buffer
+ updateLengthBytes();
+ }
+
+ void buildDummyEXCSAT () throws SqlException
+ {
+ createCommand ();
+
+ // begin excsat collection by placing the 4 byte llcp in the buffer.
+ // the length of this command will be computed later and "filled in"
+ // with the call to request.updateLengthBytes().
+ markLengthBytes (CodePoint.EXCSAT);
+
+ // the excsat command is complete so the updateLengthBytes method
+ // is called to dynamically compute the length for this command and insert
+ // it into the buffer
+ updateLengthBytes();
+ }
+
+ void buildACCSEC (int secmec,
+ String rdbnam,
+ byte[] sectkn) throws SqlException
+ {
+ createCommand ();
+
+ // place the llcp for the ACCSEC in the buffer. save the length bytes for
+ // later update
+ markLengthBytes (CodePoint.ACCSEC);
+
+ // the security mechanism is a required instance variable. it will
+ // always be sent.
+ buildSECMEC (secmec);
+
+ // the rdbnam will be built and sent. different sqlam levels support
+ // different lengths. at this point the length has been checked against
+ // the maximum allowable length. so write the bytes and padd up to the
+ // minimum length if needed.
+ buildRDBNAM (rdbnam);
+
+ if (sectkn != null) buildSECTKN (sectkn);
+
+ // the accsec command is complete so notify the the request object to
+ // update the ddm length and the dss header length.
+ updateLengthBytes();
+ }
+
+ void buildSECCHK (int secmec,
+ String rdbnam,
+ String user,
+ String password,
+ byte[] sectkn,
+ byte[] sectkn2) throws SqlException
+ {
+ createCommand ();
+ markLengthBytes (CodePoint.SECCHK);
+
+ // always send the negotiated security mechanism for the connection.
+ buildSECMEC (secmec);
+
+ // the rdbnam will be built and sent. different sqlam levels support
+ // different lengths. at this point the length has been checked against
+ // the maximum allowable length. so write the bytes and padd up to the
+ // minimum length if needed.
+ buildRDBNAM (rdbnam);
+ if (user != null ) buildUSRID (user);
+ if (password != null ) buildPASSWORD (password);
+ if (sectkn != null) buildSECTKN (sectkn);
+ if (sectkn2 != null) buildSECTKN (sectkn2);
+ updateLengthBytes();
+
+ }
+
+ // The Access RDB (ACCRDB) command makes a named relational database (RDB)
+ // available to a requester by creating an instance of an SQL application
+ // manager. The access RDB command then binds the created instance to the target
+ // agent and to the RDB. The RDB remains available (accessed) until
+ // the communications conversation is terminate.
+ void buildACCRDB (String rdbnam,
+ boolean readOnly,
+ byte[] crrtkn,
+ byte[] prddta,
+ Typdef typdef) throws SqlException
+ {
+ createCommand ();
+
+ markLengthBytes (CodePoint.ACCRDB);
+
+ // the relational database name specifies the name of the rdb to
+ // be accessed. this can be different sizes depending on the level of
+ // support. the size will have ben previously checked so at this point just
+ // write the data and pad with the correct number of bytes as needed.
+ // this instance variable is always required.
+ buildRDBNAM (rdbnam);
+
+ // the rdb access manager class specifies an instance of the SQLAM
+ // that accesses the RDB. the sqlam manager class codepoint
+ // is always used/required for this. this instance variable
+ // is always required.
+ buildRDBACCCL();
+
+ // product specific identifier specifies the product release level
+ // of this driver. see the hard coded value in the NetConfiguration class.
+ // this instance variable is always required.
+ buildPRDID();
+
+ // product specific data. this is an optional parameter which carries
+ // product specific information. although it is optional, it will be
+ // sent to the server. use the first byte to determine the number
+ // of the prddta bytes to write to the buffer. note: this length
+ // doesn't include itself so increment by it by 1 to get the actual
+ // length of this data.
+ buildPRDDTA (prddta);
+
+
+ // the typdefnam parameter specifies the name of the data type to data representation
+ // mappings used when this driver sends command data objects.
+ buildTYPDEFNAM (typdef.getTypdefnam());
+
+ if (crrtkn == null)
+ netAgent_.netConnection_.constructCrrtkn();
+
+ buildCRRTKN(netAgent_.netConnection_.crrtkn_);
+
+ // This specifies the single-byte, double-byte
+ // and mixed-byte CCSIDs of the Scalar Data Arrays (SDAs) in the identified
+ // data type to the data representation mapping definitions. This can
+ // contain 3 CCSIDs. The driver will only send the ones which were set.
+ buildTYPDEFOVR (typdef.isCcsidSbcSet(),
+ typdef.getCcsidSbc(),
+ typdef.isCcsidDbcSet(),
+ typdef.getCcsidDbc(),
+ typdef.isCcsidMbcSet(),
+ typdef.getCcsidMbc());
+
+ // RDB allow update is an optional parameter which indicates
+ // whether the RDB allows the requester to perform update operations
+ // in the RDB. If update operations are not allowed, this connection
+ // is limited to read-only access of the RDB resources.
+ buildRDBALWUPD (readOnly);
+
+
+
+ // the Statement Decimal Delimiter (STTDECDEL),
+ // Statement String Delimiter (STTSTRDEL),
+ // and Target Default Value Return (TRGDFTRT) are all optional
+ // instance variables which will not be sent to the server.
+
+ // the command and the dss are complete so make the call to notify
+ // the request object.
+ updateLengthBytes();
+ }
+
+
+ void buildSYNCCTLMigrate() throws SqlException
+ {
+ }
+
+ void buildSYNCCTLCommit (int xaFlags, Xid xid) throws SqlException
+ {
+ }
+
+ void buildSYNCCTLRollback (int xaFlags) throws SqlException
+ {
+ }
+
+
+ // The External Name is the name of the job, task, or process on a
+ // system for which a DDM server is active.
+ private void buildEXTNAM (String extnam) throws SqlException
+ {
+ int extnamTruncateLength = Utils.min (extnam.length(),
+ NetConfiguration.EXTNAM_MAXSIZE);
+
+ writeScalarString (CodePoint.EXTNAM,
+ extnam.substring (0, extnamTruncateLength));
+ }
+
+ // Server Name is the name of the DDM server.
+ private void buildSRVNAM (String srvnam) throws SqlException
+ {
+ int srvnamTruncateLength = Utils.min (srvnam.length(),
+ NetConfiguration.SRVNAM_MAXSIZE);
+ writeScalarString (CodePoint.SRVNAM,
+ srvnam.substring (0,srvnamTruncateLength));
+ }
+
+ // Server Product Release Level String specifies the product
+ // release level of a DDM server.
+ private void buildSRVRLSLV () throws SqlException
+ {
+ // Hard-coded to ClientDNC 1.0 for dnc 1.0.
+ writeScalarString (CodePoint.SRVRLSLV, NetConfiguration.SRVRLSLV);
+ }
+
+ private void buildSRVCLSNM () throws SqlException
+ {
+ // Server class name is hard-coded to QDERBY/JVM for dnc.
+ writeScalarString (CodePoint.SRVCLSNM, NetConfiguration.SRVCLSNM_JVM);
+ }
+
+ // Precondition: valid secmec is assumed.
+ private void buildSECMEC (int secmec) throws SqlException
+ {
+ writeScalar2Bytes (CodePoint.SECMEC, secmec);
+ }
+
+ // Relational Database Name specifies the name of a relational database
+ // of the server.
+ // if length of RDB name <= 18 characters, there is not change to the format
+ // of the RDB name. The length of the RDBNAM remains fixed at 18 which includes
+ // any right bland padding if necessary.
+ // if length of the RDB name is > 18 characters, the length of the RDB name is
+ // identical to the length of the RDB name. No right blank padding is required.
+ private void buildRDBNAM (String rdbnam) throws SqlException
+ {
+ // since this gets built more than once on the connect flow,
+ // see if we can optimize
+
+ int rdbnamLength = rdbnam.length();
+ if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_FIXED_LEN ) {
+ writeScalarPaddedString (CodePoint.RDBNAM,
+ rdbnam,
+ NetConfiguration.PKG_IDENTIFIER_FIXED_LEN); // minimum length of RDBNAM
+ }
+ else {
+ if (rdbnamLength <= NetConfiguration.PKG_IDENTIFIER_MAX_LEN)
+ writeScalarString (CodePoint.RDBNAM, rdbnam);
+ else
+ throw new SqlException (netAgent_.logWriter_, "Length of the Relational Database Name, " +
+ rdbnam +
+ ", exceeds maximum size allowed for PROTOCOL Connection.");// +
+ //"at SQLAM level " + netAgent_.targetSqlam_);
+ }
+ }
+
+ private void buildSECTKN (byte[] sectkn) throws SqlException
+ {
+ if (sectkn.length > NetConfiguration.SECTKN_MAXSIZE)
+ throw new SqlException (netAgent_.logWriter_, "bug check: sectkn too long");
+ writeScalarBytes (CodePoint.SECTKN, sectkn);
+ }
+
+ private void buildUSRID (String usrid) throws SqlException
+ {
+ int usridLength = usrid.length();
+ if ((usridLength == 0) || (usridLength > NetConfiguration.USRID_MAXSIZE))
+ throw new SqlException (netAgent_.logWriter_, "userid length, " + usridLength + ", is not allowed.");
+
+ writeScalarString (CodePoint.USRID, usrid);
+ }
+
+ private void buildPASSWORD (String password) throws SqlException
+ {
+ int passwordLength = password.length();
+ if ((passwordLength == 0) || (passwordLength > NetConfiguration.PASSWORD_MAXSIZE))
+ throw new SqlException (netAgent_.logWriter_, "password length, " + passwordLength + ", is not allowed.");
+ if (netAgent_.logWriter_ != null) {
+ // remember the position of password in order to
+ // mask it out in trace (see Request.sendBytes()).
+ passwordIncluded_ = true;
+ passwordStart_ = offset_ + 4;
+ passwordLength_ = passwordLength;
+ }
+ writeScalarString (CodePoint.PASSWORD, password);
+ }
+
+ private void buildRDBACCCL() throws SqlException
+ {
+ writeScalar2Bytes (CodePoint.RDBACCCL, CodePoint.SQLAM);
+ }
+
+
+ private void buildPRDID () throws SqlException
+ {
+ writeScalarString (CodePoint.PRDID, NetConfiguration.PRDID); // product id is hard-coded to DNC01000 for dnc 1.0.
+ }
+
+ private void buildPRDDTA (byte[] prddta) throws SqlException
+ {
+ int prddtaLength = (prddta[NetConfiguration.PRDDTA_LEN_BYTE] & 0xff) + 1;
+ writeScalarBytes (CodePoint.PRDDTA, prddta, 0, prddtaLength);
+ }
+
+ private void buildTYPDEFNAM (String typdefnam) throws SqlException
+ {
+ writeScalarString (CodePoint.TYPDEFNAM, typdefnam);
+ }
+
+ void buildTYPDEFOVR (boolean sendCcsidSbc,
+ int ccsidSbc,
+ boolean sendCcsidDbc,
+ int ccsidDbc,
+ boolean sendCcsidMbc,
+ int ccsidMbc
+ ) throws SqlException
+ {
+ markLengthBytes (CodePoint.TYPDEFOVR);
+ // write the single-byte ccsid used by this driver.
+ if (sendCcsidSbc) writeScalar2Bytes (CodePoint.CCSIDSBC, ccsidSbc);
+
+ // write the double-byte ccsid used by this driver.
+ if (sendCcsidDbc) writeScalar2Bytes (CodePoint.CCSIDDBC, ccsidDbc);
+
+ // write the mixed-byte ccsid used by this driver
+ if (sendCcsidMbc) writeScalar2Bytes (CodePoint.CCSIDMBC, ccsidMbc);
+
+ updateLengthBytes();
+
+ }
+
+ private void buildMGRLVLLS (int agent,
+ int sqlam,
+ int rdb,
+ int secmgr,
+ int xamgr,
+ int syncptmgr,
+ int rsyncmgr) throws SqlException
+
+ {
+ markLengthBytes(CodePoint.MGRLVLLS);
+
+ // place the managers and their levels in the buffer
+ writeCodePoint4Bytes (CodePoint.AGENT, agent);
+ writeCodePoint4Bytes (CodePoint.SQLAM, sqlam);
+ writeCodePoint4Bytes (CodePoint.RDB, rdb);
+ writeCodePoint4Bytes (CodePoint.SECMGR, secmgr);
+
+ if (netAgent_.netConnection_.isXAConnection())
+ {
+ if (xamgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.XAMGR, xamgr);
+ if (syncptmgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.SYNCPTMGR, syncptmgr);
+ if (rsyncmgr != NetConfiguration.MGRLVL_NA) writeCodePoint4Bytes (CodePoint.RSYNCMGR, rsyncmgr);
+ }
+ updateLengthBytes();
+ }
+
+ private void buildCRRTKN (byte[] crrtkn) throws SqlException
+ {
+ writeScalarBytes (CodePoint.CRRTKN, crrtkn);
+ }
+
+ private void buildRDBALWUPD (boolean readOnly) throws SqlException
+ {
+ if (readOnly) writeScalar1Byte (CodePoint.RDBALWUPD, CodePoint.FALSE);
+ }
+
+}
+
+
+
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionRequest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,1066 @@
+/*
+
+ Derby - Class org.apache.derby.client.net.NetCursor
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where 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.
+
+*/
+
+package org.apache.derby.client.net;
+
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.SqlWarning;
+import org.apache.derby.client.am.SignedBinary;
+import org.apache.derby.client.am.DisconnectException;
+import org.apache.derby.client.am.Blob;
+import org.apache.derby.client.am.Clob;
+import org.apache.derby.client.am.Agent;
+import org.apache.derby.client.am.Types;
+
+public class NetCursor extends org.apache.derby.client.am.Cursor
+{
+
+ NetResultSet netResultSet_;
+ NetAgent netAgent_;
+
+ Typdef qrydscTypdef_;
+
+ int targetSqlamForTypdef_;
+
+
+ // override column meta data
+ int numMddOverrides_;
+ int maximumRowSize_;
+ boolean blocking_; // if true, multiple rows may be "blocked" in a single reply
+
+ // Raw fdoca column meta data.
+ int[] typeToUseForComputingDataLength_;
+ boolean[] isGraphic_;
+
+ // key = column position, value = index into extdtaData_
+ java.util.HashMap extdtaPositions_;
+ java.util.ArrayList extdtaData_; // queue to hold EXTDTA data that hasn't been correlated to its column #
+
+
+ boolean rtnextrow_ = true;
+
+ //-----------------------------constants--------------------------------------
+
+ //---------------------constructors/finalizer---------------------------------
+
+ NetCursor (NetAgent netAgent)
+ {
+ super (netAgent);
+ netAgent_ = netAgent;
+ numMddOverrides_ = 0;
+ maximumRowSize_ = 0;
+ extdtaPositions_ = new java.util.HashMap();
+ extdtaData_ = new java.util.ArrayList ();
+ }
+
+ NetCursor (NetAgent netAgent,
+ int qryprctyp) //protocolType, CodePoint.FIXROWPRC | CodePoint.LMTBLKPRC
+ {
+ this (netAgent);
+ if (qryprctyp == CodePoint.FIXROWPRC)
+ blocking_ = false;
+ else if (qryprctyp == CodePoint.LMTBLKPRC)
+ blocking_ = true;
+ }
+ //-----------------------------parsing the data buffer------------------------
+
+ // Pseudo-code:
+ // parse thru the current row in dataBuffer computing column offsets
+ // if (we hit the super.lastValidBytePosition, ie. encounter partial row) {
+ // shift partial row bytes to beginning of dataBuffer (this.shiftPartialRowToBeginning())
+ // reset current row position (also done by this.shiftPartialRowToBeginning())
+ // send and recv continue-query into commBuffer (rs.flowContinueQuery())
+ // parse commBuffer up to QRYDTA (rs.flowContinueQuery())
+ // copy query data from reply's commBuffer to our dataBuffer (this.copyQrydta())
+ // }
+ // Returns true if the current row position is a valid row position.
+ // rename this to parse*()
+ protected boolean calculateColumnOffsetsForRow_ (int rowIndex) throws SqlException, org.apache.derby.client.am.DisconnectException
+ {
+ int daNullIndicator = CodePoint.NULLDATA;
+ int colNullIndicator = CodePoint.NULLDATA;
+ int length;
+
+ if (hasLobs_)
+ extdtaPositions_.clear(); // reset positions for this row
+
+ int[] columnDataPosition = null;
+ int[] columnDataComputedLength = null;
+ boolean[] columnDataIsNull = null;
+
+ if ((position_ == lastValidBytePosition_) &&
+ (netResultSet_ != null) && (netResultSet_.scrollable_))
+ return false;
+
+ NetSqlca netSqlca = this.parseSQLCARD (qrydscTypdef_);
+
+ if (netSqlca != null) {
+ int sqlcode = netSqlca.getSqlCode();
+ if (sqlcode < 0) {
+ throw new SqlException (netAgent_.logWriter_, netSqlca);
+ }
+ else {
+ if (sqlcode > 0) {
+ if (sqlcode == 100) {
+ allRowsReceivedFromServer_ = true;
+ if (netResultSet_ != null && netSqlca.containsSqlcax())
+ netResultSet_.setRowCountEvent (netSqlca.getRowCount(qrydscTypdef_));
+ }
+ else if (netResultSet_ != null)
+ netResultSet_.accumulateWarning (new SqlWarning (agent_.logWriter_, netSqlca));
+ }
+ }
+ }
+
+ // If we don't have at least one byte in the buffer for the DA null indicator,
+ // then we need to send a CNTQRY request to fetch the next block of data.
+ // Read the DA null indicator.
+ daNullIndicator = readFdocaOneByte ();
+
+ // In the case for held cursors, the +100 comes back as part of the QRYDTA, and as
+ // we are parsing through the row that contains the SQLCA with +100, we mark the
+ // nextRowPosition_ which is the lastValidBytePosition_, but we don't mark the
+ // currentRowPosition_ until the next time next() is called causing the check
+ // cursor_.currentRowPositionIsEqualToNextRowPosition () to fail in getRow() and thus
+ // not returning 0 when it should. So we need to mark the current row position immediately
+ // in order for getRow() to be able to pick it up.
+
+ // markNextRowPosition() is called again once this method returns, but it is ok
+ // since it's only resetting nextRowPosition_ to position_ and position_ will
+ // not change again from this point.
+
+ if (allRowsReceivedFromServer_ && (position_ == lastValidBytePosition_)) {
+ markNextRowPosition ();
+ makeNextRowPositionCurrent ();
+ return false;
+ }
+
+ // If data flows....
+ if (daNullIndicator == 0x0) {
+
+ incrementRowsReadEvent();
+
+ // netResultSet_ is null if this method is invoked from Lob.position()
+ // If row has exceeded the size of the ArrayList, new up a new int[] and add it to the
+ // ArrayList, otherwise just reuse the int[].
+ if (netResultSet_ != null && netResultSet_.scrollable_) {
+ columnDataPosition = allocateColumnDataPositionArray (rowIndex);
+ columnDataComputedLength = allocateColumnDataComputedLengthArray (rowIndex);
+ columnDataIsNull = allocateColumnDataIsNullArray (rowIndex);
+ // Since we are no longer setting the int[]'s to null for a delete/update hole, we need
+ // another way of keeping track of the delete/update holes.
+ setIsUpdataDeleteHole (rowIndex, false);
+ }
+ else {
+ // Use the arrays defined on the Cursor for forward-only cursors.
+ // can they ever be null
+ if (columnDataPosition_ == null || columnDataComputedLength_ == null || isNull_ == null)
+ allocateColumnOffsetAndLengthArrays ();
+ columnDataPosition = columnDataPosition_;
+ columnDataComputedLength = columnDataComputedLength_;
+ columnDataIsNull = isNull_;
+ }
+
+ // Loop through the columns
+ for (int index = 0; index < columns_; index++) {
+ // If column is nullable, read the 1-byte null indicator.
+ if (nullable_[index])
+ // Need to pass the column index so all previously calculated offsets can be
+ // readjusted if the query block splits on a column null indicator.
+
+ // null indicators from FD:OCA data
+ // 0 to 127: a data value will flow.
+ // -1 to -128: no data value will flow.
+ colNullIndicator = readFdocaOneByte (index);
+
+ // If non-null column data
+ if (!nullable_[index] || (colNullIndicator >= 0 && colNullIndicator <= 127)) {
+
+ // Set the isNull indicator to false
+ columnDataIsNull[index] = false;
+
+ switch (typeToUseForComputingDataLength_[index]) {
+ // for fixed length data
+ case Typdef.FIXEDLENGTH:
+ columnDataPosition[index] = position_;
+ if (isGraphic_[index])
+ columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index]*2, index);
+ else
+ columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index], index);
+ break;
+
+ // for variable character string and variable byte string,
+ // there are 2-byte of length in front of the data
+ case Typdef.TWOBYTELENGTH:
+ columnDataPosition[index] = position_;
+ length = readFdocaTwoByteLength (index);
+ // skip length + the 2-byte length field
+ if (isGraphic_[index])
+ columnDataComputedLength[index] = skipFdocaBytes (length*2, index) + 2;
+ else
+ columnDataComputedLength[index] = skipFdocaBytes (length, index) + 2;
+ break;
+
+ // For decimal columns, determine the precision, scale, and the representation
+ case Typdef.DECIMALLENGTH:
+ columnDataPosition[index] = position_;
+ columnDataComputedLength[index] = skipFdocaBytes (getDecimalLength(index), index);
+ break;
+
+ case Typdef.LOBLENGTH:
+ columnDataPosition[index] = position_;
+ columnDataComputedLength[index] = this.skipFdocaBytes (fdocaLength_[index] & 0x7fff, index);
+ break;
+
+ // for short variable character string and short variable byte string,
+ // there is a 1-byte length in front of the data
+ case Typdef.ONEBYTELENGTH:
+ columnDataPosition[index] = position_;
+ length = readFdocaOneByte (index);
+ // skip length + the 1-byte length field
+ if (isGraphic_[index])
+ columnDataComputedLength[index] = skipFdocaBytes (length*2, index) + 1;
+ else
+ columnDataComputedLength[index] = skipFdocaBytes (length, index) + 1;
+ break;
+
+ default:
+ columnDataPosition[index] = position_;
+ if (isGraphic_[index])
+ columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index]*2, index);
+ else
+ columnDataComputedLength[index] = skipFdocaBytes (fdocaLength_[index], index);
+ break;
+ }
+ }
+ else if ((colNullIndicator & 0x80) == 0x80) {
+ // Null data. Set the isNull indicator to true.
+ columnDataIsNull[index] = true;
+ }
+ }
+
+ // set column offsets for the current row.
+ columnDataPosition_ = columnDataPosition;
+ columnDataComputedLength_ = columnDataComputedLength;
+ isNull_ = columnDataIsNull;
+
+ if (!allRowsReceivedFromServer_) {
+ calculateLobColumnPositionsForRow();
+ // Flow another CNTQRY if we are blocking, are using rtnextrow, and expect
+ // non-trivial EXTDTAs for forward only cursors. Note we do not support
+ // EXTDTA retrieval for scrollable cursors.
+ // if qryrowset was sent on excsqlstt for a sp call, which is only the case
+ if (blocking_ && rtnextrow_ &&
+ extdtaPositions_.size () > 0 && !netResultSet_.scrollable_)
+ if (!extdtaPositions_.isEmpty())
+ netResultSet_.flowFetch ();
+ }
+ }
+
+ // Else if this row is null, only add to the isRowNullCache_ if the cursor is scrollable.
+ else {
+ if (netResultSet_ != null && netResultSet_.scrollable_) setIsUpdataDeleteHole (rowIndex, true);
+ }
+
+ // If blocking protocol is used, we could have already received an ENDQRYRM,
+ // which sets allRowsReceivedFromServer_ to true. It's safe to assume that all of
+ // our QRYDTA's have been successfully copied to the dataBuffer. And even though
+ // the flag for allRowsReceivedFromServer_ is set, we still want to continue to parse through
+ // the data in the dataBuffer.
+ // But in the case where fixed row protocol is used,
+ if (!blocking_ && allRowsReceivedFromServer_ && daNullIndicator == 0xFF)
+ return false;
+ else
+ return true;
+ }
+
+ protected boolean isDataBufferNull ()
+ {
+ if (dataBuffer_ == null)
+ return true;
+ else
+ return false;
+ }
+
+ protected void allocateDataBuffer ()
+ {
+ int length;
+ if (maximumRowSize_ > DssConstants.MAX_DSS_LEN)
+ length = maximumRowSize_;
+ else
+ length = DssConstants.MAX_DSS_LEN;
+
+ dataBuffer_ = new byte[length];
+ position_ = 0;
+ lastValidBytePosition_ = 0;
+ }
+
+ protected void allocateDataBuffer (int length)
+ {
+ dataBuffer_ = new byte[length];
+ }
+
+
+ private int readFdocaInt () throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ if ((position_ + 4) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ int i = SignedBinary.getInt (dataBuffer_, position_);
+ position_ += 4;
+ return i;
+ }
+
+ // Reads 1-byte from the dataBuffer from the current position.
+ // If position is already at the end of the buffer, send CNTQRY to get more data.
+ private int readFdocaOneByte () throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if (position_ == lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+ return dataBuffer_[position_++] & 0xff;
+ }
+
+ // Reads 1-byte from the dataBuffer from the current position.
+ // If position is already at the end of the buffer, send CNTQRY to get more data.
+ private int readFdocaOneByte (int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if (position_ == lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow (index);
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+ return dataBuffer_[position_++] & 0xff;
+ }
+
+ // Reads <i>length</i> number of bytes from the dataBuffer starting from the
+ // current position. Returns a new byte array which contains the bytes read.
+ // If current position plus length goes past the lastValidBytePosition, send
+ // CNTQRY to get more data.
+ private byte[] readFdocaBytes (int length) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ byte[] b = new byte[length];;
+
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + length) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ for (int i = 0; i < length; i++)
+ b[i] = dataBuffer_[position_++];
+
+ return b;
+ }
+
+ // Reads 2-bytes from the dataBuffer starting from the current position, and
+ // returns an integer constructed from the 2-bytes. If current position plus
+ // 2 bytes goes past the lastValidBytePosition, send CNTQRY to get more data.
+ private int readFdocaTwoByteLength () throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + 2) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ return
+ ((dataBuffer_[position_++] & 0xff) << 8) +
+ ((dataBuffer_[position_++] & 0xff) << 0);
+ }
+
+ private int readFdocaTwoByteLength (int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + 2) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow (index);
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ return
+ ((dataBuffer_[position_++] & 0xff) << 8) +
+ ((dataBuffer_[position_++] & 0xff) << 0);
+ }
+
+ // Check if position plus length goes past the lastValidBytePosition.
+ // If so, send CNTQRY to get more data.
+ // length - number of bytes to skip
+ // returns the number of bytes skipped
+ private int skipFdocaBytes (int length) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + length) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+ position_ += length;
+ return length;
+ }
+
+ private int skipFdocaBytes (int length, int index) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + length) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow (index);
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ position_ += length;
+ return length;
+ }
+
+ // Shift partial row bytes to beginning of dataBuffer,
+ // and resets current row position, and lastValidBytePosition.
+ // When we shift partial row, we'll have to recalculate column offsets
+ // up to this column.
+ private void shiftPartialRowToBeginning ()
+ {
+ // Get the length to shift from the beginning of the partial row.
+ int length = lastValidBytePosition_ - currentRowPosition_;
+
+ // shift the data in the dataBufferStream
+ dataBufferStream_.reset ();
+ if (dataBuffer_ != null)
+ dataBufferStream_.write (dataBuffer_, currentRowPosition_, length);
+
+ for (int i = 0; i < length; i++)
+ dataBuffer_[i] = dataBuffer_[currentRowPosition_+i];
+
+ position_ = length - (lastValidBytePosition_ - position_);
+ lastValidBytePosition_ = length;
+ }
+
+ private void adjustColumnOffsetsForColumnsPreviouslyCalculated (int index)
+ {
+ for (int j = 0; j <= index; j++) {
+ columnDataPosition_[j] -= currentRowPosition_;
+ }
+ }
+
+ private void resetCurrentRowPosition ()
+ {
+ currentRowPosition_ = 0;
+ }
+
+ // Calculates the column index for Lob objects constructed from EXTDTA data.
+ // Describe information isn't sufficient because we have to check
+ // for trivial values (nulls or zero-length) and exclude them.
+ void calculateLobColumnPositionsForRow ()
+ {
+ int currentPosition = 0;
+
+ for (int i = 0; i < columns_; i++) {
+ if ( isNonTrivialDataLob (i) )
+ // key = column position, data = index to corresponding data in extdtaData_
+ // ASSERT: the server always returns the EXTDTA objects in ascending order
+ extdtaPositions_.put(new Integer(i + 1), new Integer (currentPosition++));
+ }
+ }
+
+ // prereq: the base data for the cursor has been processed for offsets and lengths
+ boolean isNonTrivialDataLob (int index)
+ {
+ long length = 0L;
+
+ if (isNull_[index] ||
+ (jdbcTypes_[index] != Types.BLOB &&
+ jdbcTypes_[index] != Types.CLOB) )
+ return false;
+
+ int position = columnDataPosition_[index];
+
+ // if the high-order bit is set, length is unknown -> set value to x'FF..FF'
+ if (((dataBuffer_[position])&0x80) == 0x80)
+ length = -1;
+ else {
+
+ byte[] lengthBytes = new byte[columnDataComputedLength_[index]];
+ byte[] longBytes = new byte[8];
+
+ System.arraycopy (dataBuffer_,
+ position,
+ lengthBytes,
+ 0,
+ columnDataComputedLength_[index] );
+
+ // right-justify for BIG ENDIAN
+ int j = 0;
+ for (int i = 8 - columnDataComputedLength_[index]; i < 8; i++) {
+ longBytes[i] = lengthBytes[j];
+ j++;
+ }
+ length = SignedBinary.getLong (longBytes, 0);
+ }
+ return (length != 0L)?true:false;
+ }
+
+ protected void clearLobData_()
+ {
+ extdtaData_.clear ();
+ extdtaPositions_.clear ();
+ }
+
+ // SQLCARD : FDOCA EARLY ROW
+ // SQL Communications Area Row Description
+ //
+ // FORMAT FOR ALL SQLAM LEVELS
+ // SQLCAGRP; GROUP LID 0x54; ELEMENT TAKEN 0(all); REP FACTOR 1
+ NetSqlca parseSQLCARD (Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ return parseSQLCAGRP (typdef);
+ }
+
+ // SQLCAGRP : FDOCA EARLY GROUP
+ // SQL Communcations Area Group Description
+ //
+ // FORMAT FOR SQLAM <= 6
+ // SQLCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLSTATE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
+ // SQLERRPROC; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
+ // SQLCAXGRP; PROTOCOL TYPE N-GDA; ENVLID 0x52; Length Override 0
+ //
+ // FORMAT FOR SQLAM >= 7
+ // SQLCODE; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLSTATE; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 5
+ // SQLERRPROC; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 8
+ // SQLCAXGRP; PROTOCOL TYPE N-GDA; ENVLID 0x52; Length Override 0
+ // SQLDIAGGRP; PROTOCOL TYPE N-GDA; ENVLID 0x56; Length Override 0
+ private NetSqlca parseSQLCAGRP (Typdef typdef) throws org.apache.derby.client.am.DisconnectException, SqlException
+ {
+ if (readFdocaOneByte() == CodePoint.NULLDATA)
+ return null;
+ int sqlcode = readFdocaInt();
+ byte[] sqlstate = readFdocaBytes (5);
+ byte[] sqlerrproc = readFdocaBytes (8);
+ NetSqlca netSqlca = new NetSqlca (netAgent_.netConnection_, sqlcode, sqlstate, sqlerrproc, typdef.getCcsidSbc());
+
+ parseSQLCAXGRP (typdef, netSqlca);
+
+ parseSQLDIAGGRP ();
+
+ return netSqlca;
+ }
+
+ // SQLCAXGRP : EARLY FDOCA GROUP
+ // SQL Communications Area Exceptions Group Description
+ //
+ // FORMAT FOR SQLAM <= 6
+ // SQLRDBNME; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 18
+ // SQLERRD1; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD2; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD3; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD4; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD5; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLWARN0; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN1; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN2; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN3; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN4; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN5; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN6; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN7; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN8; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN9; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
+ // SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
+ //
+ // FORMAT FOR SQLAM >= 7
+ // SQLERRD1; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD2; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD3; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD4; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD5; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ // SQLWARN0; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN1; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN2; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN3; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN4; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN5; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN6; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN7; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN8; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARN9; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ // SQLRDBNAME; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
+ // SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
+ // SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
+ private void parseSQLCAXGRP (Typdef typdef, NetSqlca netSqlca) throws DisconnectException, SqlException
+ {
+ if (readFdocaOneByte() == CodePoint.NULLDATA) {
+ netSqlca.setContainsSqlcax (false);
+ return;
+ }
+
+
+ // SQLERRD1 to SQLERRD6; PROTOCOL TYPE I4; ENVLID 0x02; Length Override 4
+ int[] sqlerrd = new int[6];
+ for (int i = 0; i < sqlerrd.length; i++)
+ sqlerrd[i] = readFdocaInt ();
+
+ // SQLWARN0 to SQLWARNA; PROTOCOL TYPE FCS; ENVLID 0x30; Length Override 1
+ byte[] sqlwarn = readFdocaBytes (11);
+
+ // skip over the rdbnam for now
+ // SQLRDBNAME; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 255
+ parseVCS (typdef);
+
+ // SQLERRMSG_m; PROTOCOL TYPE VCM; ENVLID 0x3E; Length Override 70
+ // SQLERRMSG_s; PROTOCOL TYPE VCS; ENVLID 0x32; Length Override 70
+ int varcharLength = readFdocaTwoByteLength(); // mixed length
+ byte[] sqlerrmc = null;
+ int sqlerrmcCcsid = 0;
+ if (varcharLength != 0) { // if mixed
+ sqlerrmc = readFdocaBytes(varcharLength); // read mixed bytes
+ sqlerrmcCcsid = typdef.getCcsidMbc();
+ skipFdocaBytes(2); // skip single length
+ }
+ else {
+ varcharLength = readFdocaTwoByteLength(); // read single length
+ sqlerrmc = readFdocaBytes (varcharLength); // read single bytes
+ sqlerrmcCcsid = typdef.getCcsidSbc();
+ }
+
+ netSqlca.setSqlerrd (sqlerrd);
+ netSqlca.setSqlwarnBytes (sqlwarn);
+ netSqlca.setSqlerrmcBytes (sqlerrmc, sqlerrmcCcsid);
+ }
+
+ // SQLDIAGGRP : FDOCA EARLY GROUP
+ private void parseSQLDIAGGRP () throws DisconnectException, SqlException
+ {
+ if (readFdocaOneByte() == CodePoint.NULLDATA)
+ return;
+
+ netAgent_.accumulateChainBreakingReadExceptionAndThrow (new DisconnectException (
+ netAgent_,
+ "parseSQLDIAGGRP not yet implemented"));
+ }
+
+ private String parseVCS (Typdef typdefInEffect) throws DisconnectException, SqlException
+ {
+ return readFdocaString(readFdocaTwoByteLength(),
+ typdefInEffect.getCcsidSbcEncoding());
+ }
+
+ // This is not used for column data.
+ private String readFdocaString (int length, String encoding) throws DisconnectException, SqlException
+ {
+ if (length == 0)
+ return null;
+
+ // For singleton select, the complete row always comes back, even if multiple query blocks are required,
+ // so there is no need to drive a flowFetch (continue query) request for singleton select.
+ if ((position_ + length) > lastValidBytePosition_) {
+ // Check for ENDQRYRM, throw SqlException if already received one.
+ checkAndThrowReceivedEndqryrm ();
+
+ // Send CNTQRY to complete the row/rowset.
+ int lastValidByteBeforeFetch = completeSplitRow ();
+
+ // if lastValidBytePosition_ has not changed, and an ENDQRYRM was received,
+ // throw a SqlException for the ENDQRYRM.
+ checkAndThrowReceivedEndqryrm (lastValidByteBeforeFetch);
+ }
+
+ String s = null;
+
+ try {
+ s = new String (dataBuffer_, position_, length, encoding);
+ }
+ catch (java.io.UnsupportedEncodingException e) {
+ netAgent_.accumulateChainBreakingReadExceptionAndThrow (
+ new org.apache.derby.client.am.DisconnectException (
+ e,
+ netAgent_,
+ "encoding not supported!!"));
+ }
+
+ position_ += length;
+ return s;
+ }
+
+ void allocateColumnOffsetAndLengthArrays ()
+ {
+ columnDataPosition_ = new int[columns_];
+ columnDataComputedLength_ = new int[columns_];
+ isNull_ = new boolean[columns_];
+ }
+
+ void setBlocking (int queryProtocolType)
+ {
+ if (queryProtocolType == CodePoint.LMTBLKPRC)
+ blocking_ = true;
+ else
+ blocking_ = false;
+ }
+
+ protected byte[] findExtdtaData (int column)
+ {
+ byte[] data = null;
+
+ // locate the EXTDTA bytes, if any
+ Integer key = new Integer(column);
+
+ if (extdtaPositions_.containsKey (key)) {
+ // found, get the data
+ int extdtaQueuePosition = ((Integer) extdtaPositions_.get(key)).intValue();
+ data = (byte[]) (extdtaData_.get(extdtaQueuePosition));
+ }
+
+ return data;
+ }
+
+ public Blob getBlobColumn_ (int column, Agent agent) throws SqlException
+ {
+ int index = column - 1;
+ int dataOffset;
+ byte[] data;
+ Blob blob = null;
+
+ // locate the EXTDTA bytes, if any
+ data = findExtdtaData (column);
+
+ if (data != null) {
+ // data found
+ // set data offset based on the presence of a null indicator
+ if (!nullable_[index])
+ dataOffset = 0;
+ else
+ dataOffset = 1;
+
+ blob = new Blob ( data, agent, dataOffset);
+ }
+ else {
+ blob = new Blob (new byte[0], agent, 0);
+ }
+
+ return blob;
+ }
+
+
+ public Clob getClobColumn_ (int column, Agent agent) throws SqlException
+ {
+ int index = column - 1;
+ int dataOffset;
+ byte[] data;
+ Clob clob = null;
+
+ // locate the EXTDTA bytes, if any
+ data = findExtdtaData (column);
+
+ if (data != null) {
+ // data found
+ // set data offset based on the presence of a null indicator
+ if (! nullable_[index])
+ dataOffset = 0;
+ else
+ dataOffset = 1;
+ clob = new Clob (agent, data, charsetName_[index], dataOffset);
+ }
+ else {
+ // the locator is not valid, it is a zero-length LOB
+ clob = new Clob (agent, "");
+ }
+
+ return clob;
+ }
+
+ public byte[] getClobBytes_ (int column, int[] dataOffset /*output*/) throws SqlException
+ {
+ int index = column - 1;
+ byte[] data = null;
+
+ // locate the EXTDTA bytes, if any
+ data = findExtdtaData (column);
+
+ if (data != null) {
+ // data found
+ // set data offset based on the presence of a null indicator
+ if (! nullable_[index])
+ dataOffset[0] = 0;
+ else
+ dataOffset[0] = 1;
+ }
+
+ return data;
+ }
+
+ // this is really an event-callback from NetStatementReply.parseSQLDTARDarray()
+ void initializeColumnInfoArrays (Typdef typdef,
+ int columnCount, int targetSqlamForTypdef) throws DisconnectException
+ {
+ qrydscTypdef_ = typdef;
+
+ // Allocate arrays to hold the descriptor information.
+ setNumberOfColumns (columnCount);
+ fdocaLength_ = new int[columnCount];
+ isGraphic_ = new boolean[columnCount];
+ typeToUseForComputingDataLength_ = new int[columnCount];
+ targetSqlamForTypdef_ = targetSqlamForTypdef;
+ }
+
+
+ int ensureSpaceForDataBuffer (int ddmLength)
+ {
+ if (dataBuffer_ == null) {
+ allocateDataBuffer();
+ }
+ //super.resultSet.cursor.clearColumnDataOffsetsCache();
+ // Need to know how many bytes to ask from the Reply object,
+ // and handle the case where buffer is not big enough for all the bytes.
+ // Get the length in front of the code point first.
+
+ int bytesAvailableInDataBuffer = dataBuffer_.length - lastValidBytePosition_;
+
+ // Make sure the buffer has at least ddmLength amount of room left.
+ // If not, expand the buffer before calling the getQrydtaData() method.
+ if (bytesAvailableInDataBuffer < ddmLength) {
+
+ // Get a new buffer that is twice the size of the current buffer.
+ // Copy the contents from the old buffer to the new buffer.
+ int newBufferSize = 2 * dataBuffer_.length;
+
+ while (newBufferSize < ddmLength) {
+ newBufferSize = 2 * newBufferSize;
+ }
+
+ byte[] tempBuffer = new byte[newBufferSize];
+
+ System.arraycopy (dataBuffer_,
+ 0,
+ tempBuffer,
+ 0,
+ lastValidBytePosition_);
+
+ // Make the new buffer the dataBuffer.
+ dataBuffer_ = tempBuffer;
+
+ // Recalculate bytesAvailableInDataBuffer
+ bytesAvailableInDataBuffer = dataBuffer_.length - lastValidBytePosition_;
+ }
+ return bytesAvailableInDataBuffer;
+ }
+
+ protected void getMoreData_ () throws SqlException
+ {
+ // reset the dataBuffer_ before getting more data if cursor is foward-only.
+ // getMoreData() is only called in Cursor.next() when current position is
+ // equal to lastValidBytePosition_.
+ if (netResultSet_.resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
+ resetDataBuffer();
+ netResultSet_.flowFetch ();
+ }
+
+ public void nullDataForGC () // memory leak fix
+ {
+ super.nullDataForGC();
+ qrydscTypdef_ = null;
+ typeToUseForComputingDataLength_ = null;
+ isGraphic_ = null;
+
+ if (extdtaPositions_ != null) extdtaPositions_.clear();
+ extdtaPositions_ = null;
+
+ if (extdtaData_ != null) extdtaData_.clear();
+ extdtaData_ = null;
+ }
+
+ // It is possible for the driver to have received an QRYDTA(with incomplete row)+ENDQRYRM+SQLCARD.
+ // This means some error has occurred on the server and the server is terminating the query.
+ // Before sending a CNTQRY to retrieve the rest of the split row, check if an ENDQRYRM has already
+ // been received. If so, do not send CNTQRY because the cursor is already closed on the server.
+ // Instead, throw a SqlException. Since we did not receive a complete row, it is not safe to
+ // allow the application to continue to access the ResultSet, so we close it.
+ private void checkAndThrowReceivedEndqryrm () throws SqlException
+ {
+ // If we are in a split row, and before sending CNTQRY, check whether an ENDQRYRM
+ // has been received.
+ if (!netResultSet_.openOnServer_) {
+ SqlException sqlException = null;
+ int sqlcode = org.apache.derby.client.am.Utils.getSqlcodeFromSqlca (netResultSet_.queryTerminatingSqlca_);
+ if (sqlcode < 0)
+ sqlException = new SqlException (agent_.logWriter_, netResultSet_.queryTerminatingSqlca_);
+ else
+ sqlException = new SqlException (agent_.logWriter_, "Query processing has been terminated due to error on the server.");
+ try {
+ netResultSet_.closeX(); // the auto commit logic is in closeX()
+ }
+ catch (SqlException e) {
+ sqlException.setNextException (e);
+ }
+ throw sqlException;
+ }
+ }
+
+ private void checkAndThrowReceivedEndqryrm (int lastValidBytePositionBeforeFetch) throws SqlException
+ {
+ // if we have received more data in the dataBuffer_, just return.
+ if (lastValidBytePosition_ > lastValidBytePositionBeforeFetch)
+ return;
+ checkAndThrowReceivedEndqryrm ();
+ }
+
+ private int completeSplitRow () throws DisconnectException, SqlException
+ {
+ int lastValidBytePositionBeforeFetch = 0;
+ if (netResultSet_ != null && netResultSet_.scrollable_) {
+ lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+ netResultSet_.flowFetchToCompleteRowset ();
+ }
+ else {
+ // Shift partial row to the beginning of the dataBuffer
+ shiftPartialRowToBeginning ();
+ resetCurrentRowPosition ();
+ lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+ netResultSet_.flowFetch ();
+ }
+ return lastValidBytePositionBeforeFetch;
+ }
+
+ private int completeSplitRow (int index) throws DisconnectException, SqlException
+ {
+ int lastValidBytePositionBeforeFetch = 0;
+ if (netResultSet_ != null && netResultSet_.scrollable_) {
+ lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+ netResultSet_.flowFetchToCompleteRowset ();
+ }
+ else {
+ // Shift partial row to the beginning of the dataBuffer
+ shiftPartialRowToBeginning ();
+ adjustColumnOffsetsForColumnsPreviouslyCalculated (index);
+ resetCurrentRowPosition ();
+ lastValidBytePositionBeforeFetch = lastValidBytePosition_;
+ netResultSet_.flowFetch ();
+ }
+ return lastValidBytePositionBeforeFetch;
+ }
+
+ private int[] allocateColumnDataPositionArray (int row)
+ {
+ int[] columnDataPosition;
+ if (columnDataPositionCache_.size() == row) {
+ columnDataPosition = new int[columns_];
+ columnDataPositionCache_.add (columnDataPosition);
+ }
+ else
+ columnDataPosition = (int[])columnDataPositionCache_.get(row);
+ return columnDataPosition;
+ }
+
+ private int[] allocateColumnDataComputedLengthArray (int row)
+ {
+ int[] columnDataComputedLength;
+ if (columnDataLengthCache_.size() == row) {
+ columnDataComputedLength = new int[columns_];
+ columnDataLengthCache_.add (columnDataComputedLength);
+ }
+ else
+ columnDataComputedLength = (int[])columnDataLengthCache_.get(row);
+ return columnDataComputedLength;
+ }
+
+ private boolean[] allocateColumnDataIsNullArray (int row)
+ {
+ boolean[] columnDataIsNull;
+ if (columnDataIsNullCache_.size() <= row) {
+ columnDataIsNull = new boolean[columns_];
+ columnDataIsNullCache_.add(columnDataIsNull);
+ }
+ else
+ columnDataIsNull = (boolean[])columnDataIsNullCache_.get(row);
+ return columnDataIsNull;
+ }
+
+ protected int getDecimalLength (int index)
+ {
+ return (((fdocaLength_[index] >> 8) & 0xff) + 2) / 2;
+ }
+
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,80 @@
+/*
+
+ Derby - Class org.apache.derby.client.net.NetDatabaseMetaData
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where 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.
+
+*/
+package org.apache.derby.client.net;
+
+import org.apache.derby.client.am.Configuration;
+import org.apache.derby.client.am.ProductLevel;
+import org.apache.derby.client.am.SqlException;
+
+
+public class NetDatabaseMetaData extends org.apache.derby.client.am.DatabaseMetaData
+{
+
+ private final NetAgent netAgent_;
+
+
+ public NetDatabaseMetaData (NetAgent netAgent, NetConnection netConnection)
+ {
+ // Consider setting product level during parse
+ super (netAgent, netConnection, new ProductLevel (netConnection.productID_,
+ netConnection.targetSrvclsnm_,
+ netConnection.targetSrvrlslv_));
+ // Set up cheat-links
+ netAgent_ = netAgent;
+ }
+
+ //---------------------------call-down methods--------------------------------
+
+ public String getURL_ () throws SqlException
+ {
+ String urlProtocol;
+
+ urlProtocol = Configuration.jdbcDerbyNETProtocol;
+
+ return
+ urlProtocol +
+ connection_.serverNameIP_+
+ ":" +
+ connection_.portNumber_ +
+ "/" +
+ connection_.databaseName_;
+ }
+
+ //-----------------------------helper methods---------------------------------
+
+ // Set flags describing the level of support for this connection.
+ // Flags will be set based on manager level and/or specific product identifiers.
+ // Support for a specific server version can be set as follows. For example
+ // if (productLevel_.greaterThanOrEqualTo(11,1,0))
+ // supportsTheBestThingEver = true
+ protected void computeFeatureSet_ ()
+ {
+ if (connection_.resultSetHoldability_ == 0) // property not set
+ setDefaultResultSetHoldability ();
+
+ }
+
+
+ public void setDefaultResultSetHoldability ()
+ {
+ connection_.resultSetHoldability_ = org.apache.derby.jdbc.ClientDataSource.HOLD_CURSORS_OVER_COMMIT;
+ }
+
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,84 @@
+/*
+
+ Derby - Class org.apache.derby.client.net.NetXACallInfo
+
+ Copyright (c) 2002, 2005 The Apache Software Foundation or its licensors, where 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.
+
+*/
+package org.apache.derby.client.net;
+
+import javax.transaction.xa.*;
+
+/**
+ * <p>Title: dnc Project</p>
+ * <p>Description: </p>
+ * @version 1.0
+ */
+
+public class NetIndoubtTransaction
+{
+
+ Xid xid_;
+ byte[] uowid_;
+ byte[] cSyncLog_;
+ byte[] pSyncLog_;
+ String ipaddr_;
+ int port_;
+
+ protected NetIndoubtTransaction(Xid xid,
+ byte[] uowid,
+ byte[] cSyncLog,
+ byte[] pSyncLog,
+ String ipaddr,
+ int port)
+ {
+ xid_ = xid;
+ uowid_ = uowid;
+ cSyncLog_ = cSyncLog;
+ pSyncLog_ = pSyncLog;
+ ipaddr_ = ipaddr;
+ port_ = port;
+ }
+
+ protected Xid getXid()
+ {
+ return xid_;
+ }
+
+ protected byte[] getUOWID()
+ {
+ return uowid_;
+ }
+
+ protected byte[] getCSyncLog()
+ {
+ return cSyncLog_;
+ }
+
+ protected byte[] getPSyncLog()
+ {
+ return pSyncLog_;
+ }
+
+ protected String getIpAddr()
+ {
+ return ipaddr_;
+ }
+
+ protected int getPort()
+ {
+ return port_;
+ }
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetIndoubtTransaction.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,416 @@
+/*
+
+ Derby - Class org.apache.derby.client.net.NetLogWriter
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where 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.
+
+*/
+
+package org.apache.derby.client.net;
+
+// network traffic tracer.
+// This class traces communication buffers for both sends and receives.
+// The value of the hex bytes are traced along with the ascii and ebcdic translations.
+public class NetLogWriter extends org.apache.derby.client.am.LogWriter
+{
+
+ // The recevie constant is used to indicate that the bytes were read to a Stream.
+ // It indicates to this class that a receive header should be used.
+ public static final int TYPE_TRACE_RECEIVE = 2;
+
+ // The send constant is used to indicate that the bytes were written to
+ // a Stream. It indicates to this class that a send header should be used.
+ public static final int TYPE_TRACE_SEND = 1;
+
+ //------------------------------ internal constants --------------------------
+
+ // This class was implemented using character arrays to translate bytes
+ // into ascii and ebcdic. The goal was to be able to quickly index into the
+ // arrays to find the characters. Char arrays instead of strings were used as
+ // much as possible in an attempt to help speed up performance.
+
+ // An array of characters used to translate bytes to ascii.
+ // The position in the array corresponds to the hex value of the character.
+ private static final char asciiChar__ [] = {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //0
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //1
+ ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', //2
+ '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', //3
+ '@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', //4
+ 'P','Q','R','S','T','U','V','W','X','Y','Z','[','\\',']','^','_', //5
+ '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', //6
+ 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~','.', //7
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //8
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //9
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //A
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //B
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //C
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //D
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //E
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.' //F
+ };
+
+ // This column position header is used to mark offsets into the trace.
+ private static final String colPosHeader__ =
+ " 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF";
+
+ // An array of characters used to translate bytes to ebcdic.
+ // The position in the array corresponds to the hex value of the
+ // character.
+ private static final char ebcdicChar__[] = {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //0
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //1
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //2
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //3
+ ' ','.','.','.','.','.','.','.','.','.','.','.','<','(','+','|', //4
+ '&','.','.','.','.','.','.','.','.','.','!','$','*',')',';','.', //5
+ '-','/','.','.','.','.','.','.','.','.','|',',','%','_','>','?', //6
+ '.','.','.','.','.','.','.','.','.','`',':','#','@','\'','=','"', //7
+ '.','a','b','c','d','e','f','g','h','i','.','.','.','.','.','.', //8
+ '.','j','k','l','m','n','o','p','q','r','.','.','.','.','.','.', //9
+ '.','~','s','t','u','v','w','x','y','z','.','.','.','.','.','.', //A
+ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', //B
+ '{','A','B','C','D','E','F','G','H','I','.','.','.','.','.','.', //C
+ '}','J','K','L','M','N','O','P','Q','R','.','.','.','.','.','.', //D
+ '\\','.','S','T','U','V','W','X','Y','Z','.','.','.','.','.','.', //E
+ '0','1','2','3','4','5','6','7','8','9','.','.','.','.','.','.' //F
+ };
+
+ // An array of characters representing hex numbers.
+ private static final char hexDigit__ [] = {
+ '0','1','2','3','4','5','6','7',
+ '8','9','A','B','C','D','E','F'
+ };
+
+ // The receive header comes befor bytes which would be read from a stream.
+ private static final String receiveHeader__ =
+ " RECEIVE BUFFER: (ASCII) (EBCDIC)";
+
+ // The send header comes before bytes which would be written to a stream.
+ private static final String sendHeader__ =
+ " SEND BUFFER: (ASCII) (EBCDIC)";
+
+ private static final char spaceChar__ = ' ';
+
+ private static final char zeroChar__ = '0';
+
+ // This mapping table associates a codepoint to a String describing the codepoint.
+ // This is needed because the trace prints the first codepoint in send and receive buffers.
+ // This is created lazily because there is no need to create the mapping if tracing isn't used.
+ // So this array will only be created when the com buffer trace is started.
+ private static CodePointNameTable codePointNameTable__ = null;
+
+ //-----------------------------internal state---------------------------------
+
+ //-----------------------------constructors/finalizer-------------------------
+
+ // One NetLogWriter object is created per data source, iff tracing is enabled.
+ public NetLogWriter (java.io.PrintWriter printWriter, int traceLevel)
+ {
+ super (printWriter, traceLevel);
+
+ // Initialize the codepoint name table if not previously initialized.
+ // This is done lazily so that it is not created if the trace isn't used (save some init time).
+ if (codePointNameTable__ == null) {
+ codePointNameTable__ = new CodePointNameTable();
+ }
+ }
+
+ //------------------------------entry points----------------------------------
+
+ // Specialization of LogWriter.traceConnectsExit()
+ public void traceConnectsExit (org.apache.derby.client.am.Connection connection)
+ {
+ if (traceSuspended()) return;
+ NetConnection c = (NetConnection) connection;
+ synchronized (printWriter_) {
+ super.traceConnectsExit (c);
+ dncnetprint (" PROTOCOL manager levels: { ");
+ printWriter_.print ("SQLAM=" + c.getSQLAM() + ", ");
+ printWriter_.print ("AGENT=" + c.getAGENT() + ", ");
+ printWriter_.print ("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
+ printWriter_.print ("RDB=" + c.getRDB() + ", ");
+ printWriter_.print ("SECMGR=" + c.getSECMGR() + ", ");
+ printWriter_.print ("XAMGR=" + c.getXAMGR() + ", ");
+ printWriter_.print ("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
+ printWriter_.print ("RSYNCMGR=" + c.getRSYNCMGR());
+ printWriter_.println (" }");
+ printWriter_.flush();
+ }
+ }
+
+ public void traceConnectsResetExit (org.apache.derby.client.am.Connection connection)
+ {
+ if (traceSuspended()) return;
+ NetConnection c = (NetConnection) connection;
+ synchronized (printWriter_) {
+ super.traceConnectsResetExit (c);
+ dncnetprint (" PROTOCOL manager levels: { ");
+ printWriter_.print ("SQLAM=" + c.getSQLAM() + ", ");
+ printWriter_.print ("AGENT=" + c.getAGENT() + ", ");
+ printWriter_.print ("CMNTCPIP=" + c.getCMNTCPIP() + ", ");
+ printWriter_.print ("RDB=" + c.getRDB() + ", ");
+ printWriter_.print ("SECMGR=" + c.getSECMGR() + ", ");
+ printWriter_.print ("XAMGR=" + c.getXAMGR() + ", ");
+ printWriter_.print ("SYNCPTMGR=" + c.getSYNCPTMGR() + ", ");
+ printWriter_.print ("RSYNCMGR=" + c.getRSYNCMGR());
+ printWriter_.println (" }");
+ printWriter_.flush();
+ }
+ }
+
+ // Pass the connection handle and print it in the header
+ // What exactly is supposed to be passed, assume one complete DSS packet
+ // Write the communication buffer data to the trace.
+ // The data is passed in via a byte array. The start and length of the data is given.
+ // The type is needed to indicate if the data is part of the send or receive buffer.
+ // The class name, method name, and trcPt number are also written to the trace.
+ // Not much checking is performed on the parameters. This is done to help performance.
+ synchronized public void traceProtocolFlow (byte[] buff,
+ int offset,
+ int len,
+ int type,
+ String className,
+ String methodName,
+ int tracepoint)
+ {
+ if (traceSuspended()) return;
+ if (!loggingEnabled (org.apache.derby.jdbc.ClientDataSource.TRACE_PROTOCOL_FLOWS)) return;
+ synchronized (printWriter_) {
+ super.tracepoint ("[net]", tracepoint, className, methodName);
+
+ int fullLen = len;
+ boolean printColPos = true;
+ while( fullLen >= 2 )
+ { // format each DssHdr seperately
+ // get the length of this DssHdr
+ len = ((buff[offset] & 0xff) << 8) + ((buff[offset+1] & 0xff) << 0);
+
+ // check for valid dss header or not all of dss block
+ if ((len < 10) || (len > fullLen))
+ len = fullLen;
+
+ // subtract that length from the full length
+ fullLen -= len;
+ // The data will only be written if there is a non-zero positive length.
+ if (len != 0) {
+ String codePointName = null;
+ // If the length <= 10, lookup the first codepoint so it's name can be printed
+ if (len >= 10) {
+ // Get the int value of the two byte unsigned codepoint.
+ int codePoint = getCodePoint (buff, offset+8);
+ codePointName = codePointNameTable__.lookup (codePoint);
+
+ // if this is not a valid codepoint then format the entire buffer
+ // as one block.
+ if (codePointName == null)
+ {
+ len += fullLen;
+ fullLen = 0;
+ }
+ }
+
+ if( !printColPos )
+ { // not 1st Dss header of this buffer, write seperator
+ dncnetprintln( "" );
+ }
+
+ if (codePointName == null) {
+ // codePointName was still null so either < 10 bytes were given or
+ // the codepoint wasn't found in the table. Just print the plain send header.
+ dncnetprintln (getHeader (type));
+ }
+ else {
+ // codePointName isn't null so the name of the codepoint will be printed.
+ printHeaderWithCodePointName (codePointName, type);
+ }
+
+ // Print the col position header in the trace.
+ if( printColPos )
+ { // first Dss header of buffer, need column position header
+ dncnetprintln (colPosHeader__);
+ printColPos = false;
+ }
+
+ // A char array will be used to translate the bytes to their character
+ // representations along with ascii and ebcdic representations.
+ char trcDump[] = new char[77];
+
+ // bCounter, aCounter, eCounter are offsets used to help position the characters
+ short bCounter = 7;
+ short aCounter = 43;
+ short eCounter = 61;
+
+ // The lines will be counted starting at zero.
+ // This is hard coded since we are at the beginning.
+ trcDump[0] = zeroChar__;
+ trcDump[1] = zeroChar__;
+ trcDump[2] = zeroChar__;
+ trcDump[3] = zeroChar__;
+
+ // The 0's are already in the trace so bump the line counter up a row.
+ int lineCounter = 0x10;
+
+ // Make sure the character array has all blanks in it.
+ // Some of these blanks will be replaced later with values.
+ // The 0's were not wrote over.
+ for (int j = 4; j < 77; j++) {
+ trcDump[j] = spaceChar__;
+ }
+
+ // i will maintain the position in the byte array to be traced.
+ int i = 0;
+
+ do {
+ // Get the unsigned value of the byte.
+ // int num = b[off++] & 0xff;
+ int num = (buff[offset] < 0)? buff[offset] + 256 : buff[offset];
+ offset++;
+ i++;
+ // Place the characters representing the bytes in the array.
+ trcDump[bCounter++] = hexDigit__[((num >>> 4) & 0xf)];
+ trcDump[bCounter++] = hexDigit__[(num & 0xf)];
+
+ // Place the ascii and ebcdc representations in the array.
+ trcDump[aCounter++] = asciiChar__[num];
+ trcDump[eCounter++] = ebcdicChar__[num];
+
+ if (((i%8) == 0)) {
+ if (((i%16) == 0)) {
+ // Print the array each time 16 bytes are processed.
+ dncnetprintln (trcDump);
+ if (i != len) {
+ // Not yet at the end of the byte array.
+ if ((len - i) < 16) {
+ // This is the last line so blank it all out.
+ // This keeps the last line looking pretty in case
+ // < 16 bytes remain.
+ for (int j = 0; j < trcDump.length; j++) {
+ trcDump[j] = spaceChar__;
+ }
+ }
+ // Reset the counters.
+ bCounter = 0;
+ aCounter = 43;
+ eCounter = 61;
+ // Reset the lineCounter if it starts to get too large.
+ if (lineCounter == 0x100000) {
+ lineCounter = 0;
+ }
+ // Place the characters representing the line counter in the array.
+ trcDump[bCounter++] = hexDigit__[((lineCounter >>> 12) & 0xf)];
+ trcDump[bCounter++] = hexDigit__[((lineCounter >>> 8) & 0xf)];
+ trcDump[bCounter++] = hexDigit__[((lineCounter >>> 4) & 0xf)];
+ trcDump[bCounter++] = hexDigit__[(lineCounter & 0xf)];
+ bCounter += 3;
+ // Bump up the line counter.
+ lineCounter += 0x10;
+ }
+ }
+ else {
+ // 8 bytes were processed so move the counter to adjust for
+ // spaces between the columns of bytes.
+ bCounter += 2;
+ }
+ }
+ // do this until we all the data has been traced.
+ }
+ while (i < len);
+
+ // print the last line and add some blank lines to make it easier to read.
+ if (len % 16 != 0) {
+ dncnetprintln (trcDump);
+ }
+ }
+ }
+ dncnetprintln ("");
+ }
+ }
+
+ // Gets the int value of the two byte unsigned codepoint.
+ private static int getCodePoint (byte[] buff, int offset)
+ {
+ return ((buff[offset++] & 0xff) << 8) +
+ ((buff[offset] & 0xff) << 0);
+ }
+
+ private static String getHeader (int type)
+ {
+ switch (type) {
+ case TYPE_TRACE_SEND:
+ return sendHeader__;
+ case TYPE_TRACE_RECEIVE:
+ return receiveHeader__;
+ default:
+ return null;
+ }
+ }
+
+ private static int getStartPosition (int type)
+ {
+ switch (type) {
+ case TYPE_TRACE_SEND:
+ return 20; // This is right after 'SEND BUFFER: '.
+ case TYPE_TRACE_RECEIVE:
+ return 23; // This is right after 'RECEIVE BUFFER: '.
+ default:
+ return 0;
+ }
+ }
+
+ private void printHeaderWithCodePointName (String codePointName, int type)
+ {
+ // Create a char array so some of the characters
+ // can be replaced with the name of the codepoint.
+ char headerArray[] = getHeader(type).toCharArray();
+
+ // At most, 16 character name will be used. This is so
+ // the headers on top of the ascii and ebcdic rows aren't shifted.
+ int replaceLen = (codePointName.length() < 17) ? codePointName.length() : 16;
+
+ int offset = getStartPosition (type);
+ for (int i = 0; i < replaceLen; i++) {
+ headerArray[offset++] = codePointName.charAt (i);
+ }
+ dncnetprintln (headerArray);
+ }
+
+ private void dncnetprint (String s)
+ {
+ synchronized (printWriter_) {
+ printWriter_.print ("[derby] " + s);
+ printWriter_.flush();
+ }
+ }
+
+ private void dncnetprintln (String s)
+ {
+ synchronized (printWriter_) {
+ printWriter_.println ("[derby] " + s);
+ printWriter_.flush();
+ }
+ }
+
+ private void dncnetprintln (char[] s)
+ {
+ synchronized (printWriter_) {
+ printWriter_.print ("[derby] ");
+ printWriter_.println (s);
+ printWriter_.flush();
+ }
+ }
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/net/NetLogWriter.java
------------------------------------------------------------------------------
svn:eol-style = native