📄 drdaconnthread.java
字号:
* @param dbname database name * @param drdaID DRDA identifier * @param msg message */ protected static void println2Log(String dbname, String drdaID, String msg) { if (logStream == null) logStream = Monitor.getStream(); if (dbname != null) { int endOfName = dbname.indexOf(';'); if (endOfName != -1) dbname = dbname.substring(0, endOfName); } logStream.printlnWithHeader("(DATABASE = " + dbname + "), (DRDAID = " + drdaID + "), " + msg); } /** * Write RDBNAM * * @param rdbnam database name * @exception DRDAProtocolException */ protected void writeRDBNAM(String rdbnam) throws DRDAProtocolException { int len = rdbnam.length(); if (len < CodePoint.RDBNAM_LEN) len = CodePoint.RDBNAM_LEN; writer.writeScalarHeader(CodePoint.RDBNAM, len); try { writer.writeScalarPaddedBytes(rdbnam.getBytes(server.DEFAULT_ENCODING), len, server.SPACE_CHAR); } catch (UnsupportedEncodingException e) { agentError("Unsupported coding exception for server encoding " + server.DEFAULT_ENCODING); } } /*************************************************************************** * Private methods ***************************************************************************/ /** * Initialize class */ private void initialize() { // set input and output sockets // this needs to be done before creating reader sockis = session.sessionInput; sockos = session.sessionOutput; reader = new DDMReader(this, session.dssTrace); writer = new DDMWriter(ccsidManager, this, session.dssTrace); } /** * Initialize for a new session */ private void initializeForSession() { // set input and output sockets sockis = session.sessionInput; sockos = session.sessionOutput; // intialize reader and writer reader.initialize(this, session.dssTrace); writer.reset(session.dssTrace); // initialize local pointers to session info database = session.database; appRequester = session.appRequester; // set sqlamLevel if (session.state == Session.ATTEXC) sqlamLevel = appRequester.getManagerLevel(CodePoint.SQLAM); } /** * In initial state for a session, * determine whether this is a command * session or a DRDA protocol session. A command session is for changing * the configuration of the Net server, e.g., turning tracing on * If it is a command session, process the command and close the session. * If it is a DRDA session, exchange server attributes and change session * state. */ private void sessionInitialState() throws Exception { // process NetworkServerControl commands - if it is not either valid protocol let the // DRDA error handling handle it if (reader.isCmd()) { try { server.processCommands(reader, writer, session); // reset reader and writer reader.initialize(this, null); writer.reset(null); closeSession(); } catch (Throwable t) { if (t instanceof InterruptedException) throw (InterruptedException)t; else { server.consoleExceptionPrintTrace(t); } } } else { // exchange attributes with application requester exchangeServerAttributes(); } } /** * Process DRDA commands we can receive once server attributes have been * exchanged. * * @exception DRDAProtocolException */ private void processCommands() throws DRDAProtocolException { DRDAStatement stmt = null; int updateCount = 0; boolean PRPSQLSTTfailed = false; boolean checkSecurityCodepoint = session.requiresSecurityCodepoint(); do { correlationID = reader.readDssHeader(); int codePoint = reader.readLengthAndCodePoint(); int writerMark = writer.markDSSClearPoint(); if (checkSecurityCodepoint) verifyInOrderACCSEC_SECCHK(codePoint,session.getRequiredSecurityCodepoint()); switch(codePoint) { case CodePoint.CNTQRY: try{ stmt = parseCNTQRY(); if (stmt != null) { writeQRYDTA(stmt); if (stmt.rsIsClosed()) { writeENDQRYRM(CodePoint.SVRCOD_WARNING); writeNullSQLCARDobject(); } // Send any warnings if JCC can handle them checkWarning(null, null, stmt.getResultSet(), 0, false, sendWarningsOnCNTQRY); } } catch(SQLException e) { if (stmt != null) { // if we got a SQLException we need to clean up and // close the statement Beetle 4758 writer.clearDSSesBackToMark(writerMark); if (! stmt.rsIsClosed()) { try { stmt.rsClose(); } catch (SQLException ec) { if (SanityManager.DEBUG) trace("Warning: Error closing statement"); } writeABNUOWRM(); writeSQLCARD(e,CodePoint.SVRCOD_ERROR,0,0); } } else { writeSQLCARDs(e, 0); } errorInChain(e); } break; case CodePoint.EXCSQLIMM: try { updateCount = parseEXCSQLIMM(); // RESOLVE: checking updateCount is not sufficient // since it will be 0 for creates, we need to know when // any logged changes are made to the database // Not getting this right for JCC is probably O.K., this // will probably be a problem for ODBC and XA // The problem is that JDBC doesn't provide this information // so we would have to expand the JDBC API or call a // builtin method to check(expensive) // For now we will assume that every execute immediate // does an update (that is the most conservative thing) if (database.RDBUPDRM_sent == false) { writeRDBUPDRM(); } // we need to set update count in SQLCARD checkWarning(null, database.getDefaultStatement().getStatement(), null, updateCount, true, true); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.EXCSQLSET: try { if (parseEXCSQLSET()) // all went well. writeSQLCARDs(null,0); } catch (SQLWarning w) { writeSQLCARD(w, CodePoint.SVRCOD_WARNING, 0, 0); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.PRPSQLSTT: int sqldaType; PRPSQLSTTfailed = false; try { database.getConnection().clearWarnings(); sqldaType = parsePRPSQLSTT(); if (sqldaType > 0) // do write SQLDARD writeSQLDARD(database.getCurrentStatement(), (sqldaType == CodePoint.TYPSQLDA_LIGHT_OUTPUT), database.getConnection().getWarnings()); else checkWarning(database.getConnection(), null, null, 0, true, true); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); writeSQLCARDs(e, 0, true); PRPSQLSTTfailed = true; errorInChain(e); } break; case CodePoint.OPNQRY: PreparedStatement ps = null; try { if (PRPSQLSTTfailed) { // read the command objects // for ps with parameter // Skip objects/parameters skipRemainder(true); // If we failed to prepare, then we fail // to open, which means OPNQFLRM. writeOPNQFLRM(null); break; } Pkgnamcsn pkgnamcsn = parseOPNQRY(); if (pkgnamcsn != null) { stmt = database.getDRDAStatement(pkgnamcsn); ps = stmt.getPreparedStatement(); ps.clearWarnings(); stmt.execute(); writeOPNQRYRM(false, stmt); checkWarning(null, ps, null, 0, false, true); writeQRYDSC(stmt, false); // We could send QRYDTA here if there's no LOB data // in the result set, and if we are using LMTBLKPRC, as // allowed by drda spec, as an option. stmt.rsSuspend(); } } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); try { // Try to cleanup if we hit an error. if (ps != null) ps.close(); writeOPNQFLRM(e); } catch (SQLException pse) {} errorInChain(e); } break; case CodePoint.RDBCMM: try { if (SanityManager.DEBUG) trace("Received commit"); if (!database.getConnection().getAutoCommit()) { database.getConnection().clearWarnings(); database.commit(); writeENDUOWRM(COMMIT); checkWarning(database.getConnection(), null, null, 0, true, true); } // we only want to write one of these per transaction // so set to false in preparation for next command database.RDBUPDRM_sent = false; } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); // Even in case of error, we have to write the ENDUOWRM. writeENDUOWRM(COMMIT); writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.RDBRLLBCK: try { if (SanityManager.DEBUG) trace("Received rollback"); database.getConnection().clearWarnings(); database.rollback(); writeENDUOWRM(ROLLBACK); checkWarning(database.getConnection(), null, null, 0, true, true); // we only want to write one of these per transaction // so set to false in preparation for next command database.RDBUPDRM_sent = false; } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); // Even in case of error, we have to write the ENDUOWRM. writeENDUOWRM(ROLLBACK); writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.CLSQRY: try{ stmt = parseCLSQRY(); stmt.rsClose(); writeSQLCARDs(null, 0); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.EXCSAT: parseEXCSAT(); writeEXCSATRD(); break; case CodePoint.ACCSEC: int securityCheckCode = parseACCSEC(); writeACCSECRD(securityCheckCode); checkSecurityCodepoint = true; break; case CodePoint.SECCHK: if(parseDRDAConnection()) // security all checked and connection ok checkSecurityCodepoint = false; break; /* since we don't support sqlj, we won't get bind commands from jcc, we * might get it from ccc; just skip them. */ case CodePoint.BGNBND: reader.skipBytes(); writeSQLCARDs(null, 0); break; case CodePoint.BNDSQLSTT: reader.skipBytes(); parseSQLSTTDss(); writeSQLCARDs(null, 0); break; case CodePoint.SQLSTTVRB: // optional reader.skipBytes(); break; case CodePoint.ENDBND: reader.skipBytes(); writeSQLCARDs(null, 0); break; case CodePoint.DSCSQLSTT: if (PRPSQLSTTfailed) { reader.skipBytes(); writeSQLCARDs(null, 0); break; } try { boolean rtnOutput = parseDSCSQLSTT(); writeSQLDARD(database.getCurrentStatement(), rtnOutput, null); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); server.consoleExceptionPrint(e); try { writeSQLDARD(database.getCurrentStatement(), true, e); } catch (SQLException e2) { // should not get here since doing nothing with ps agentError("Why am I getting another SQLException?"); } errorInChain(e); } break; case CodePoint.EXCSQLSTT: if (PRPSQLSTTfailed) { // Skip parameters too if they are chained Beetle 4867 skipRemainder(true); writeSQLCARDs(null, 0); break; } try { parseEXCSQLSTT(); DRDAStatement curStmt = database.getCurrentStatement(); if (curStmt != null) curStmt.rsSuspend(); } catch (SQLException e) { writer.clearDSSesBackToMark(writerMark); if (SanityManager.DEBUG) { server.consoleExceptionPrint(e); } writeSQLCARDs(e, 0); errorInChain(e); } break; case CodePoint.SYNCCTL: if (xaProto == null) xaProto = new DRDAXAProtocol(this); xaProto.parseSYNCCTL(); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -