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

📄 tds.java

📁 Java写的TDS协议(JDBC/ODBC)实现
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
//
// Copyright 1998, 1999 CDS Networks, Inc., Medford Oregon
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
//    must display the following acknowledgement:
//      This product includes software developed by CDS Networks, Inc.
// 4. The name of CDS Networks, Inc.  may not be used to endorse or promote
//    products derived from this software without specific prior
//    written permission.
//
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//




package net.sourceforge.jtds.jdbc;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.Socket;
import java.sql.*;
import java.util.*;

import net.sourceforge.jtds.util.Logger;

/**
 * Cancel the current SQL if the timeout expires.
 *
 * @author     Craig Spannring
 * @created    March 17, 2001
 * @version    $Id: Tds.java,v 1.4 2002/11/07 11:07:01 alin_sinpalean Exp $
 */
class TimeoutHandler extends Thread
{
    public final static String cvsVersion = "$Id: Tds.java,v 1.4 2002/11/07 11:07:01 alin_sinpalean Exp $";

    Tds tds;
    SQLWarningChain wChain;
    int timeout;

    public TimeoutHandler(Tds tds_, SQLWarningChain wChain_, int timeout_)
    {
        tds = tds_;
        wChain = wChain_;
        timeout = timeout_;
    }

    public void run()
    {
        try {
            sleep( timeout * 1000 );
            // SAfe The java.sql.Statement.cancel() javadoc says an SQLException
            //      must be thrown if the execution timed out, so that's what
            //      we're going to do.
            wChain.addException(new SQLException("Query has timed out."));
            tds.cancel();
            System.out.println("Cancel done.");
        }
        // Ignore interrupts (this is how we know all was ok)
        catch( java.lang.InterruptedException e )
        {
            // nop
        }
        // SAfe Add an exception if anything else happens
        catch( Exception ex )
        {
            wChain.addException(new SQLException(ex.toString()));
        }
    }
}


/**
 *  Implement the TDS protocol.
 *
 *@author     Craig Spannring
 *@author     Igor Petrovski
 *@author     The FreeTDS project
 *@created    March 17, 2001
 *@version    $Id: Tds.java,v 1.4 2002/11/07 11:07:01 alin_sinpalean Exp $
 */
public class Tds implements TdsDefinitions {


    Socket sock = null;
    TdsComm comm = null;

    String databaseProductName;
    String databaseProductVersion;
    int databaseMajorVersion;

    TdsConnection connection;
    TdsStatement statement;
    String host;
    int serverType = -1;
    // either Tds.SYBASE or Tds.SQLSERVER
    int port;
    // Port numbers are _unsigned_ 16 bit, short is too small
    String database;
    String user;
    String password;
    String appName;
    String serverName;
    String progName;
    byte progMajorVersion;
    byte progMinorVersion;

    boolean haveProcNameTable = false;
    String procNameGeneratorName = null;
    String procNameTableName = null;

    HashMap             procedureCache = null; // XXX: as
    ArrayList           proceduresOfTra = null;

    CancelController cancelController = null;

    SqlMessage lastServerMessage = null;

    private EncodingHelper encoder = null;
    private String charset = null;

    // int          rowCount    = -1;    // number of rows selected or updated
    private boolean moreResults = false;
    // Is there another result set?

    // Jens Jakobsen 1999-01-10
    // Until TDS_END_TOKEN is reached we assume that there are outstanding
    // UpdateCounts or ResultSets
    private boolean moreResults2 = true;

    // Added 2000-06-07.  Used to control TDS version-specific behavior.
    private int tdsVer = Tds.TDS70;

    // RMK 2000-06-08.
    private boolean showWarnings = false;

    // RMK 2000-06-12.  Time zone offset on client (disregarding DST).
    private int zoneOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET);

    int maxRows = 0;
    /**
     *  Description of the Field
     */
    public final static String cvsVersion = "$Id: Tds.java,v 1.4 2002/11/07 11:07:01 alin_sinpalean Exp $";

    //
    // If the following variable is false we will consider calling
    // unimplemented methods to be an error and will raise an exception.
    // If you want to ignore any unimplemented methods, set it to
    // true.  Only do this if you know what you are doing and can tolerate
    // bogus results from the unimplemented methods.
    //
    static boolean ignoreNotImplemented = false;

    /**
     * The last transaction isolation level set for this <code>Tds</code>.
     */
    int transactionIsolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;

    /**
     * The last auto commit mode set on this <code>Tds</code>.
     */
    boolean autoCommit = true;

    public Tds(
            TdsConnection connection_,
            Properties props_)
             throws java.io.IOException, java.net.UnknownHostException,
            java.sql.SQLException, net.sourceforge.jtds.jdbc.TdsException
    {
        connection = connection_;

        host = props_.getProperty(PROP_HOST);
        serverType = Integer.parseInt(props_.getProperty(PROP_SERVERTYPE));
        port = Integer.parseInt(props_.getProperty(PROP_PORT));
        // SAfe We don't know what database we'll get (probably master)
        database = null;
        user = props_.getProperty(PROP_USER);
        password = props_.getProperty(PROP_PASSWORD);
        appName = props_.getProperty(PROP_APPNAME, "jdbclib");
        serverName = props_.getProperty(PROP_SERVERNAME, host);
        progName = props_.getProperty(PROP_PROGNAME, "java_app");
        progMajorVersion = (byte) DriverVersion.getDriverMajorVersion();
        progMinorVersion = (byte) DriverVersion.getDriverMinorVersion();
        String verString = props_.getProperty(PROP_TDS, "7.0");
        procedureCache = new HashMap(); // new Vector();   // XXX as
        proceduresOfTra = new ArrayList();

        // XXX This driver doesn't properly support TDS 5.0, AFAIK.
        // Added 2000-06-07.

        if (verString.equals("5.0")) {
            tdsVer = Tds.TDS50;
        }
        else if (verString.equals("4.2")) {
            tdsVer = Tds.TDS42;
        }

        // RMK 2000-06-08
        if (System.getProperty("TDS_SHOW_WARNINGS") != null
                 ||
                props_.getProperty("TDS_SHOW_WARNINGS") != null) {
            showWarnings = true;
        }

        cancelController = new CancelController();

        // Send the logon packet to the server
        sock = new Socket(host, port);
        sock.setTcpNoDelay(true);
        comm = new TdsComm(sock, tdsVer);

        String cs = props_.getProperty("CHARSET");
        cs = cs==null ? props_.getProperty("charset") : cs;
        setCharset(cs);

        autoCommit = connection.getAutoCommit();
        transactionIsolationLevel = connection.getTransactionIsolation();

        if( !logon(props_.getProperty(PROP_DBNAME)) )
            throw new SQLException("Logon failed.  " + lastServerMessage);
    }

    /**
     * Set the <code>TdsStatement</code> currently using the Tds.
     */
    public void setStatement(TdsStatement s)
    {
        statement = s;
    }

    /**
     * Get the <code>Statement</code> currently using the Tds.
     */
    public Statement getStatement()
    {
        return statement;
    }

    /**
     * Get the <code>Statement</code> currently using the Tds.
     */
    public String getDatabase()
    {
        return database;
    }

    /*
     * cvtNativeTypeToJdbcType()
     */

    /**
     *  Return the type of server that we attempted to connect to.
     *
     *@return    TdsDefinitions.SYBASE or TdsDefinitions.SQLSERVER
     */
    public int getServerType()
    {
        return serverType;
    }


    /**
     *  Create a new and unique name for a store procedure. This routine will
     *  return a unique name for a stored procedure that will be associated with
     *  a PreparedStatement(). <p>
     *
     *  Since SQLServer supports temporary procedure names we can just use
     *  UniqueId.getUniqueId() to generate a unique (for the connection) name.
     *  <p>
     *
     *  Sybase does not support temporary procedure names so we will have to
     *  have a per user table devoted to storing user specific stored
     *  procedures. The table name will be of the form
     *  database.user.jdbc_temp_stored_proc_names. The table will be defined as
     *  <code>CREATE TABLE database.user.jdbc_temp_stored_proc_names ( id
     *  NUMERIC(10, 0) IDENTITY; session int not null; name char(29) )</code>
     *  This routine will use that table to track names that are being used.
     *
     *@return                            The UniqueProcedureName value
     *@exception  java.sql.SQLException  Description of Exception
     */
    public String getUniqueProcedureName()
             throws java.sql.SQLException
    {
        String result = null;

        if (serverType == SYBASE) {
            if (null == procNameTableName) {
                procNameTableName = database + "." + user
                         + ".jdbc_temp_stored_proc_names";
                procNameGeneratorName = user + ".jdbc_gen_temp_sp_names";
            }

            //
            // Attempt to create the table for the stored procedure names
            // If it already exists we'll get an error, but we don't care.
            // Also create a stored procedure for generating the unique
            // names.
            //
            haveProcNameTable = createStoredProcedureNameTable();

            result = generateUniqueProcName();
        }
        else {
            result = "#jdbc#" + UniqueId.getUniqueId();
        }
        return result;
    }
    // peek()

    synchronized public byte getByte()
      throws java.io.IOException, net.sourceforge.jtds.jdbc.TdsException
    {
      return comm.getByte();
    } // peek()


    /**
     *  Determine if the next subpacket is a result set. <p>
     *
     *  This does not eat any input.
     *
     *@return                                            true if the next piece
     *      of data to read is a result set.
     *@exception  net.sourceforge.jtds.jdbc.TdsException
     *@exception  java.io.IOException
     */
    public synchronized boolean isResultSet()
             throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        byte type = comm.peek();

        /*
         * XXX to support 5.0 we need to expand our view of what a result
         * set is.
         */
        return type == TDS_COL_NAME_TOKEN || type == TDS_COLMETADATA;
    }


    /**
     *  Determine if the next subpacket is a ret stat <p>
     *
     *  This does not eat any input.
     *
     *@return                                            true if the next piece
     *      of data to read is a result row.
     *@exception  net.sourceforge.jtds.jdbc.TdsException
     *@exception  java.io.IOException
     */
    public synchronized boolean isRetStat()
             throws net.sourceforge.jtds.jdbc.TdsException, java.io.IOException
    {
        byte type = comm.peek();

        return type == TDS_RETURNSTATUS;
    }

⌨️ 快捷键说明

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