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

📄 tdsconnection.java

📁 Java写的TDS协议(JDBC/ODBC)实现
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
//
// 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.sql.*;
import java.util.Properties;
import java.util.Vector;

/**
 * Wrapper for a <code>Tds</code> instance and a flag marking if the
 * <code>Tds</code> instance is in use.
 *
 * @author  skizz
 * @created March 16, 2001
 */
class TdsInstance
{
    /**
     * Set if the <code>Tds</code> instance is in use.
     */
    public boolean inUse = false;
    /**
     * <code>Tds</code> instance wrapped by this object.
     */
    public Tds tds = null;
    /**
     * CVS revision of the file.
     */
    public final static String cvsVersion = "$Id: TdsConnection.java,v 1.3 2002/10/17 14:59:59 alin_sinpalean Exp $";

    public TdsInstance(Tds tds_)
    {
        tds = tds_;
        inUse = false;
    }
}


/**
 *  <P>
 *
 *  A Connection represents a session with a specific database. Within the
 *  context of a Connection, SQL statements are executed and results are
 *  returned. <P>
 *
 *  A Connection's database is able to provide information describing its
 *  tables, its supported SQL grammar, its stored procedures, the capabilities
 *  of this connection, etc. This information is obtained with the getMetaData
 *  method. <P>
 *
 *  <B>Note:</B> By default the Connection automatically commits changes after
 *  executing each statement. If auto commit has been disabled, an explicit
 *  commit must be done or database changes will not be saved.
 *
 * @author     Craig Spannring
 * @author     Igor Petrovski
 * @author     Alin Sinpalean
 * @author     The FreeTDS project
 * @created    March 16, 2001
 * @version    $Id: TdsConnection.java,v 1.3 2002/10/17 14:59:59 alin_sinpalean Exp $
 * @see        Statement
 * @see        ResultSet
 * @see        DatabaseMetaData
 */
public class TdsConnection implements Connection
{
    private String host = null;
    // Can be either Driver.SYBASE or Driver.SQLSERVER
    private int serverType = -1;
    // Port numbers are _unsigned_ 16 bit, short is too small
    private int port = -1;
    private int tdsVer = -1;
    private String database = null;
    private Properties initialProps = null;

    private final Vector tdsPool = new Vector();
    private final Vector allStatements = new Vector();
    private DatabaseMetaData databaseMetaData = null;

    private boolean autoCommit = true;
    private int transactionIsolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
    private boolean isClosed = false;

    private SQLWarningChain warningChain;

    /**
     * <code>true</code> if the first <code>Tds</code> instance (the one at position 0 in <code>tdsPool</code>) is being
     * used for running <code>CursorResultSet</code> requests. In this case, all cursors will be created on this
     * <code>Tds</code>. If <code>false</code> it means no <code>CursorResultSet</code> were created on this connection.
     */
    private boolean haveMainTds = false;
    final Object mainTdsMonitor = new Object();

    /**
     * CVS revision of the file.
     */
    public final static String cvsVersion = "$Id: TdsConnection.java,v 1.3 2002/10/17 14:59:59 alin_sinpalean Exp $";

    /**
     * Create a <code>Connection</code> to a database server.
     *
     * @param  props_            <code>Properties</code> of the new
     *     <code>Connection</code> instance
     * @exception  SQLException  if a database access error occurs
     * @exception  TdsException  if a network protocol error occurs
     */
    public TdsConnection(Properties props_)
        throws SQLException, TdsException
    {
        host = props_.getProperty(Tds.PROP_HOST);
        serverType = Integer.parseInt(props_.getProperty(Tds.PROP_SERVERTYPE));
        port = Integer.parseInt(props_.getProperty(Tds.PROP_PORT));
        database = props_.getProperty(Tds.PROP_DBNAME);
        String user = props_.getProperty(Tds.PROP_USER);
        String password = props_.getProperty(Tds.PROP_PASSWORD);
        initialProps = props_;

        warningChain = new SQLWarningChain();

        if (user == null) {
            user = props_.getProperty(Tds.PROP_USER.toLowerCase());
            if (user == null) {
                throw new SQLException("Need a username.");
            }
            props_.put(Tds.PROP_USER, user);
        }

        if (password == null) {
            password = props_.getProperty(Tds.PROP_PASSWORD.toLowerCase());
            if (password == null) {
                throw new SQLException("Need a password.");
            }
            props_.put(Tds.PROP_PASSWORD, password);
        }

        Tds tmpTds = this.allocateTds(false);
        tdsVer = tmpTds.getTdsVer();
        database = tmpTds.getDatabase();
        freeTds(tmpTds);
    }

    /**
     * Returns the version of TDS used (one of the TdsDefinitions.TDS<i>XX</i>
     * constants).
     */
    protected int getTdsVer() throws SQLException
    {
        checkClosed();
        return tdsVer;
    }

    /**
     * If a connection is in auto-commit mode, then all its SQL statements will
     * be executed and committed as individual transactions. Otherwise, its SQL
     * statements are grouped into transactions that are terminated by either
     * commit() or rollback(). By default, new connections are in auto-commit
     * mode. The commit occurs when the statement completes or the next execute
     * occurs, whichever comes first. In the case of statements returning a
     * ResultSet, the statement completes when the last row of the ResultSet
     * has been retrieved or the ResultSet has been closed. In advanced cases,
     * a single statement may return multiple results as well as output
     * parameter values. Here the commit occurs when all results and output
     * param values have been retrieved.
     *
     * @param value             true enables auto-commit; false disables
     *     auto-commit.
     * @exception SQLException  if a database-access error occurs.
     */
    public synchronized void setAutoCommit(boolean value) throws SQLException
    {
        checkClosed();
        autoCommit = value;
        changeSettings();
    }

    /**
     * Change the auto-commit and transaction isolation level values for all
     * the <code>Statement</code>s belonging to this <code>Connection</code>.
     * <p>
     * Note: This is not synchronized because it's only supposed to be called
     *       by synchronized methods.
     */
    private void changeSettings() throws SQLException
    {
        for( int i=0; i<allStatements.size(); i++ )
            ((TdsStatement)allStatements.elementAt(i))
                .changeSettings(autoCommit, transactionIsolationLevel);
    }

    /**
     * You can put a connection in read-only mode as a hint to enable database
     * optimizations <B>Note:</B> setReadOnly cannot be called while in the
     * middle of a transaction
     *
     * @param readOnly          true enables read-only mode; false disables it
     * @exception SQLException  if a database access error occurs
     */
    public void setReadOnly(boolean readOnly) throws SQLException
    {
    }

    /**
     * A sub-space of this Connection's database may be selected by setting a
     * catalog name. If the driver does not support catalogs it will silently
     * ignore this request.
     *
     * @param  catalog           The new Catalog value
     * @exception  SQLException  if a database-access error occurs.
     */
    public synchronized void setCatalog(String catalog) throws SQLException
    {
        if( database.equals(catalog) )
            return;

        /** @todo Maybe find a smarter implementation for this */
        for( int i=0; i<tdsPool.size(); i++ )
        {
            Tds tds = ((TdsInstance)tdsPool.get(i)).tds;

            // SAfe We have to synchronize this so that the Statement doesn't
            //      begin sending data while we're changing the database. Not
            //      really safe though, since the Tds could be deallocated just
            //      before entering the monitor. Or not? Not too clear to me...
            synchronized( tds )
            {
                TdsStatement s = tds.statement;

                // SAfe A bit paranoic thinking here, but better to be sure it
                //      works. :o) Will synchronize again on the Tds if the
                //      Statement is null (otherwise it crashes with NPE).
                Object o = s==null ? (Object)tds : s;
                synchronized( o )
                {
                    if( s != null )
                        s.skipToEnd();
                    tds.changeDB(catalog);
                }
            }
        }

        database = catalog;
    }

    /**
     * You can call this method to try to change the transaction isolation
     * level using one of the TRANSACTION_* values. <P>
     *
     * <B>Note:</B> setTransactionIsolation cannot be called while in the
     * middle of a transaction.
     *
     * @param level             one of the TRANSACTION_* isolation values with
     *     the exception of TRANSACTION_NONE; some databases may not support
     *     other values
     * @exception SQLException  if a database-access error occurs.
     * @see                     DatabaseMetaData#supportsTransactionIsolationLevel
     */
    public synchronized void setTransactionIsolation(int level)
             throws SQLException
    {
        checkClosed();
        transactionIsolationLevel = level;
        changeSettings();
    }

    /**
     * JDBC 2.0 Installs the given type map as the type map for this
     * connection. The type map will be used for the custom mapping of SQL
     * structured types and distinct types.
     *
     * @param  map               The new TypeMap value
     * @exception  SQLException  Description of Exception
     */
    public void setTypeMap(java.util.Map map) throws SQLException
    {
        NotImplemented();
    }

    public String getUrl() throws SQLException
    {
        checkClosed();
        // XXX Is it legal to return something that might not be
        // exactly the URL used to connect?
        return
                ("jdbc:jtds:"
                 + (serverType == Tds.SYBASE ? "sybase" : "sqlserver")
                 + "://" + host + ":" + port + "/" + database);
    }

    /**
     *  Get the current auto-commit state.
     *
     *@return                   Current state of auto-commit mode.

⌨️ 快捷键说明

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