📄 tds.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.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 + -