📄 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 com.internetcds.jdbc.tds;
import java.net.Socket;
import java.util.Vector;
import java.lang.Thread;
import java.util.StringTokenizer;
import java.sql.*;
import com.internetcds.jdbc.tds.TdsComm;
import com.internetcds.util.Logger;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Properties;
import java.util.TimeZone;
import java.util.Locale;
/**
* Cancel the current SQL if the timeout expires.
*
* @version $Id: Tds.java,v 1.1 2003/04/29 18:07:53 sinisa Exp $
* @author Craig Spannring
*/
class TimeoutHandler extends Thread
{
public static final String cvsVersion = "$Id: Tds.java,v 1.1 2003/04/29 18:07:53 sinisa Exp $";
java.sql.Statement stmt;
int timeout;
public TimeoutHandler(
java.sql.Statement stmt_,
int timeout_)
{
stmt = stmt_;
timeout = timeout_;
}
public void run()
{
try
{
sleep(timeout * 1000);
stmt.cancel();
}
catch(SQLException e)
{
// nop
}
catch(java.lang.InterruptedException e)
{
// nop
}
}
}
/**
* Implement the TDS protocol.
*
* @version $Id: Tds.java,v 1.1 2003/04/29 18:07:53 sinisa Exp $
* @author Craig Spannring
* @author Igor Petrovski
* @author The FreeTDS project
*/
public class Tds implements TdsDefinitions
{
public static final String cvsVersion = "$Id: Tds.java,v 1.1 2003/04/29 18:07:53 sinisa 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;
Socket sock = null;
TdsComm comm = null;
String databaseProductName;
String databaseProductVersion;
java.sql.Connection connection;
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;
String initialSettings = null;
private Properties initialProps = 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;
CancelController cancelController = null;
SqlMessage lastServerMessage = null;
// Added 2000-06-07. Used to control TDS version-specific behavior.
private int tdsVer = Tds.TDS42;
// 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);
public Tds(
java.sql.Connection connection_,
Properties props_,
String initialSettings)
throws java.io.IOException, java.net.UnknownHostException,
java.sql.SQLException, com.internetcds.jdbc.tds.TdsException
{
connection = (java.sql.Connection)connection_;
initialProps = props_;
host = props_.getProperty("HOST");
serverType = Integer.parseInt(props_.getProperty("SERVERTYPE"));
port = Integer.parseInt(props_.getProperty("PORT"));
database = props_.getProperty("DBNAME");
user = props_.getProperty("user");
password = props_.getProperty("password");
appName = props_.getProperty("APPNAME", "jdbclib");
serverName = props_.getProperty("SERVERNAME", host);
progName = props_.getProperty("PROGNAME", "java_app");
progMajorVersion = (byte)DriverVersion.getDriverMajorVersion();
progMinorVersion = (byte)DriverVersion.getDriverMinorVersion();
// String verString = props_.getProperty("TDS", "42");
String verString = props_.getProperty("TDS", "7.0");
// XXX This driver doesn't properly support TDS 5.0, AFAIK.
// Added 2000-06-07.
tdsVer = TDS42;
if (verString.equals("5.0"))
{
tdsVer = Tds.TDS50;
}
else if (verString.equals("7.0"))
{
tdsVer = Tds.TDS70;
}
// 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);
setCharset(props_.getProperty("CHARSET"));
if (logon())
{
// everything is hunky-dory.
}
else
{
throw new SQLException("Logon failed. " + lastServerMessage);
}
}
private void setCharset(String charset)
{
try
{
Logger.println("Trying to change charset to " + charset);
}
catch(java.io.IOException e)
{
// nop
}
if (charset == null || charset.length() > 30)
{
charset = "iso_1";
}
if (!charset.equals(this.charset))
{
encoder = EncodingHelper.getHelper(charset);
if (encoder == null)
{
charset = "iso_1";
encoder = EncodingHelper.getHelper(charset);
}
this.charset = charset;
}
}
EncodingHelper getEncoder() {
return encoder;
}
public void close()
{
comm.close();
try
{
sock.close();
}
catch(java.io.IOException e)
{
// XXX should do something here
}
}
static private int toUInt(byte b)
{
int result = ((int)b) & 0x00ff;
return result;
}
public String toString()
{
return ""
+ database + ", "
+ sock.getLocalAddress() + ":" + sock.getLocalPort()
+ " -> " + sock.getInetAddress() + ":" + sock.getPort();
}
/**
* Convert a JDBC escaped SQL string into the native SQL
*
* @param input escaped string to convert
*
* @return native SQL string
*/
static public String toNativeSql(String input, int serverType)
throws SQLException
{
EscapeProcessor escape;
if (serverType==TdsDefinitions.SYBASE)
{
escape = new SybaseEscapeProcessor(input);
}
else
{
escape = new MSSqlServerEscapeProcessor(input);
}
return escape.nativeString();
}
/**
* Convert a JDBC java.sql.Types identifier to a SQLServer type identifier
*
* @author Craig Spannring
*
* @param jdbcType JDBC type to convert. Should be one of the
* constants from java.sql.Types.
*
* @return The corresponding SQLServer type identifier.
*/
public static byte cvtJdbcTypeToNativeType(int jdbcType)
throws TdsNotImplemented
{
// This function is thread safe.
byte result = 0;
switch(jdbcType)
{
case java.sql.Types.CHAR:
// case java.sql.Types.VARCHAR:
// case java.sql.Types.LONGVARCHAR:
{
result = SYBCHAR;
break;
}
//Sinisa
//Add java.sql.types VARCHAR & LONGVARCHAR as a native type SYBVARCHAR
case java.sql.Types.VARCHAR:
case java.sql.Types.LONGVARCHAR:
{
result = SYBVARCHAR;
break;
}
//Sinisa
//Add java.sql.types VARCHAR & LONGVARCHAR as a native type SYBFLT8
case java.sql.Types.DECIMAL:
{
result = SYBFLT8;
break;
}
case java.sql.Types.INTEGER:
case java.sql.Types.SMALLINT:
case java.sql.Types.BIGINT:
{
result = SYBINT4;
break;
}
case java.sql.Types.REAL:
case java.sql.Types.DOUBLE:
{
result = SYBFLT8;
break;
}
case java.sql.Types.DATE:
case java.sql.Types.TIMESTAMP:
case java.sql.Types.TIME:
{
result = SYBDATETIMN;
break;
}
case java.sql.Types.VARBINARY:
case java.sql.Types.LONGVARBINARY:
{
result = SYBIMAGE;
break;
}
//Dusan
case java.sql.Types.BIT:
{
result = SYBBIT;
break;
}
default:
{
throw new TdsNotImplemented("cvtJdbcTypeToNativeType ("
+ TdsUtil.javaSqlTypeToString(jdbcType) + ")");
}
}
return result;
}
/**
* Convert a JDBC java.sql.Types identifier to a
* SQLServer type identifier
*
* @author Craig Spannring
*
* @param nativeType SQLServer type to convert.
* @param size Maximum size of data coming back from server.
*
* @return The corresponding JDBC type identifier.
*/
public static int cvtNativeTypeToJdbcType(int nativeType,
int size)
throws TdsException
{
// This function is thread safe.
int result = java.sql.Types.OTHER;
switch(nativeType)
{
// XXX We need to figure out how to map _all_ of these types
case SYBBINARY: result = java.sql.Types.BINARY; break;
case SYBBIT: result = java.sql.Types.BIT; break;
case SYBBITN: result = java.sql.Types.BIT; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -