⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tds.java

📁 Java写的TDS协议(JDBC/ODBC)实现
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            case TDS_ORDER:
            {
                int len = comm.getTdsShort();
                comm.skip(len);

                result = new PacketColumnOrderResult();
                break;
            }
            case TDS_CONTROL:
            {
                int len = comm.getTdsShort();
                comm.skip(len);
                // FIXME - I'm just ignoring this
                result = new PacketControlResult();
                break;
            }
            case TDS_ROW:
            {
                result = getRow(context);
                break;
            }
            case TDS_COLMETADATA:
            {
                result = processTds7Result();
                break;
            }
            default:
            {
                throw new TdsUnknownPacketSubType(packetSubType);
            }
        }

        return result;
    }


    private void setCharset(String charset)
    {
        if (charset == null || charset.length() > 30)
            charset = "iso_1";

        if( charset.startsWith("cp") )
            charset = "Cp" + charset.substring(2);

        if (!charset.equals(this.charset)) {
            encoder = EncodingHelper.getHelper(charset);
            this.charset = charset;
        }
    }


    /**
     *  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();
        }
    }


    /**
     *  Get the length of the current subpacket. <p>
     *
     *  This will eat two bytes from the input socket.
     *
     *@return                                            length of the current
     *      subpacket.
     *@exception  java.io.IOException                    Description of
     *      Exception
     *@exception  net.sourceforge.jtds.jdbc.TdsException  Description of
     *      Exception
     */
    private int getSubPacketLength()
             throws java.io.IOException, net.sourceforge.jtds.jdbc.TdsException
    {
        return comm.getTdsShort();
    }


    /**
     *  determine if a given datatype is a fixed size
     *
     *@param  nativeColumnType                           The SQLServer datatype
     *      to check
     *@return                                            <code>true</code> if
     *      the datatype is a fixed size, <code>false</code> if the datatype is
     *      a variable size
     *@exception  net.sourceforge.jtds.jdbc.TdsException  If the <code>
     *      nativeColumnType</code> is not a knowm datatype.
     */
    private boolean isFixedSizeColumn(byte nativeColumnType)
             throws net.sourceforge.jtds.jdbc.TdsException
    {
        switch (nativeColumnType) {
            case SYBINT1:
            case SYBINT2:
            case SYBINT4:
            case SYBFLT8:
            case SYBDATETIME:
            case SYBBIT:
            case SYBMONEY:
            case SYBMONEY4:
            case SYBSMALLMONEY:
            case SYBREAL:
            case SYBDATETIME4:
            {
                return true;
            }
            case SYBINTN:
            case SYBMONEYN:
            case SYBVARCHAR:
            case SYBNVARCHAR:
            case SYBDATETIMN:
            case SYBFLTN:
            case SYBCHAR:
            case SYBNCHAR:
            case SYBNTEXT:
            case SYBIMAGE:
            case SYBVARBINARY:
            case SYBBINARY:
            case SYBDECIMAL:
            case SYBNUMERIC:
            case SYBBITN:
            case SYBUNIQUEID:
            {
                return false;
            }
            default:
            {
                throw new TdsException("Unrecognized column type 0x"
                         + Integer.toHexString(nativeColumnType));
            }
        }
    }


    private Object getMoneyValue(
            int type)
             throws java.io.IOException, TdsException
    {
        int len;
        Object result;

        switch( type )
        {
            case SYBSMALLMONEY:
            case SYBMONEY4:
                len = 4;
                break;
            case SYBMONEY:
                len = 8;
                break;
            case SYBMONEYN:
                len = comm.getByte();
                break;
            default:
                throw new TdsException("Not a money value.");
        }

        if (len == 0) {
            result = null;
        }
        else {
            BigInteger x = null;

            if (len == 4) {
                x = BigInteger.valueOf(comm.getTdsInt());
            }
            else if (len == 8) {
                byte b4 = comm.getByte();
                byte b5 = comm.getByte();
                byte b6 = comm.getByte();
                byte b7 = comm.getByte();
                byte b0 = comm.getByte();
                byte b1 = comm.getByte();
                byte b2 = comm.getByte();
                byte b3 = comm.getByte();
                long l =
                        (long) (b0 & 0xff) + ((long) (b1 & 0xff) << 8) +
                        ((long) (b2 & 0xff) << 16) + ((long) (b3 & 0xff) << 24) +
                        ((long) (b4 & 0xff) << 32) + ((long) (b5 & 0xff) << 40) +
                        ((long) (b6 & 0xff) << 48) + ((long) (b7 & 0xff) << 56);
                x = BigInteger.valueOf(l);
            }
            else {
                throw new TdsConfused("Don't know what to do with len of "
                         + len);
            }
            x = x.divide(BigInteger.valueOf(100));
            result = new BigDecimal(x, 2);
        }
        return result;
    }
    // getMoneyValue


    /**
     *  Extracts decimal value from the server's results packet. Takes advantage
     *  of Java's superb handling of large numbers, which does all the heavy
     *  lifting for us. Format is:
     *  <UL>
     *    <LI> Length byte <code>len</code> ; count includes sign byte.</LI>
     *
     *    <LI> Sign byte (0=negative; 1=positive).</LI>
     *    <LI> Magnitude bytes (array of <code>len</code> - 1 bytes, in
     *    little-endian order.</LI>
     *  </UL>
     *
     *
     *@param  scale                      number of decimal digits after the
     *      decimal point.
     *@return                            <code>BigDecimal</code> for extracted
     *      value (or ( <code>null</code> if appropriate).
     *@exception  TdsException           Description of Exception
     *@exception  java.io.IOException    Description of Exception
     *@exception  NumberFormatException  Description of Exception
     */
    private Object getDecimalValue(int scale)
             throws TdsException, java.io.IOException, NumberFormatException
    {
        int len = comm.getByte() & 0xff;
        if (--len < 1) {
            return null;
        }

        // RMK 2000-06-10.  Deduced from some testing/packet sniffing.
        byte[] bytes = new byte[len];
        int signum = comm.getByte() == 0 ? -1 : 1;
        while (len > 0) {
            bytes[--len] = comm.getByte();
        }
        BigInteger bigInt = new BigInteger(signum, bytes);
        return new BigDecimal(bigInt, scale);
    }


    private Object getDatetimeValue(
            int type)
             throws java.io.IOException, TdsException
    {
        // Some useful constants
        final long SECONDS_PER_DAY = 24L * 60L * 60L;
        final long DAYS_BETWEEN_1900_AND_1970 = 25567L;

        int len;
        Object result;

        if (type == SYBDATETIMN) {
            len = comm.getByte();
        }
        else if (type == SYBDATETIME4) {
            len = 4;
        }
        else {
            len = 8;
            // XXX shouldn't this be an error?
        }

        switch (len) {
            case 0:
            {
                result = null;
                break;
            }
            case 8:
            {
                // It appears that a datetime is made of of 2 32bit ints
                // The first one is the number of days since 1900
                // The second integer is the number of seconds*300
                // The reason the calculations below are sliced up into
                // such small baby steps is to avoid a bug in JDK1.2.2's
                // runtime, which got confused by the original complexity.
                long tdsDays = (long) comm.getTdsInt();
                long tdsTime = (long) comm.getTdsInt();
                long sqlDays = tdsDays - DAYS_BETWEEN_1900_AND_1970;
                long seconds = sqlDays * SECONDS_PER_DAY + tdsTime / 300L;
                long micros = ((tdsTime % 300L) * 1000000L) / 300L;
                long millis = seconds * 1000L + micros / 1000L - zoneOffset;

                // Round up if appropriate.
                if (micros % 1000L >= 500L) {
                    millis++;
                }

                result = new Timestamp(millis - getDstOffset(millis));
                break;
            }
            case 4:
            {
                // Accroding to Transact SQL Reference
                // a smalldatetime is two small integers.
                // The first is the number of days past January 1, 1900,
                // the second smallint is the number of minutes past
                // midnight.

                long tdsDays = (long) comm.getTdsShort();
                long minutes = (long) comm.getTdsShort();
                long sqlDays = tdsDays - DAYS_BETWEEN_1900_AND_1970;
                long seconds = sqlDays * SECONDS_PER_DAY + minutes * 60L;
                long millis = seconds * 1000L - zoneOffset;

                result = new Timestamp(millis - getDstOffset(millis));
                break;
            }
            default:
            {
                result = null;
                throw new TdsNotImplemented("Don't now how to handle "
                         + "date with size of "
                         + len);
            }
        }
        return result;
    }
    // getDatetimeValue()


    /**
     *  Determines the number of milliseconds needed to adjust for daylight
     *  savings time for a given date/time value. Note that there is a problem
     *  with the way SQL Server sends a DATETIME value, since it is constructed
     *  to represent the local time for the server. This means that each fall
     *  there is a window of approximately one hour during which a single value
     *  can represent two different times.
     *
     * @param  time  Description of Parameter
     * @return       The DstOffset value
     * @todo SAfe Try to find a better way to do this, because it doubles the time it takes to process datetime values!!!
     */
    private long getDstOffset(long time)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new java.util.Date(time));
        return cal.get(Calendar.DST_OFFSET);
    }


    private Object getIntValue(int type)
             throws java.io.IOException, TdsException
    {
        Obje

⌨️ 快捷键说明

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