📄 tdsdata.java
字号:
* <li> [int1 type] [int1 buffersize] [int1 precision] [int1 scale] - eg decimal.
* </ol>
* For TDS 8 large character types include a 5 byte collation field after the buffer size.
*
* @param in The server response stream.
* @param ci The ColInfo column descriptor object.
* @return The number of bytes read from the input stream.
* @throws IOException
* @throws ProtocolException
*/
static int readType(ResponseStream in, ColInfo ci)
throws IOException, ProtocolException {
boolean isTds8 = in.getTdsVersion() >= Driver.TDS80;
boolean isTds5 = in.getTdsVersion() == Driver.TDS50;
int bytesRead = 1;
// Get the TDS data type code
int type = in.read();
if (types[type] == null || (isTds5 && type == SYBLONGDATA)) {
// Trap invalid type or 0x24 received from a Sybase server!
throw new ProtocolException("Invalid TDS data type 0x" + Integer.toHexString(type & 0xFF));
}
ci.tdsType = type;
ci.jdbcType = types[type].jdbcType;
ci.bufferSize = types[type].size;
// Now get the buffersize if required
if (ci.bufferSize == -5) {
// sql_variant
// Sybase long binary
ci.bufferSize = in.readInt();
bytesRead += 4;
} else if (ci.bufferSize == -4) {
// text or image
ci.bufferSize = in.readInt();
if (isTds8) {
bytesRead += getCollation(in, ci);
}
int lenName = in.readShort();
ci.tableName = in.readString(lenName);
bytesRead += 6 + ((in.getTdsVersion() >= Driver.TDS70) ? lenName * 2 : lenName);
} else if (ci.bufferSize == -2) {
// longvarchar longvarbinary
if (isTds5 && ci.tdsType == XSYBCHAR) {
ci.bufferSize = in.readInt();
bytesRead += 4;
} else {
ci.bufferSize = in.readShort();
bytesRead += 2;
}
if (isTds8) {
bytesRead += getCollation(in, ci);
}
} else if (ci.bufferSize == -1) {
// varchar varbinary decimal etc
bytesRead += 1;
ci.bufferSize = in.read();
}
// Set default displaySize and precision
ci.displaySize = types[type].displaySize;
ci.precision = types[type].precision;
ci.sqlType = types[type].sqlType;
// Now fine tune sizes for specific types
switch (type) {
//
// long datetime has scale of 3 smalldatetime has scale of 0
//
case SYBDATETIME:
ci.scale = 3;
break;
// Establish actual size of nullable datetime
case SYBDATETIMN:
if (ci.bufferSize == 8) {
ci.displaySize = types[SYBDATETIME].displaySize;
ci.precision = types[SYBDATETIME].precision;
ci.scale = 3;
} else {
ci.displaySize = types[SYBDATETIME4].displaySize;
ci.precision = types[SYBDATETIME4].precision;
ci.sqlType = types[SYBDATETIME4].sqlType;
ci.scale = 0;
}
break;
// Establish actual size of nullable float
case SYBFLTN:
if (ci.bufferSize == 8) {
ci.displaySize = types[SYBFLT8].displaySize;
ci.precision = types[SYBFLT8].precision;
} else {
ci.displaySize = types[SYBREAL].displaySize;
ci.precision = types[SYBREAL].precision;
ci.jdbcType = java.sql.Types.REAL;
ci.sqlType = types[SYBREAL].sqlType;
}
break;
// Establish actual size of nullable int
case SYBINTN:
if (ci.bufferSize == 8) {
ci.displaySize = types[SYBINT8].displaySize;
ci.precision = types[SYBINT8].precision;
ci.jdbcType = java.sql.Types.BIGINT;
ci.sqlType = types[SYBINT8].sqlType;
} else if (ci.bufferSize == 4) {
ci.displaySize = types[SYBINT4].displaySize;
ci.precision = types[SYBINT4].precision;
} else if (ci.bufferSize == 2) {
ci.displaySize = types[SYBINT2].displaySize;
ci.precision = types[SYBINT2].precision;
ci.jdbcType = java.sql.Types.SMALLINT;
ci.sqlType = types[SYBINT2].sqlType;
} else {
ci.displaySize = types[SYBINT1].displaySize;
ci.precision = types[SYBINT1].precision;
ci.jdbcType = java.sql.Types.TINYINT;
ci.sqlType = types[SYBINT1].sqlType;
}
break;
//
// Money types have a scale of 4
//
case SYBMONEY:
case SYBMONEY4:
ci.scale = 4;
break;
// Establish actual size of nullable money
case SYBMONEYN:
if (ci.bufferSize == 8) {
ci.displaySize = types[SYBMONEY].displaySize;
ci.precision = types[SYBMONEY].precision;
} else {
ci.displaySize = types[SYBMONEY4].displaySize;
ci.precision = types[SYBMONEY4].precision;
ci.sqlType = types[SYBMONEY4].sqlType;
}
ci.scale = 4;
break;
// Read in scale and precision for decimal types
case SYBDECIMAL:
case SYBNUMERIC:
ci.precision = in.read();
ci.scale = in.read();
ci.displaySize = ((ci.scale > 0) ? 2 : 1) + ci.precision;
bytesRead += 2;
ci.sqlType = types[type].sqlType;
break;
// Although a binary type force displaysize to MAXINT
case SYBIMAGE:
ci.precision = Integer.MAX_VALUE;
ci.displaySize = Integer.MAX_VALUE;
break;
// Normal binaries have a display size of 2 * precision 0x0A0B etc
case SYBLONGBINARY:
case SYBVARBINARY:
case SYBBINARY:
case XSYBBINARY:
case XSYBVARBINARY:
ci.precision = ci.bufferSize;
ci.displaySize = ci.precision * 2;
if (ci.userType == UDT_TIMESTAMP) {
// Look for system defined timestamp type
ci.sqlType = "timestamp";
}
break;
// SQL Server unicode text can only display half as many chars
case SYBNTEXT:
ci.precision = Integer.MAX_VALUE / 2;
ci.displaySize = Integer.MAX_VALUE / 2;
break;
// SQL Server unicode chars can only display half as many chars
case XSYBNCHAR:
case XSYBNVARCHAR:
ci.displaySize = ci.bufferSize / 2;
ci.precision = ci.displaySize;
if (ci.userType == UDT_NEWSYSNAME) {
// Look for SQL Server 7+ version of sysname
ci.sqlType = "sysname";
}
break;
// Normal characters display size = precision = buffer size.
case SYBTEXT:
case SYBCHAR:
case XSYBCHAR:
case XSYBVARCHAR:
case SYBVARCHAR:
case SYBNVARCHAR:
ci.precision = ci.bufferSize;
ci.displaySize = ci.precision;
if (ci.userType == UDT_SYSNAME) {
// Look for SQL 6.5 or Sybase version of sysname
ci.sqlType = "sysname";
}
break;
}
// For numeric types add 'identity' for auto inc data type
if (ci.isIdentity) {
ci.sqlType += " identity";
}
// Fine tune Sybase data types
if (isTds5) {
if (ci.tdsType == SYBLONGBINARY) {
switch (ci.userType) {
case UDT_BINARY:
ci.sqlType = "binary";
ci.displaySize = ci.bufferSize * 2;
ci.jdbcType = java.sql.Types.BINARY;
break;
case UDT_VARBINARY:
ci.sqlType = "varbinary";
ci.displaySize = ci.bufferSize * 2;
ci.jdbcType = java.sql.Types.VARBINARY;
break;
case UDT_UNICHAR:
ci.sqlType = "unichar";
ci.displaySize = ci.bufferSize / 2;
ci.precision = ci.displaySize;
ci.jdbcType = java.sql.Types.CHAR;
break;
case UDT_UNIVARCHAR:
ci.sqlType = "univarchar";
ci.displaySize = ci.bufferSize / 2;
ci.precision = ci.displaySize;
ci.jdbcType = java.sql.Types.VARCHAR;
break;
}
} else
if (ci.tdsType == XSYBCHAR) {
switch (ci.userType) {
case UDT_CHAR:
ci.sqlType = "char";
ci.displaySize = ci.bufferSize;
ci.jdbcType = java.sql.Types.CHAR;
break;
case UDT_VARCHAR:
ci.sqlType = "varchar";
ci.displaySize = ci.bufferSize;
ci.jdbcType = java.sql.Types.VARCHAR;
break;
case UDT_NCHAR:
ci.sqlType = "nchar";
ci.displaySize = ci.bufferSize;
ci.jdbcType = java.sql.Types.CHAR;
break;
case UDT_NVARCHAR:
ci.sqlType = "nvarchar";
ci.displaySize = ci.bufferSize;
ci.jdbcType = java.sql.Types.VARCHAR;
break;
}
}
}
return bytesRead;
}
/**
* Read the TDS data item from the Response Stream.
* <p> The data size is either implicit in the type for example
* fixed size integers, or a count field precedes the actual data.
* The size of the count field varies with the data type.
*
* @param connection an object reference to the caller of this method;
* must be a <code>Connection</code>, <code>Statement</code> or
* <code>ResultSet</code>
* @param in The server ResponseStream.
* @param ci The ColInfo column descriptor object.
* @return The data item Object or null.
* @throws IOException
* @throws ProtocolException
*/
static Object readData(ConnectionJDBC2 connection, ResponseStream in, ColInfo ci)
throws IOException, ProtocolException {
int len;
switch (ci.tdsType) {
case SYBINTN:
switch (in.read()) {
case 1:
return new Integer(in.read() & 0xFF);
case 2:
return new Integer(in.readShort());
case 4:
return new Integer(in.readInt());
case 8:
return new Long(in.readLong());
}
break;
case SYBINT1:
return new Integer(in.read() & 0xFF);
case SYBINT2:
return new Integer(in.readShort());
case SYBINT4:
return new Integer(in.readInt());
case SYBINT8:
return new Long(in.readLong());
case SYBIMAGE:
len = in.read();
if (len > 0) {
BlobImpl blob;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -