📄 tds.java
字号:
case SYBCHAR: result = java.sql.Types.CHAR; break;
case SYBNCHAR: result = java.sql.Types.CHAR; break;
case SYBDATETIME4: result = java.sql.Types.TIMESTAMP; break;
case SYBDATETIME: result = java.sql.Types.TIMESTAMP; break;
case SYBDATETIMN: result = java.sql.Types.TIMESTAMP; break;
case SYBDECIMAL: result = java.sql.Types.DECIMAL; break;
case SYBNUMERIC: result = java.sql.Types.NUMERIC; break;
case SYBFLT8: result = java.sql.Types.DOUBLE; break;
case SYBFLTN: result = java.sql.Types.DOUBLE; break;
case SYBINT1: result = java.sql.Types.TINYINT; break;
case SYBINT2: result = java.sql.Types.SMALLINT; break;
case SYBINT4: result = java.sql.Types.INTEGER; break;
case SYBINTN:
{
switch (size)
{
case 1: result = java.sql.Types.TINYINT; break;
case 2: result = java.sql.Types.SMALLINT; break;
case 4: result = java.sql.Types.INTEGER; break;
default: throw new TdsException("Bad size of SYBINTN");
}
break;
}
// XXX Should money types by NUMERIC or OTHER?
case SYBSMALLMONEY: result = java.sql.Types.NUMERIC; break;
case SYBMONEY4: result = java.sql.Types.NUMERIC; break;
case SYBMONEY: result = java.sql.Types.NUMERIC; break;
case SYBMONEYN: result = java.sql.Types.NUMERIC; break;
// case SYBNUMERIC: result = java.sql.Types.NUMERIC; break;
case SYBREAL: result = java.sql.Types.REAL; break;
case SYBTEXT: result = java.sql.Types.LONGVARCHAR; break;
case SYBNTEXT: result = java.sql.Types.LONGVARCHAR; break;
case SYBIMAGE: result = java.sql.Types.VARBINARY; break;
case SYBVARBINARY: result = java.sql.Types.VARBINARY; break;
case SYBVARCHAR: result = java.sql.Types.VARCHAR; break;
case SYBNVARCHAR: result = java.sql.Types.VARCHAR; break;
// case SYBVOID: result = java.sql.Types. ; break;
default: throw new TdsException("Unknown native data type "
+ Integer.toHexString(
nativeType&0xff));
}
return result;
} /* cvtNativeTypeToJdbcType() */
/**
* Return the type of server that we attempted to connect to.
*
* @return TdsDefinitions.SYBASE or TdsDefinitions.SQLSERVER
*/
public int getServerType()
{
return serverType;
}
/**
* Try to figure out what client name we should identify
* ourselves as. Get the hostname of this machine,
*
* @return name we will use as the client.
*/
private String getClientName()
{
// This method is thread safe.
String tmp;
try
{
tmp = java.net.InetAddress.getLocalHost().getHostName();
}
catch(java.net.UnknownHostException e)
{
tmp = "";
}
StringTokenizer st = new StringTokenizer(tmp, ".");
if (!st.hasMoreTokens())
{
// This means hostname wasn't found for this machine.
return "JOHNDOE";
}
// Look at the first (and possibly only) word in the name.
tmp = st.nextToken();
if (tmp.length()==0)
{
// This means the hostname had no leading component.
// (This case would be strange.)
return "JANEDOE";
}
else if (Character.isDigit(tmp.charAt(0)))
{
// This probably means that the name was a quad-decimal
// number. We don't want to send that as our name,
// so make one up.
return "BABYDOE";
}
else
{
// Ah, Life is good. We have a name. All other
// applications I've seen have upper case client names,
// and so shall we.
return tmp.toUpperCase();
}
}
/**
* Log onto the SQLServer
* <p>
*
* This method is not synchronized and does not need to be so long
* as it can only be called from the constructor.
*
* <p>
* <U>Login Packet</U>
* <P>
* Packet type (first byte) is 2. The following is from tds.h the numbers
* on the left are offsets <I>not including</I> the packet header.
* <br>
* Note: The logical logon packet is split into two physical
* packets. Each physical packet has its own header.
* <br>
* <PRE>
* -- 0 -- DBCHAR host_name[30];
* -- 30 -- DBTINYINT host_name_length;
* -- 31 -- DBCHAR user_name[30];
* -- 61 -- DBTINYINT user_name_length;
* -- 62 -- DBCHAR password[30];
* -- 92 -- DBTINYINT password_length;
* -- 93 -- DBCHAR host_process[30];
* -- 123 -- DBTINYINT host_process_length;
* -- 124 -- DBCHAR magic1[6]; -- here were most of the mystery stuff is --
* -- 130 -- DBTINYINT bulk_copy;
* -- 131 -- DBCHAR magic2[9]; -- here were most of the mystery stuff is --
* -- 140 -- DBCHAR app_name[30];
* -- 170 -- DBTINYINT app_name_length;
* -- 171 -- DBCHAR server_name[30];
* -- 201 -- DBTINYINT server_name_length;
* -- 202 -- DBCHAR magic3; -- 0, dont know this one either --
* -- 203 -- DBTINYINT password2_length;
* -- 204 -- DBCHAR password2[30];
* -- 234 -- DBCHAR magic4[223];
* -- 457 -- DBTINYINT password2_length_plus2;
* -- 458 -- DBSMALLINT major_version; -- TDS version --
* -- 460 -- DBSMALLINT minor_version; -- TDS version --
* -- 462 -- DBCHAR library_name[10]; -- Ct-Library or DB-Library --
* -- 472 -- DBTINYINT library_length; -- Ct-Library or DB-Library --
* -- 473 -- DBSMALLINT major_version2; -- program version --
* -- 475 -- DBSMALLINT minor_version2; -- program version --
* -- 477 -- DBCHAR magic6[3]; -- ? last two octets are 13 and 17 --
* -- bdw reports last two as 12 and 16 here --
* -- possibly a bitset flag --
* -- 480 -- DBCHAR language[30]; -- ie us-english --
* -- second packet --
* -- 524 -- DBTINYINT language_length; -- 10 in this case --
* -- 525 -- DBCHAR magic7; -- no clue... has 1 in the first octet --
* -- bdw reports 0x0 --
* -- 526 -- DBSMALLINT old_secure; -- explaination? --
* -- 528 -- DBTINYINT encrypted; -- 1 means encrypted all password fields blank --
* -- 529 -- DBCHAR magic8; -- no clue... zeros --
* -- 530 -- DBCHAR sec_spare[9]; -- explaination --
* -- 539 -- DBCHAR char_set[30]; -- ie iso_1 --
* -- 569 -- DBTINYINT char_set_length; -- 5 --
* -- 570 -- DBTINYINT magic9; -- 1 --
* -- 571 -- DBCHAR block_size[6]; -- in text --
* -- 577 -- DBTINYINT block_size_length;
* -- 578 -- DBCHAR magic10[25]; -- lots of stuff here...no clue --
*
* </PRE>
*
* This routine will basically eat all of the data returned from the
* SQLServer.
*
* @author Craig Spannring
*
* @exception TdsUnknownPacketSubType
* @exception com.internetcds.jdbc.tds.TdsException
* @exception java.io.IOException
* @exception java.sql.SQLException
*/
private boolean logon()
throws java.sql.SQLException,
TdsUnknownPacketSubType, java.io.IOException,
com.internetcds.jdbc.tds.TdsException
{
boolean isOkay = true;
byte pad = (byte) 0;
byte[] empty = new byte[0];
// Added 2000-06-07.
if (tdsVer == Tds.TDS70)
send70Login();
else {
comm.startPacket(TdsComm.LOGON);
// hostname (offset0)
// comm.appendString("TOLEDO", 30, (byte)0);
byte[] tmp = encoder.getBytes(getClientName());
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// username (offset 31 0x1f)
tmp = encoder.getBytes(user);
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// password (offset 62 0x3e)
tmp = encoder.getBytes(password);
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// hostproc (offset 93 0x5d)
tmp = encoder.getBytes("00000116");
comm.appendBytes(tmp, 8, pad);
// unused (offset 109 0x6d)
comm.appendBytes(empty, (30-14), pad);
// apptype (offset )
comm.appendByte((byte)0x0);
comm.appendByte((byte)0xA0);
comm.appendByte((byte)0x24);
comm.appendByte((byte)0xCC);
comm.appendByte((byte)0x50);
comm.appendByte((byte)0x12);
// hostproc length (offset )
comm.appendByte((byte)8);
// type of int2
comm.appendByte((byte)3);
// type of int4
comm.appendByte((byte)1);
// type of char
comm.appendByte((byte)6);
// type of flt
comm.appendByte((byte)10);
// type of date
comm.appendByte((byte)9);
// notify of use db
comm.appendByte((byte)1);
// disallow dump/load and bulk insert
comm.appendByte((byte)1);
// sql interface type
comm.appendByte((byte)0);
// type of network connection
comm.appendByte((byte)0);
// spare[7]
comm.appendBytes(empty, 7, pad);
// appname
tmp = encoder.getBytes(appName);
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// server name
tmp = encoder.getBytes(serverName);
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// remote passwords
comm.appendBytes(empty, 2, pad);
tmp = encoder.getBytes(password);
comm.appendBytes(tmp, 253, pad);
comm.appendByte((byte)(tmp.length < 253 ? tmp.length+2 : 253+2));
// tds version
comm.appendByte((byte)4);
comm.appendByte((byte)2);
comm.appendByte((byte)0);
comm.appendByte((byte)0);
// prog name
tmp = encoder.getBytes(progName);
comm.appendBytes(tmp, 10, pad);
comm.appendByte((byte)(tmp.length < 10 ? tmp.length : 10));
// prog version
comm.appendByte((byte) 6); // Tell the server we can handle SQLServer version 6
comm.appendByte((byte) 0); // Send zero to tell the server we can't handle any other version
comm.appendByte((byte) 0);
comm.appendByte((byte) 0);
// auto convert short
comm.appendByte((byte)0);
// type of flt4
comm.appendByte((byte)0x0D);
// type of date4
comm.appendByte((byte)0x11);
// language
tmp = encoder.getBytes("us_english");
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// notify on lang change
comm.appendByte((byte)1);
// security label hierachy
comm.appendShort((short)0);
// security components
comm.appendBytes(empty, 8, pad);
// security spare
comm.appendShort((short)0);
// security login role
comm.appendByte((byte)0);
// charset
tmp = encoder.getBytes(charset);
comm.appendBytes(tmp, 30, pad);
comm.appendByte((byte)(tmp.length < 30 ? tmp.length : 30));
// notify on charset change
comm.appendByte((byte)1);
// length of tds packets
tmp = encoder.getBytes("512");
comm.appendBytes(tmp, 6, pad);
comm.appendByte((byte)3);
// pad out to a longword
comm.appendBytes(empty, 8, pad);
moreResults2=true; //JJ 1999-01-10
}
comm.sendPacket();
// Get the reply to the logon packet.
PacketResult result;
while (! ((result = processSubPacket()) instanceof PacketEndTokenResult))
{
if (result instanceof PacketErrorResult)
{
isOkay = false;
}
// XXX Should really process some more types of packets.
}
if (isOkay)
{
// XXX Should we move this to the Connection class?
isOkay = changeSettings(database, initialSettings);
}
// XXX Possible bug. What happend if this is cancelled before the logon
// takes place? Should isOkay be false?
return isOkay;
}
/*
* New code added to handle TDS 7.0 login, which uses a completely
* different packet layout. Logic taken directly from freetds C
* code in tds/login.c. Lots of magic values: I don't pretend
* to have any idea what most of this means.
*
* Added 2000-06-05.
*/
private void send70Login() throws java.io.IOException {
byte[] magic1 = {(byte)0006, (byte)0203, (byte)0362, (byte)0370,
(byte)0377, (byte)0000, (byte)0000, (byte)0000,
(byte)0000, (byte)0340, (byte)0003, (byte)0000,
(byte)0000, (byte)0210, (byte)0377, (byte)0377,
(byte)0377, (byte)0066, (byte)0004, (byte)0000,
(byte)0000};
byte[] magic2 = {(byte)0000, (byte)0100, (byte)0063, (byte)0232,
(byte)0153, (byte)0120};
byte[] magic3 = encoder.getBytes("NTLMSSP");
String libName = "DB-Library";
byte pad = (byte)0;
byte[] empty = new byte[0];
String appName = "CDR";
short len = (short)(86 + 2 * (user.length() +
password.length() +
appName.length() +
serverName.length() +
libName.length()));
short packSize = (short)(len + 48);
comm.startPacket(TdsComm.LOGON70);
comm.appendTdsShort(packSize);
comm.appendBytes(empty, 5, pad);
comm.appendByte((byte)0x70);
comm.appendBytes(empty, 7, pad);
comm.appendBytes(magic1, 21, pad);
// Pack up value lengths, positions.
short curPos = 86;
// Unknown
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)0);
// Username
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)user.length());
curPos += user.length() * 2;
// Password
comm.appendTdsShort(curPos);
comm.appendTdsShort((short)password.length());
curPos += password.length() * 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -