⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysqlio.java

📁 用java访问MySQL数据库的JDBC驱动程序。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * MM JDBC Drivers for MySQL
 *
 * $Id: MysqlIO.java,v 1.3 1998/08/25 00:53:47 mmatthew 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$
 */

package org.gjt.mm.mysql;

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 class MysqlIO
{
    private Socket               _Mysql_Conn               = null;
    private BufferedInputStream  _Mysql_Buf_Input          = null;
    private BufferedOutputStream _Mysql_Buf_Output         = null;
    private DataInputStream      _Mysql_Input              = null;
    private DataOutputStream     _Mysql_Output             = null;

    static int                   MAXBUF                    = 65535; 
    static final int             HEADER_LENGTH             = 4;
    static final int             COMP_HEADER_LENGTH        = 3;

    private byte                 _packetSequence           = 0;
    private byte                 _protocol_V               = 0;
    private String               _Server_V                 = null;
    private int                  _server_major_version     = 0;
    private int                  _server_minor_version     = 0;
    private int                  _server_sub_minor_version = 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 = new Buffer(MAXBUF);
  
    //
    // For SQL Warnings
    //

    java.sql.SQLWarning _Warning = 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 database.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 use_compression = 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.
     */
    
    MysqlIO(String Host, int port) throws IOException, java.sql.SQLException
    {
	_port = port;
	_Host = Host;

	_Mysql_Conn = new Socket(_Host, _port);
	_Mysql_Buf_Input  = new BufferedInputStream(_Mysql_Conn.getInputStream());
	_Mysql_Buf_Output = new BufferedOutputStream(_Mysql_Conn.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
	    _protocol_V = Buf.readByte(); 
			
	    if (_protocol_V == -1) {
		try {
		    _Mysql_Conn.close();
		}
		catch (Exception E) {}
				
		throw new SQLException("Server configuration denies access to data source", "08001", 0);
	    }
	    _Server_V = Buf.readString();
		    
	    // Parse the server version into major/minor/subminor 
		    
	    int point = _Server_V.indexOf(".");
		    
	    if (point != -1) {
		try {
		    int n = Integer.parseInt(_Server_V.substring(0, point));
		    _server_major_version = n;
		}
		catch (NumberFormatException NFE1) {
		}
			
			
		String Remaining = _Server_V.substring(point + 1, _Server_V.length());
		  
		point = Remaining.indexOf(".");
		  
		if (point != -1) {
		    try {
			int n = Integer.parseInt(Remaining.substring(0, point));
			_server_minor_version = 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));
			_server_sub_minor_version = n;
		    }
		    catch (NumberFormatException NFE3) {
		    }     
		}
	    }
		  
	    long threadId = Buf.readLong();

	    Seed = Buf.readString();
   
	    if (Driver.trace) {
		Debug.msg(this, "Protocol Version: " + (int)_protocol_V);
		Debug.msg(this, "Server Version: " + _Server_V);
		Debug.msg(this, "Thread ID: " + threadId);
		Debug.msg(this, "Crypt Seed: " + Seed);
	    }

	    // Client capabilities
	    int clientParam = 0;

	    if (Buf.pos < Buf.buf_length) {
		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;
		}
	    }
    
	    // Authenticate
	 	
	    if (_protocol_V > 9) {
		//clientParam |= CLIENT_LONG_PASSWORD; // for long passwords
		clientParam = 1;
	    }
	    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 (_protocol_V > 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 (_protocol_V > 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 (_server_major_version >= 3 &&
		    _server_minor_version >= 22 &&
		    _server_sub_minor_version >= 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) {
	    E.printStackTrace();
	    throw new java.sql.SQLException(SQLError.get("08S01") + ": " + E.getClass().getName(), "08S01", 0);
	}
    }

    /**
     * Get the version string of the server we are talking to
     */

    String getServerVersion()
    {
	return _Server_V;
    }

    /**
     * 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;
	byte statusCode;

	try {
	    Buffer Packet = null;
		
	    if (QueryPacket == null) {
		int pack_length = HEADER_LENGTH + COMP_HEADER_LENGTH + 1 + ExtraData.length() + 2;
		Packet = new Buffer(pack_length);
		_packetSequence = -1;
		Packet.clear();

		// Offset different for compression
		if (use_compression) {
		    Packet.pos += COMP_HEADER_LENGTH;
		}

		Packet.writeByte((byte)command);
			
		if (command == MysqlDefs.INIT_DB || command == MysqlDefs.CREATE_DB ||
		    command == MysqlDefs.DROP_DB || command == MysqlDefs.QUERY) {
				
		    Packet.writeStringNoNull(ExtraData);
		}
		else if (command == MysqlDefs.PROCESS_KILL) {
		    long id = new Long(ExtraData).longValue();
		    Packet.writeLong(id);
		}
		else if (command == MysqlDefs.RELOAD && _protocol_V > 9) {
		    Debug.msg(this, "Reload");
		    //Packet.writeByte(reloadParam);
		}
	    }
	    else {
		_packetSequence = -1;
		Packet = QueryPacket;
	    }
	    send(Packet);
	}
	catch (Exception Ex) {
	    Ex.printStackTrace();
	    throw new java.sql.SQLException(SQLError.get("08S01") + ": " 
					    + Ex.getClass().getName(), "08S01", 0);
	}

	try {
    
	    // Check return value, if we get a java.io.EOFException,
            // the server has gone away. We'll pass it on up the 
            // exception chain and let someone higher up decide
	    // what to do (barf, reconnect, etc).

	    Ret = readPacket();

	    statusCode = Ret.readByte();
	}
	catch (java.io.EOFException EOFE) {
	    throw EOFE;
	}
	catch (Exception FallThru) {
	    throw new java.sql.SQLException(SQLError.get("08S01") 
					    + ": " +
					    FallThru.getClass().getName(), 
					    "08S01", 0);
	}
	 
	try {
	    
	    // Error handling
	    if (statusCode == (byte)0xff) {
		String ErrorMessage;
		int errno = 2000;

		if (_protocol_V > 9) {
		    errno = Ret.readInt();
		    ErrorMessage = Ret.readString();
		    clearReceive();
		    String XOpen = SQLError.mysqlToXOpen(errno);

		    throw new java.sql.SQLException(SQLError.get(XOpen) + 
						    ": " + ErrorMessage, 
						    XOpen, errno);
		}
		else {
		    ErrorMessage = Ret.readString();
		    clearReceive();

		    if (ErrorMessage.indexOf("Unknown column") != -1) {
			throw new java.sql.SQLException(SQLError.get("S0022") 
							+ ": " + ErrorMessage,
							"S0022", -1);
		    }
		    else {
			throw new java.sql.SQLException(SQLError.get("S1000") 
							+ ": " + ErrorMessage,
							"S1000", -1);
		    }
		}
	    }
	    else if (statusCode == 0x00) {
		if (command == MysqlDefs.CREATE_DB || command == MysqlDefs.DROP_DB) {
		    java.sql.SQLWarning NW = new java.sql.SQLWarning("Command=" + command + ": ");
		    if (_Warning != null)
			NW.setNextException(_Warning);
		    _Warning = NW;
		}
	    }
	    else if (Ret.isLastDataPacket()) {
		java.sql.SQLWarning NW = new java.sql.SQLWarning("Command=" + command + ": ");
		if (_Warning != null)
		    NW.setNextException(_Warning);
		_Warning = NW;
	    }
	    return Ret;
	}
	catch (IOException E) {
	    throw new java.sql.SQLException(SQLError.get("08S01") + ": " + E.getClass().getName(), "08S01", 0);
	}
    }

    /**
     * Send a query stored in a packet directly to the server.
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -