001: /*
002:
003: Derby - Class org.apache.derby.client.net.NetResultSetReply
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.client.net;
023:
024: import org.apache.derby.client.am.DisconnectException;
025: import org.apache.derby.client.am.ResultSet;
026: import org.apache.derby.client.am.ResultSetCallbackInterface;
027: import org.apache.derby.client.am.SqlException;
028: import org.apache.derby.client.am.ClientMessageId;
029:
030: import org.apache.derby.shared.common.reference.SQLState;
031: import org.apache.derby.shared.common.reference.MessageId;
032:
033: public class NetResultSetReply extends NetStatementReply implements
034: ResultSetReplyInterface {
035: public NetResultSetReply(NetAgent netAgent, int bufferSize) {
036: super (netAgent, bufferSize);
037: }
038:
039: //----------------------------- entry points ---------------------------------
040:
041: public void readFetch(ResultSetCallbackInterface resultSet)
042: throws DisconnectException {
043: startSameIdChainParse();
044: parseCNTQRYreply(resultSet, true); // true means we expect row data
045: endOfSameIdChainData();
046: }
047:
048: public void readPositioningFetch(
049: ResultSetCallbackInterface resultSet)
050: throws DisconnectException {
051: startSameIdChainParse();
052: parseCNTQRYreply(resultSet, false); // false means return data is not expected
053: endOfSameIdChainData();
054: }
055:
056: public void readScrollableFetch(ResultSetCallbackInterface resultSet)
057: throws DisconnectException {
058: startSameIdChainParse();
059: parseCNTQRYreply(resultSet, true); // true means return data is expected
060: endOfSameIdChainData();
061: }
062:
063: public void readCursorClose(ResultSetCallbackInterface resultSet)
064: throws DisconnectException {
065: startSameIdChainParse();
066: parseCLSQRYreply(resultSet);
067: endOfSameIdChainData();
068: }
069:
070: //----------------------helper methods----------------------------------------
071:
072: //------------------parse reply for specific command--------------------------
073:
074: // These methods are "private protected", which is not a recognized java privilege,
075: // but means that these methods are private to this class and to subclasses,
076: // and should not be used as package-wide friendly methods.
077:
078: // Parse the reply for the Close Query Command.
079: // This method handles the parsing of all command replies and reply data
080: // for the clsqry command.
081: private void parseCLSQRYreply(ResultSetCallbackInterface resultSet)
082: throws DisconnectException {
083: int peekCP = parseTypdefsOrMgrlvlovrs();
084:
085: if (peekCP == CodePoint.SQLCARD) {
086: NetSqlca netSqlca = parseSQLCARD(null); //@f48553sxg - null means rowsetSqlca_ is null
087: // Set the cursor state if null SQLCA or sqlcode is equal to 0.
088: resultSet.completeSqlca(netSqlca);
089: } else {
090: parseCloseError(resultSet);
091: }
092: }
093:
094: // Parse the reply for the Continue Query Command.
095: // This method handles the parsing of all command replies and reply data for the cntqry command.
096: // If doCopyQrydta==false, then there is no data, and we're only parsing out the sqlca to get the row count.
097: private void parseCNTQRYreply(
098: ResultSetCallbackInterface resultSetI, boolean doCopyQrydta)
099: throws DisconnectException {
100: boolean found = false;
101: int peekCP = peekCodePoint();
102: if (peekCP == CodePoint.RDBUPDRM) {
103: found = true;
104: parseRDBUPDRM();
105: peekCP = peekCodePoint();
106: }
107:
108: if (peekCP == CodePoint.QRYDTA) {
109: found = true;
110: if (!doCopyQrydta) {
111: parseLengthAndMatchCodePoint(CodePoint.QRYDTA);
112: //we don't need to copy QRYDTA since there is no data
113: if (longValueForDecryption_ != null) {
114: longValueForDecryption_ = null;
115: }
116: if (longBufferForDecryption_ != null) {
117: longBufferForDecryption_ = null;
118: }
119:
120: int ddmLength = getDdmLength();
121: ensureBLayerDataInBuffer(ddmLength);
122: ((ResultSet) resultSetI).expandRowsetSqlca();
123: NetSqlca sqlca = parseSQLCARDrow(((ResultSet) resultSetI).rowsetSqlca_);
124: int daNullIndicator = readFastByte();
125: adjustLengths(getDdmLength());
126: // define event interface and use the event method
127: // only get the rowCount_ if sqlca is not null and rowCount_ is unknown
128: if (sqlca != null && sqlca.containsSqlcax()) {
129: ((ResultSet) resultSetI).setRowCountEvent(sqlca
130: .getRowCount(netAgent_.targetTypdef_));
131: }
132:
133: peekCP = peekCodePoint();
134: if (peekCP == CodePoint.RDBUPDRM) {
135: parseRDBUPDRM();
136: peekCP = peekCodePoint();
137: }
138: return;
139: }
140: do {
141: parseQRYDTA((NetResultSet) resultSetI);
142: peekCP = peekCodePoint();
143: } while (peekCP == CodePoint.QRYDTA);
144: }
145:
146: if (peekCP == CodePoint.EXTDTA) {
147: found = true;
148: do {
149: copyEXTDTA((NetCursor) ((ResultSet) resultSetI).cursor_);
150: if (longBufferForDecryption_ != null) {//encrypted EXTDTA
151: buffer_ = longBufferForDecryption_;
152: pos_ = longPosForDecryption_;
153: if (longBufferForDecryption_ != null
154: && count_ > longBufferForDecryption_.length) {
155: count_ = longBufferForDecryption_.length;
156: }
157: }
158:
159: peekCP = peekCodePoint();
160: } while (peekCP == CodePoint.EXTDTA);
161: }
162:
163: if (peekCP == CodePoint.SQLCARD) {
164: found = true;
165: ((ResultSet) resultSetI).expandRowsetSqlca();
166: NetSqlca netSqlca = parseSQLCARD(((ResultSet) resultSetI).rowsetSqlca_);
167: // for an atomic operation, the SQLCA contains the sqlcode for the first (statement
168: // terminating)error, the last warning, or zero. all multi-row fetch operatons are
169: // atomic. (the only operation that is not atomic is multi-row insert).
170: if (((ResultSet) resultSetI).sensitivity_ != ResultSet.sensitivity_sensitive_dynamic__) {
171: if (netSqlca != null && netSqlca.containsSqlcax()
172: && netSqlca.getRowsetRowCount() == 0) {
173: ((ResultSet) resultSetI).setRowCountEvent(netSqlca
174: .getRowCount(netAgent_.targetTypdef_));
175: }
176: }
177: resultSetI.completeSqlca(netSqlca);
178: peekCP = peekCodePoint();
179: }
180:
181: if (peekCP == CodePoint.ENDQRYRM) {
182: found = true;
183: parseEndQuery(resultSetI);
184: peekCP = peekCodePoint();
185: }
186:
187: if (peekCP == CodePoint.RDBUPDRM) {
188: found = true;
189: parseRDBUPDRM();
190: }
191:
192: if (!found) {
193: parseFetchError(resultSetI);
194: }
195:
196: if (longBufferForDecryption_ != null) {
197: // Not a good idea to create a new buffer_
198: buffer_ = new byte[DEFAULT_BUFFER_SIZE];
199: longBufferForDecryption_ = null;
200: }
201: }
202:
203: void parseCloseError(ResultSetCallbackInterface resultSetI)
204: throws DisconnectException {
205: int peekCP = peekCodePoint();
206: switch (peekCP) {
207: case CodePoint.ABNUOWRM: {
208: //passing the ResultSetCallbackInterface implementation will
209: //help in retrieving the the UnitOfWorkListener that needs to
210: //be rolled back
211: NetSqlca sqlca = parseAbnormalEndUow(resultSetI);
212: resultSetI.completeSqlca(sqlca);
213: break;
214: }
215: case CodePoint.CMDCHKRM:
216: parseCMDCHKRM();
217: break;
218: case CodePoint.QRYNOPRM:
219: parseQRYNOPRM(resultSetI);
220: break;
221: case CodePoint.RDBNACRM:
222: parseRDBNACRM();
223: break;
224: default:
225: parseCommonError(peekCP);
226: }
227: }
228:
229: void parseFetchError(ResultSetCallbackInterface resultSetI)
230: throws DisconnectException {
231: int peekCP = peekCodePoint();
232: switch (peekCP) {
233: case CodePoint.ABNUOWRM: {
234: //passing the ResultSetCallbackInterface implementation will
235: //help in retrieving the the UnitOfWorkListener that needs to
236: //be rolled back
237: NetSqlca sqlca = parseAbnormalEndUow(resultSetI);
238: resultSetI.completeSqlca(sqlca);
239: break;
240: }
241: case CodePoint.CMDCHKRM:
242: parseCMDCHKRM();
243: break;
244: case CodePoint.CMDNSPRM:
245: parseCMDNSPRM();
246: break;
247: case CodePoint.QRYNOPRM:
248: parseQRYNOPRM(resultSetI);
249: break;
250: case CodePoint.RDBNACRM:
251: parseRDBNACRM();
252: break;
253: default:
254: parseCommonError(peekCP);
255: }
256: }
257:
258: //-----------------------------parse DDM Reply Messages-----------------------
259:
260: // Query Not Opened Reply Message is issued if a CNTQRY or CLSQRY
261: // command is issued for a query that is not open. A previous
262: // ENDQRYRM, ENDUOWRM, or ABNUOWRM reply message might have
263: // terminated the command.
264: // PROTOCOL architects the SQLSTATE value depending on SVRCOD
265: // SVRCOD 4 -> SQLSTATE is 24501
266: // SVRCOD 8 -> SQLSTATE of 58008 or 58009
267: //
268: // if SVRCOD is 4 then SQLSTATE 24501, SQLCODE -501
269: // else SQLSTATE 58009, SQLCODE -30020
270: //
271: // Messages
272: // SQLSTATE : 24501
273: // The identified cursor is not open.
274: // SQLCODE : -501
275: // The cursor specified in a FETCH or CLOSE statement is not open.
276: // The statement cannot be processed.
277: // SQLSTATE : 58009
278: // Execution failed due to a distribution protocol error that caused deallocation of the conversation.
279: // SQLCODE : -30020
280: // Execution failed because of a Distributed Protocol
281: // Error that will affect the successful execution of subsequent
282: // commands and SQL statements: Reason Code <reason-code>.
283: // Some possible reason codes include:
284: // 121C Indicates that the user is not authorized to perform the requested command.
285: // 1232 The command could not be completed because of a permanent error.
286: // In most cases, the server will be in the process of an abend.
287: // 220A The target server has received an invalid data description.
288: // If a user SQLDA is specified, ensure that the fields are
289: // initialized correctly. Also, ensure that the length does not exceed
290: // the maximum allowed length for the data type being used.
291: //
292: // The command or statement cannot be processed. The current
293: // transaction is rolled back and the application is disconnected
294: // from the remote database.
295: //
296: // Returned from Server:
297: // SVRCOD - required (4 - WARNING, 8 - ERROR)
298: // RDBNAM - required
299: // PKGNAMCSN - required
300: //
301: private void parseQRYNOPRM(ResultSetCallbackInterface resultSet)
302: throws DisconnectException {
303: boolean svrcodReceived = false;
304: int svrcod = CodePoint.SVRCOD_INFO;
305: boolean rdbnamReceived = false;
306: String rdbnam = null;
307: boolean pkgnamcsnReceived = false;
308: Object pkgnamcsn = null;
309:
310: parseLengthAndMatchCodePoint(CodePoint.QRYNOPRM);
311: pushLengthOnCollectionStack();
312: int peekCP = peekCodePoint();
313:
314: while (peekCP != Reply.END_OF_COLLECTION) {
315:
316: boolean foundInPass = false;
317:
318: if (peekCP == CodePoint.SVRCOD) {
319: foundInPass = true;
320: svrcodReceived = checkAndGetReceivedFlag(svrcodReceived);
321: svrcod = parseSVRCOD(CodePoint.SVRCOD_WARNING,
322: CodePoint.SVRCOD_ERROR);
323: peekCP = peekCodePoint();
324: }
325:
326: if (peekCP == CodePoint.RDBNAM) {
327: foundInPass = true;
328: rdbnamReceived = checkAndGetReceivedFlag(rdbnamReceived);
329: rdbnam = parseRDBNAM(true);
330: peekCP = peekCodePoint();
331: }
332:
333: if (peekCP == CodePoint.PKGNAMCSN) {
334: foundInPass = true;
335: pkgnamcsnReceived = checkAndGetReceivedFlag(pkgnamcsnReceived);
336: pkgnamcsn = parsePKGNAMCSN(true);
337: peekCP = peekCodePoint();
338: }
339:
340: if (!foundInPass) {
341: doPrmnsprmSemantics(peekCP);
342: }
343:
344: }
345: popCollectionStack();
346: checkRequiredObjects(svrcodReceived, rdbnamReceived,
347: pkgnamcsnReceived);
348:
349: // move into a method
350: netAgent_.setSvrcod(svrcod);
351: if (svrcod == CodePoint.SVRCOD_WARNING) {
352: netAgent_.accumulateReadException(new SqlException(
353: netAgent_.logWriter_, new ClientMessageId(
354: SQLState.DRDA_CURSOR_NOT_OPEN)));
355: } else {
356: agent_
357: .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
358: agent_,
359: new ClientMessageId(
360: SQLState.DRDA_CONNECTION_TERMINATED),
361: SqlException
362: .getMessageUtil()
363: .getTextMessage(
364: MessageId.CONN_CURSOR_NOT_OPEN)));
365: }
366: }
367: }
|