📄 tdsconnection.java
字号:
//
// 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 + -