📄 tdscore.java
字号:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase// Copyright (C) 2004 The jTDS Project//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//package net.sourceforge.jtds.jdbc;import java.io.*;import java.sql.*;import java.util.Arrays;import java.util.ArrayList;import java.util.HashMap;import net.sourceforge.jtds.ssl.*;import net.sourceforge.jtds.util.*;/** * This class implements the Sybase / Microsoft TDS protocol. * <p> * Implementation notes: * <ol> * <li>This class, together with TdsData, encapsulates all of the TDS specific logic * required by the driver. * <li>This is a ground up reimplementation of the TDS protocol and is rather * simpler, and hopefully easier to understand, than the original. * <li>The layout of the various Login packets is derived from the original code * and freeTds work, and incorporates changes including the ability to login as a TDS 5.0 user. * <li>All network I/O errors are trapped here, reported to the log (if active) * and the parent Connection object is notified that the connection should be considered * closed. * <li>Rather than having a large number of classes one for each token, useful information * about the current token is gathered together in the inner TdsToken class. * <li>As the rest of the driver interfaces to this code via higher-level method calls there * should be know need for knowledge of the TDS protocol to leak out of this class. * It is for this reason that all the TDS Token constants are private. * </ol> * * @author Mike Hutchinson * @author Matt Brinkley * @author Alin Sinpalean * @author FreeTDS project * @version $Id: TdsCore.java,v 1.97 2005/06/15 14:56:58 alin_sinpalean Exp $ */public class TdsCore { /** * Inner static class used to hold information about TDS tokens read. */ private static class TdsToken { /** The current TDS token byte. */ byte token; /** The status field from a DONE packet. */ byte status; /** The operation field from a DONE packet. */ byte operation; /** The update count from a DONE packet. */ int updateCount; /** The nonce from an NTLM challenge packet. */ byte[] nonce; /** NTLM authentication message. */ byte[] ntlmMessage; /** The dynamic parameters from the last TDS_DYNAMIC token. */ ColInfo[] dynamParamInfo; /** The dynamic parameter data from the last TDS_DYNAMIC token. */ Object[] dynamParamData; /** * Retrieve the update count status. * * @return <code>boolean</code> true if the update count is valid. */ boolean isUpdateCount() { return (token == TDS_DONE_TOKEN || token == TDS_DONEINPROC_TOKEN) && (status & DONE_ROW_COUNT) != 0; } /** * Retrieve the DONE token status. * * @return <code>boolean</code> true if the current token is a DONE packet. */ boolean isEndToken() { return token == TDS_DONE_TOKEN || token == TDS_DONEINPROC_TOKEN || token == TDS_DONEPROC_TOKEN; } /** * Retrieve the NTLM challenge status. * * @return <code>boolean</code> true if the current token is an NTLM challenge. */ boolean isAuthToken() { return token == TDS_AUTH_TOKEN; } /** * Retrieve the results pending status. * * @return <code>boolean</code> true if more results in input. */ boolean resultsPending() { return !isEndToken() || ((status & DONE_MORE_RESULTS) != 0); } /** * Retrieve the result set status. * * @return <code>boolean</code> true if the current token is a result set. */ boolean isResultSet() { return token == TDS_COLFMT_TOKEN || token == TDS7_RESULT_TOKEN || token == TDS_RESULT_TOKEN || token == TDS5_WIDE_RESULT || token == TDS_COLINFO_TOKEN || token == TDS_ROW_TOKEN; } /** * Retrieve the row data status. * * @return <code>boolean</code> true if the current token is a result row. */ public boolean isRowData() { return token == TDS_ROW_TOKEN; } } /** * Inner static class used to hold table meta data. */ private static class TableMetaData { /** Table catalog (database) name. */ String catalog; /** Table schema (user) name. */ String schema; /** Table name. */ String name; } // // Package private constants // /** Minimum network packet size. */ public static final int MIN_PKT_SIZE = 512; /** Default minimum network packet size for TDS 7.0 and newer. */ public static final int DEFAULT_MIN_PKT_SIZE_TDS70 = 4096; /** Maximum network packet size. */ public static final int MAX_PKT_SIZE = 32768; /** The size of the packet header. */ public static final int PKT_HDR_LEN = 8; /** TDS 4.2 or 7.0 Query packet. */ public static final byte QUERY_PKT = 1; /** TDS 4.2 or 5.0 Login packet. */ public static final byte LOGIN_PKT = 2; /** TDS Remote Procedure Call. */ public static final byte RPC_PKT = 3; /** TDS Reply packet. */ public static final byte REPLY_PKT = 4; /** TDS Cancel packet. */ public static final byte CANCEL_PKT = 6; /** TDS MSDTC packet. */ public static final byte MSDTC_PKT = 14; /** TDS 5.0 Query packet. */ public static final byte SYBQUERY_PKT = 15; /** TDS 7.0 Login packet. */ public static final byte MSLOGIN_PKT = 16; /** TDS 7.0 NTLM Authentication packet. */ public static final byte NTLMAUTH_PKT = 17; /** SQL 2000 prelogin negotiation packet. */ public static final byte PRELOGIN_PKT = 18; /** SSL Mode - Login packet must be encrypted. */ public static final int SSL_ENCRYPT_LOGIN = 0; /** SSL Mode - Client requested force encryption. */ public static final int SSL_CLIENT_FORCE_ENCRYPT = 1; /** SSL Mode - No server certificate installed. */ public static final int SSL_NO_ENCRYPT = 2; /** SSL Mode - Server requested force encryption. */ public static final int SSL_SERVER_FORCE_ENCRYPT = 3; // // Sub packet types // /** TDS 5.0 Parameter format token. */ private static final byte TDS5_PARAMFMT2_TOKEN = (byte) 32; // 0x20 /** TDS 5.0 Language token. */ private static final byte TDS_LANG_TOKEN = (byte) 33; // 0x21 /** TSD 5.0 Wide result set token. */ private static final byte TDS5_WIDE_RESULT = (byte) 97; // 0x61 /** TDS 5.0 Close token. */ private static final byte TDS_CLOSE_TOKEN = (byte) 113; // 0x71 /** TDS DBLIB Offsets token. */ private static final byte TDS_OFFSETS_TOKEN = (byte) 120; // 0x78 /** TDS Procedure call return status token. */ private static final byte TDS_RETURNSTATUS_TOKEN= (byte) 121; // 0x79 /** TDS Procedure ID token. */ private static final byte TDS_PROCID = (byte) 124; // 0x7C /** TDS 7.0 Result set column meta data token. */ private static final byte TDS7_RESULT_TOKEN = (byte) 129; // 0x81 /** TDS 7.0 Computed Result set column meta data token. */ private static final byte TDS7_COMP_RESULT_TOKEN= (byte) 136; // 0x88 /** TDS 4.2 Column names token. */ private static final byte TDS_COLNAME_TOKEN = (byte) 160; // 0xA0 /** TDS 4.2 Column meta data token. */ private static final byte TDS_COLFMT_TOKEN = (byte) 161; // 0xA1 /** TDS Table name token. */ private static final byte TDS_TABNAME_TOKEN = (byte) 164; // 0xA4 /** TDS Cursor results column infomation token. */ private static final byte TDS_COLINFO_TOKEN = (byte) 165; // 0xA5 /** TDS Optional command token. */ private static final byte TDS_OPTIONCMD_TOKEN = (byte) 166; // 0xA6 /** TDS Computed result set names token. */ private static final byte TDS_COMP_NAMES_TOKEN = (byte) 167; // 0xA7 /** TDS Computed result set token. */ private static final byte TDS_COMP_RESULT_TOKEN = (byte) 168; // 0xA8 /** TDS Order by columns token. */ private static final byte TDS_ORDER_TOKEN = (byte) 169; // 0xA9 /** TDS error result token. */ private static final byte TDS_ERROR_TOKEN = (byte) 170; // 0xAA /** TDS Information message token. */ private static final byte TDS_INFO_TOKEN = (byte) 171; // 0xAB /** TDS Output parameter value token. */ private static final byte TDS_PARAM_TOKEN = (byte) 172; // 0xAC /** TDS Login acknowledgement token. */ private static final byte TDS_LOGINACK_TOKEN = (byte) 173; // 0xAD /** TDS control token. */ private static final byte TDS_CONTROL_TOKEN = (byte) 174; // 0xAE /** TDS Result set data row token. */ private static final byte TDS_ROW_TOKEN = (byte) 209; // 0xD1 /** TDS Computed result set data row token. */ private static final byte TDS_ALTROW = (byte) 211; // 0xD3 /** TDS 5.0 parameter value token. */ private static final byte TDS5_PARAMS_TOKEN = (byte) 215; // 0xD7 /** TDS 5.0 capabilities token. */ private static final byte TDS_CAP_TOKEN = (byte) 226; // 0xE2 /** TDS environment change token. */ private static final byte TDS_ENVCHANGE_TOKEN = (byte) 227; // 0xE3 /** TDS 5.0 message token. */ private static final byte TDS_MSG50_TOKEN = (byte) 229; // 0xE5 /** TDS 5.0 RPC token. */ private static final byte TDS_DBRPC_TOKEN = (byte) 230; // 0xE6 /** TDS 5.0 Dynamic SQL token. */ private static final byte TDS5_DYNAMIC_TOKEN = (byte) 231; // 0xE7 /** TDS 5.0 parameter descriptor token. */ private static final byte TDS5_PARAMFMT_TOKEN = (byte) 236; // 0xEC /** TDS 7.0 NTLM authentication challenge token. */ private static final byte TDS_AUTH_TOKEN = (byte) 237; // 0xED /** TDS 5.0 Result set column meta data token. */ private static final byte TDS_RESULT_TOKEN = (byte) 238; // 0xEE /** TDS done token. */ private static final byte TDS_DONE_TOKEN = (byte) 253; // 0xFD DONE /** TDS done procedure token. */ private static final byte TDS_DONEPROC_TOKEN = (byte) 254; // 0xFE DONEPROC /** TDS done in procedure token. */ private static final byte TDS_DONEINPROC_TOKEN = (byte) 255; // 0xFF DONEINPROC // // Environment change payload codes // /** Environment change: database changed. */ private static final byte TDS_ENV_DATABASE = (byte) 1; /** Environment change: language changed. */ private static final byte TDS_ENV_LANG = (byte) 2; /** Environment change: charset changed. */ private static final byte TDS_ENV_CHARSET = (byte) 3; /** Environment change: network packet size changed. */ private static final byte TDS_ENV_PACKSIZE = (byte) 4; /** Environment change: locale changed. */ private static final byte TDS_ENV_LCID = (byte) 5; /** Environment change: TDS 8 collation changed. */ private static final byte TDS_ENV_SQLCOLLATION = (byte) 7; // TDS8 Collation // // Static variables used only for performance // /** Used to optimize the {@link #getParameters()} call */ private static final ParamInfo[] EMPTY_PARAMETER_INFO = new ParamInfo[0]; // // End token status bytes // /** Done: more results are expected. */ private static final byte DONE_MORE_RESULTS = (byte) 0x01; /** Done: command caused an error. */ private static final byte DONE_ERROR = (byte) 0x02; /** Done: There is a valid row count. */ private static final byte DONE_ROW_COUNT = (byte) 0x10; /** Done: Cancel acknowledgement. */ static final byte DONE_CANCEL = (byte) 0x20; /** * Done: Response terminator (if more than one request packet is sent, each * response is terminated by a DONE packet with this flag set). */ private static final byte DONE_END_OF_RESPONSE = (byte) 0x80; // // Prepared SQL types // /** Do not prepare SQL */ public static final int UNPREPARED = 0; /** Prepare SQL using temporary stored procedures */ public static final int TEMPORARY_STORED_PROCEDURES = 1; /** Prepare SQL using sp_executesql */ public static final int EXECUTE_SQL = 2; /** Prepare SQL using sp_prepare and sp_execute */ public static final int PREPARE = 3; // // Sybase capability flags // /** Sybase char and binary > 255.*/ static final int SYB_LONGDATA = 1; /** Sybase date and time data types.*/ static final int SYB_DATETIME = 2; /** Sybase nullable bit type.*/ static final int SYB_BITNULL = 4; /** Sybase extended column meta data.*/ static final int SYB_EXTCOLINFO = 8; /** Sybase univarchar etc. */ static final int SYB_UNICODE = 16; /** Map of system stored procedures that have shortcuts in TDS8. */ private static HashMap tds8SpNames = new HashMap(); static { tds8SpNames.put("sp_cursor", new Integer(1)); tds8SpNames.put("sp_cursoropen", new Integer(2)); tds8SpNames.put("sp_cursorprepare", new Integer(3)); tds8SpNames.put("sp_cursorexecute", new Integer(4)); tds8SpNames.put("sp_cursorprepexec", new Integer(5)); tds8SpNames.put("sp_cursorunprepare", new Integer(6)); tds8SpNames.put("sp_cursorfetch", new Integer(7)); tds8SpNames.put("sp_cursoroption", new Integer(8)); tds8SpNames.put("sp_cursorclose", new Integer(9)); tds8SpNames.put("sp_executesql", new Integer(10)); tds8SpNames.put("sp_prepare", new Integer(11)); tds8SpNames.put("sp_execute", new Integer(12)); tds8SpNames.put("sp_prepexec", new Integer(13)); tds8SpNames.put("sp_prepexecrpc", new Integer(14));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -