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

📄 tds.java

📁 数据仓库工具
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
         {
            throw new TdsException("Not fixed size column "
               + nativeColumnType);
         }
      }
   } // lookupColumnSize()



   /**
    * 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 com.internetcds.jdbc.tds.TdsException
    * If the <code>nativeColumnType</code> is not a knowm datatype.
    *
    */
   private boolean isFixedSizeColumn(byte nativeColumnType)
      throws com.internetcds.jdbc.tds.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:
         {
            return false;
         }
         default:
         {
            throw new TdsException("Unrecognized column type 0x"
                                   + Integer.toHexString(nativeColumnType));
         }
      }
   }


   private Object readFloatN(int len)
      throws TdsException, java.io.IOException
   {
      Object   tmp;

      switch (len)
      {
         case 8:
         {
            long  l = comm.getTdsInt64();
            tmp = new Double(Double.longBitsToDouble(l));
            break;
         }
         case 4:
         {
            int   i = comm.getTdsInt();
            tmp = new Float(Float.intBitsToFloat(i));
            break;
         }
         case 0:
         {
            tmp = null;
            break;
         }
         default:
         {
            throw new TdsNotImplemented("Don't now how to handle "
                                        + "float with size of "
                                        + len
                                        + "(0x"
                                        + Integer.toHexString(len & 0xff)
                                        + ")");
         }
      }
      return tmp;
   }


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

      if (type == SYBMONEYN)
      {
         len = comm.getByte();
      }
      else
      {
         len = lookupColumnSize((byte)type);
      }

      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).
    */
   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.
    */
   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
   {
      Object   result;
      int      len;

      switch (type)
      {
         case SYBINTN:
         {
            len = comm.getByte();
            break;
         }
         case SYBINT4:
         {
            len = 4;
            break;
         }
         case SYBINT2:
         {
            len = 2;
            break;
         }
         case SYBINT1:
         {
            len = 1;
            break;
         }
         default:
         {
            result = null;
            throw new TdsNotImplemented(
               "can't handle integer of type "
               + Integer.toHexString(type));
         }
      }

      switch (len)
      {
         case 4: {result = new Long(comm.getTdsInt());             break;}
         case 2: {result = new Long(comm.getTdsShort());           break;}
         case 1: 
         {
            int tmp = toUInt(comm.getByte()); // XXX Are we sure this should be unsigned?
            result  = new Long(tmp);
            break;
         }
         case 0: 
         {
            result = null;    
            break;
         }
         default:
         {
            result = null;
            throw new TdsConfused("Bad SYBINTN length of " +
                                  len);
         }
      }
      return result;
   } // getIntValue()


   private Object getCharValue(boolean wideChars)
      throws TdsException, java.io.IOException
   {
      Object result;
      int     len = tdsVer == Tds.TDS70 ? comm.getTdsShort() : comm.getByte() & 0xFF;

      if (len == 0 || tdsVer == Tds.TDS70 && len == 0xFFFF)
      {
         result = null;
      }
      else if (len > 0)
      {
         if (wideChars)
            result = comm.getString(len / 2);
         else
            result = encoder.getString(comm.getBytes(len));

         if (result.equals(" "))
         {
            // In SQL trailing spaces are stripped from strings
            // MS SQLServer denotes a zero length string
            // as a single space.
            result = "";
         }
      }
      else
      {
         throw new TdsConfused("String with length<0");
      }
      return result;
   } // getCharValue()

   private Object getTextValue(boolean wideChars)
      throws TdsException, java.io.IOException
   {
      String  result;

      byte   hasValue = comm.getByte();

      if (hasValue==0)
      {
         result = null;
      }
      else
      {
         // XXX Have no idea what these 24 bytes are
         // 2000-06-06 RMK They are the TEXTPTR (16 bytes) and the TIMESTAMP.
         comm.skip(24);

         int     len = comm.getTdsInt();

         // RMK 2000-06-11
         // The logic immediately below does not agree with test t0031, 
         // so I'm commenting it out.  On the other hand, it's a bit
         // puzzling that a column defined as TEXT NOT NULL needs the 
         // hasValue byte read just above, but apparently it does.
         //if (len == 0)
         //{
         //   result = null;
         //}
         //else
         if (len >= 0)
         {
            if (wideChars) {
               result = comm.getString(len / 2);
            } else {
               result 

⌨️ 快捷键说明

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