📄 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 java.util.Random;
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.115 2007/07/08 17:28:23 bheineman 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;
/** target info for NTLM message TODO: I don't need to store these!!! */
byte[] ntlmTarget;
/** 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;
/** Sybase 15+ unitext. */
static final int SYB_UNITEXT = 32;
/** Sybase 15+ bigint. */
static final int SYB_BIGINT = 64;
/** Cancel has been generated by <code>Statement.cancel()</code>. */
private final static int ASYNC_CANCEL = 0;
/** Cancel has been generated by a query timeout. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -