tdsdata.java

来自「jtds的源码 是你学习java的好东西」· Java 代码 · 共 1,539 行 · 第 1/5 页

JAVA
1,539
字号

            for (i = 0; i < 5; ++i) {
                if (collation[i] != defaultCollation[i]) {
                    break;
                }
            }

            if (i == 5) {
                ci.charsetInfo = connection.getCharsetInfo();
            } else {
                ci.charsetInfo = CharsetInfo.getCharset(collation);
            }
        }
    }

    /**
     * Read the TDS datastream and populate the ColInfo parameter with
     * data type and related information.
     * <p>The type infomation conforms to one of the following formats:
     * <ol>
     * <li> [int1 type]  - eg SYBINT4.
     * <li> [int1 type] [int1 buffersize]  - eg VARCHAR &lt; 256
     * <li> [int1 type] [int2 buffersize]  - eg VARCHAR &gt; 255.
     * <li> [int1 type] [int4 buffersize] [int1 tabnamelen] [int1*n tabname] - eg text.
     * <li> [int1 type] [int4 buffersize] - eg sql_variant.
     * <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 {
        int tdsVersion = in.getTdsVersion();
        boolean isTds8 = tdsVersion >= Driver.TDS80;
        boolean isTds7 = tdsVersion >= Driver.TDS70;
        boolean isTds5 = tdsVersion == Driver.TDS50;
        boolean isTds42 = tdsVersion == Driver.TDS42;
        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;
                // Establish actual size of nullable unsigned int
            case SYBUINTN:
                if (ci.bufferSize == 8) {
                    ci.displaySize = types[SYBUINT8].displaySize;
                    ci.precision   = types[SYBUINT8].precision;
                    ci.jdbcType    = types[SYBUINT8].jdbcType;
                    ci.sqlType     = types[SYBUINT8].sqlType;
                } else if (ci.bufferSize == 4) {
                    ci.displaySize = types[SYBUINT4].displaySize;
                    ci.precision   = types[SYBUINT4].precision;
                } else if (ci.bufferSize == 2) {
                    ci.displaySize = types[SYBUINT2].displaySize;
                    ci.precision   = types[SYBUINT2].precision;
                    ci.jdbcType    = types[SYBUINT2].jdbcType;
                    ci.sqlType     = types[SYBUINT2].sqlType;
                } else {
                    throw new ProtocolException("unsigned int null (size 1) not supported");
                }
                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;
                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;

            // ASE 15+ unicode text can only display half as many chars
            case SYBUNITEXT:
                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;
                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;
                break;
        }

        // For numeric types add 'identity' for auto inc data type
        if (ci.isIdentity) {
            ci.sqlType += " identity";
        }
        
        // Fine tune Sybase or SQL 6.5 data types
        if (isTds42 || isTds5) {
            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_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_SYSNAME:
                    ci.sqlType = "sysname";
                    ci.displaySize = ci.bufferSize;
                    ci.jdbcType    = java.sql.Types.VARCHAR;
                    break;
                case UDT_TIMESTAMP:
                    ci.sqlType = "timestamp";
                    ci.displaySize = ci.bufferSize * 2;
                    ci.jdbcType    = java.sql.Types.VARBINARY;
                    break;
            }
        }
        
        // Fine tune Sybase data types
        if (isTds5) {
            switch (ci.userType) {
                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;
                case UDT_UNICHAR:
                    ci.sqlType     = "unichar";
                    ci.displaySize = ci.bufferSize / 2;
                    ci.precision   = ci.displaySize;
                    ci.jdbcType    = java.sql.Types.CHAR;
                    break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?