📄 mysqlio.java
字号:
/*
* MM JDBC Drivers for MySQL
*
* $Id: MysqlIO.java,v 1.6 2002/05/16 20:28:38 mark_matthews Exp $
*
* Copyright (C) 1998 Mark Matthews <mmatthew@worldserver.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*
* See the COPYING file located in the top-level-directory of
* the archive of this library for complete text of license.
*/
/**
* This class is used by Connection for communicating with the
* MySQL server.
*
* @see java.sql.Connection
* @author Mark Matthews <mmatthew@worldserver.com>
* @version $Id: MysqlIO.java,v 1.6 2002/05/16 20:28:38 mark_matthews Exp $
*/
package com.mysql.jdbc;
import java.io.*;
import java.net.*;
import java.util.*;
import java.sql.*;
import java.sql.SQLException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public abstract class MysqlIO {
/** The connection to the server */
private Socket _mysqlConnection = null;
/** Buffered data from the server */
//private BufferedInputStream _Mysql_Buf_Input = null;
/** Buffered data to the server */
//private BufferedOutputStream _Mysql_Buf_Output = null;
/** Data from the server */
//private DataInputStream _Mysql_Input = null;
private InputStream _mysqlInput = null;
/** Data to the server */
//private DataOutputStream _Mysql_Output = null;
private BufferedOutputStream _mysqlOutput = null;
/** Current open, streaming result set (if any) */
private ResultSet _pendingResultSet = null;
static int MAXBUF = 65535;
static final int HEADER_LENGTH = 4;
static final int COMP_HEADER_LENGTH = 3;
private byte _packetSequence = 0;
private byte _protocolVersion = 0;
private String _serverVersion = null;
private int _serverMajorVersion = 0;
private int _serverMinorVersion = 0;
private int _serverSubMinorVersion = 0;
private int _port = 3306;
private String _host = null;
private Deflater _deflater = null;
private Inflater _inflater = null;
//
// Use this when reading in rows to avoid thousands of new()
// calls, because the byte arrays just get copied out of the
// packet anyway
//
private Buffer _reusablePacket = null;
private Buffer _sendPacket = null;
//
// For SQL Warnings
//
java.sql.SQLWarning _warningChain = null;
private static int CLIENT_LONG_PASSWORD = 1; /* new more secure
passwords */
private static int CLIENT_FOUND_ROWS = 2;
/* Found instead of
affected rows */
private static int CLIENT_LONG_FLAG = 4; /* Get all column flags */
private static int CLIENT_CONNECT_WITH_DB = 8;
/* One can specify db
on connect */
private static int CLIENT_NO_SCHEMA = 16; /* Don't allow
db.table.column */
private static int CLIENT_COMPRESS = 32; /* Can use compression
protcol */
private static int CLIENT_ODBC = 64; /* Odbc client */
private static int CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA
LOCAL */
private static int CLIENT_IGNORE_SPACE = 256; /* Ignore spaces
before '(' */
private boolean _useCompression = false;
private com.mysql.jdbc.Connection _connection;
private boolean _profileSql = false;
/**
* Constructor: Connect to the MySQL server and setup
* a stream connection.
*
* @param host the hostname to connect to
* @param port the port number that the server is listening on
* @exception IOException if an IOException occurs during connect.
*/
public MysqlIO(String Host, int port, com.mysql.jdbc.Connection Conn)
throws IOException, java.sql.SQLException {
_connection = Conn;
_reusablePacket =
new Buffer(_connection.getNetBufferLength(), _connection.getMaxAllowedPacket());
_port = port;
_host = Host;
_mysqlConnection = new Socket(_host, _port);
try {
_mysqlConnection.setTcpNoDelay(true);
}
catch (Exception ex) {
/* Ignore */
}
_mysqlInput = new BufferedInputStream(_mysqlConnection.getInputStream(), 16384);
_mysqlOutput = new BufferedOutputStream(_mysqlConnection.getOutputStream());
//_Mysql_Input = new DataInputStream(_Mysql_Buf_Input);
//_Mysql_Output = new DataOutputStream(_Mysql_Buf_Output);
}
/**
* Initialize communications with the MySQL server.
*
* Handles logging on, and handling initial connection errors.
*/
void init(String User, String Password) throws java.sql.SQLException {
String Seed;
try {
// Read the first packet
Buffer Buf = readPacket();
// Get the protocol version
_protocolVersion = Buf.readByte();
if (_protocolVersion == -1) {
try {
_mysqlConnection.close();
}
catch (Exception E) {
}
throw new SQLException(
"Server configuration denies access to data source",
"08001",
0);
}
_serverVersion = Buf.readString();
// Parse the server version into major/minor/subminor
int point = _serverVersion.indexOf(".");
if (point != -1) {
try {
int n = Integer.parseInt(_serverVersion.substring(0, point));
_serverMajorVersion = n;
}
catch (NumberFormatException NFE1) {
}
String Remaining = _serverVersion.substring(point + 1, _serverVersion.length());
point = Remaining.indexOf(".");
if (point != -1) {
try {
int n = Integer.parseInt(Remaining.substring(0, point));
_serverMinorVersion = n;
}
catch (NumberFormatException NFE2) {
}
Remaining = Remaining.substring(point + 1, Remaining.length());
int pos = 0;
while (pos < Remaining.length()) {
if (Remaining.charAt(pos) < '0' || Remaining.charAt(pos) > '9') {
break;
}
pos++;
}
try {
int n = Integer.parseInt(Remaining.substring(0, pos));
_serverSubMinorVersion = n;
}
catch (NumberFormatException NFE3) {
}
}
}
long threadId = Buf.readLong();
Seed = Buf.readString();
if (Driver.trace) {
Debug.msg(this, "Protocol Version: " + (int) _protocolVersion);
Debug.msg(this, "Server Version: " + _serverVersion);
Debug.msg(this, "Thread ID: " + threadId);
Debug.msg(this, "Crypt Seed: " + Seed);
}
// Client capabilities
int clientParam = 0;
if (Buf._pos < Buf._bufLength) {
int serverCapabilities = Buf.readInt();
// Should be settable by user
if ((serverCapabilities & CLIENT_COMPRESS) != 0) {
// The following match with ZLIB's
// decompress() and compress()
//_Deflater = new Deflater();
//_Inflater = new Inflater();
//clientParam |= CLIENT_COMPRESS;
}
}
// return FOUND rows
clientParam |= CLIENT_FOUND_ROWS;
// Authenticate
if (_protocolVersion > 9) {
clientParam |= CLIENT_LONG_PASSWORD; // for long passwords
}
else {
clientParam &= ~CLIENT_LONG_PASSWORD;
}
int password_length = 16;
int user_length = 0;
if (User != null) {
user_length = User.length();
}
int pack_length = (user_length + password_length) + 6 + HEADER_LENGTH;
// Passwords can be 16 chars long
Buffer Packet = new Buffer(pack_length);
Packet.writeInt(clientParam);
Packet.writeLongInt(pack_length);
// User/Password data
Packet.writeString(User);
if (_protocolVersion > 9) {
Packet.writeString(Util.newCrypt(Password, Seed));
}
else {
Packet.writeString(Util.oldCrypt(Password, Seed));
}
send(Packet);
// Check for errors
Buffer B = readPacket();
byte status = B.readByte();
if (status == (byte) 0xff) {
String Message = "";
int errno = 2000;
if (_protocolVersion > 9) {
errno = B.readInt();
Message = B.readString();
clearReceive();
String XOpen = SQLError.mysqlToXOpen(errno);
if (XOpen.equals("S1000")) {
throw new java.sql.SQLException(
"Communication failure during handshake. Is there a server running on "
+ _host
+ ":"
+ _port
+ "?");
}
else {
throw new java.sql.SQLException(
SQLError.get(XOpen) + ": " + Message,
XOpen,
errno);
}
}
else {
Message = B.readString();
clearReceive();
if (Message.indexOf("Access denied") != -1) {
throw new java.sql.SQLException(
SQLError.get("28000") + ": " + Message,
"28000",
errno);
}
else {
throw new java.sql.SQLException(
SQLError.get("08001") + ": " + Message,
"08001",
errno);
}
}
}
else
if (status == 0x00) {
if (_serverMajorVersion >= 3
&& _serverMinorVersion >= 22
&& _serverSubMinorVersion >= 5) {
Packet.newReadLength();
Packet.newReadLength();
}
else {
Packet.readLength();
Packet.readLength();
}
}
else {
throw new java.sql.SQLException(
"Unknown Status code from server",
"08007",
status);
}
//if ((clientParam & CLIENT_COMPRESS) != 0) {
//use_compression = true;
//}
}
catch (IOException E) {
throw new java.sql.SQLException(
SQLError.get("08S01") + ": " + E.getClass().getName(),
"08S01",
0);
}
}
/**
* Sets the buffer size to max-buf
*/
void resetMaxBuf() {
_reusablePacket._maxLength = _connection.getMaxAllowedPacket();
_sendPacket._maxLength = _connection.getMaxAllowedPacket();
}
/**
* Get the version string of the server we are talking to
*/
String getServerVersion() {
return _serverVersion;
}
/**
* Send a command to the MySQL server
*
* If data is to be sent with command, it should be put in ExtraData
*
* Raw packets can be sent by setting QueryPacket to something other
* than null.
*/
final Buffer sendCommand(int command, String ExtraData, Buffer QueryPacket)
throws Exception {
Buffer Ret = null; // results of our query
byte statusCode; // query status code
try {
//
// PreparedStatements construct their own packets,
// for efficiency's sake.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -