Пример #1
1
 @Override
 public Value createBlob(InputStream in, long maxLength) {
   init();
   int type = Value.BLOB;
   if (maxLength < 0) {
     maxLength = Long.MAX_VALUE;
   }
   int max = (int) Math.min(maxLength, database.getMaxLengthInplaceLob());
   try {
     if (max != 0 && max < Integer.MAX_VALUE) {
       BufferedInputStream b = new BufferedInputStream(in, max);
       b.mark(max);
       byte[] small = new byte[max];
       int len = IOUtils.readFully(b, small, max);
       if (len < max) {
         if (len < small.length) {
           small = Arrays.copyOf(small, len);
         }
         return ValueLobDb.createSmallLob(type, small);
       }
       b.reset();
       in = b;
     }
     if (maxLength != Long.MAX_VALUE) {
       in = new LimitInputStream(in, maxLength);
     }
     return createLob(in, type);
   } catch (IllegalStateException e) {
     throw DbException.get(ErrorCode.OBJECT_CLOSED, e);
   } catch (IOException e) {
     throw DbException.convertIOException(e, null);
   }
 }
Пример #2
0
 @Override
 public Value convertPrecision(long precision, boolean force) {
   if (this.precision <= precision) {
     return this;
   }
   ValueLobDb lob;
   if (type == CLOB) {
     if (handler == null) {
       try {
         int p = MathUtils.convertLongToInt(precision);
         String s = IOUtils.readStringAndClose(getReader(), p);
         byte[] data = s.getBytes(Constants.UTF8);
         lob = ValueLobDb.createSmallLob(type, data, s.length());
       } catch (IOException e) {
         throw DbException.convertIOException(e, null);
       }
     } else {
       lob = ValueLobDb.createTempClob(getReader(), precision, handler);
     }
   } else {
     if (handler == null) {
       try {
         int p = MathUtils.convertLongToInt(precision);
         byte[] data = IOUtils.readBytesAndClose(getInputStream(), p);
         lob = ValueLobDb.createSmallLob(type, data, data.length);
       } catch (IOException e) {
         throw DbException.convertIOException(e, null);
       }
     } else {
       lob = ValueLobDb.createTempBlob(getInputStream(), precision, handler);
     }
   }
   return lob;
 }
Пример #3
0
  private void testCastTrim() {
    Value v;
    String spaces = new String(new char[100]).replace((char) 0, ' ');

    v = ValueArray.get(new Value[] {ValueString.get("hello"), ValueString.get("world")});
    assertEquals(10, v.getPrecision());
    assertEquals(5, v.convertPrecision(5, true).getPrecision());
    v = ValueArray.get(new Value[] {ValueString.get(""), ValueString.get("")});
    assertEquals(0, v.getPrecision());
    assertEquals("('')", v.convertPrecision(1, true).toString());

    v = ValueBytes.get(spaces.getBytes());
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getBytes().length);
    assertEquals(32, v.convertPrecision(10, false).getBytes()[9]);
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    final Value vd = ValueDecimal.get(new BigDecimal("1234567890.123456789"));
    assertEquals(19, vd.getPrecision());
    assertEquals("1234567890.1234567", vd.convertPrecision(10, true).getString());
    new AssertThrows(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1) {
      @Override
      public void test() {
        vd.convertPrecision(10, false);
      }
    };

    v = ValueLobDb.createSmallLob(Value.CLOB, spaces.getBytes(), 100);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getString().length());
    assertEquals("          ", v.convertPrecision(10, false).getString());
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    v = ValueLobDb.createSmallLob(Value.BLOB, spaces.getBytes(), 100);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getBytes().length);
    assertEquals(32, v.convertPrecision(10, false).getBytes()[9]);
    assertEquals(10, v.convertPrecision(10, true).getPrecision());

    ResultSet rs = new SimpleResultSet();
    v = ValueResultSet.get(rs);
    assertEquals(Integer.MAX_VALUE, v.getPrecision());
    assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, false).getPrecision());
    assertTrue(rs == v.convertPrecision(10, false).getObject());
    assertFalse(rs == v.convertPrecision(10, true).getObject());
    assertEquals(Integer.MAX_VALUE, v.convertPrecision(10, true).getPrecision());

    v = ValueString.get(spaces);
    assertEquals(100, v.getPrecision());
    assertEquals(10, v.convertPrecision(10, false).getPrecision());
    assertEquals("          ", v.convertPrecision(10, false).getString());
    assertEquals("          ", v.convertPrecision(10, true).getString());
  }
Пример #4
0
 /**
  * Create a temporary BLOB value from a stream.
  *
  * @param in the input stream
  * @param length the number of characters to read, or -1 for no limit
  * @param handler the data handler
  * @return the lob value
  */
 public static ValueLobDb createTempBlob(InputStream in, long length, DataHandler handler) {
   try {
     long remaining = Long.MAX_VALUE;
     boolean compress = handler.getLobCompressionAlgorithm(Value.BLOB) != null;
     if (length >= 0 && length < remaining) {
       remaining = length;
     }
     int len = getBufferSize(handler, compress, remaining);
     byte[] buff;
     if (len >= Integer.MAX_VALUE) {
       buff = IOUtils.readBytesAndClose(in, -1);
       len = buff.length;
     } else {
       buff = DataUtils.newBytes(len);
       len = IOUtils.readFully(in, buff, len);
     }
     if (len <= handler.getMaxLengthInplaceLob()) {
       byte[] small = DataUtils.newBytes(len);
       System.arraycopy(buff, 0, small, 0, len);
       return ValueLobDb.createSmallLob(Value.BLOB, small, small.length);
     }
     ValueLobDb lob = new ValueLobDb(handler, buff, len, in, remaining);
     return lob;
   } catch (IOException e) {
     throw DbException.convertIOException(e, null);
   }
 }
Пример #5
0
 /**
  * Create a temporary CLOB value from a stream.
  *
  * @param in the reader
  * @param length the number of characters to read, or -1 for no limit
  * @param handler the data handler
  * @return the lob value
  */
 public static ValueLobDb createTempClob(Reader in, long length, DataHandler handler) {
   BufferedReader reader;
   if (in instanceof BufferedReader) {
     reader = (BufferedReader) in;
   } else {
     reader = new BufferedReader(in, Constants.IO_BUFFER_SIZE);
   }
   try {
     boolean compress = handler.getLobCompressionAlgorithm(Value.CLOB) != null;
     long remaining = Long.MAX_VALUE;
     if (length >= 0 && length < remaining) {
       remaining = length;
     }
     int len = getBufferSize(handler, compress, remaining);
     char[] buff;
     if (len >= Integer.MAX_VALUE) {
       String data = IOUtils.readStringAndClose(reader, -1);
       buff = data.toCharArray();
       len = buff.length;
     } else {
       buff = new char[len];
       reader.mark(len);
       len = IOUtils.readFully(reader, buff, len);
     }
     if (len <= handler.getMaxLengthInplaceLob()) {
       byte[] small = new String(buff, 0, len).getBytes(Constants.UTF8);
       return ValueLobDb.createSmallLob(Value.CLOB, small, len);
     }
     reader.reset();
     ValueLobDb lob = new ValueLobDb(handler, reader, remaining);
     return lob;
   } catch (IOException e) {
     throw DbException.convertIOException(e, null);
   }
 }
Пример #6
0
 /**
  * Convert a lob to another data type. The data is fully read in memory except when converting to
  * BLOB or CLOB.
  *
  * @param t the new type
  * @return the converted value
  */
 @Override
 public Value convertTo(int t) {
   if (t == type) {
     return this;
   } else if (t == Value.CLOB) {
     if (handler != null) {
       Value copy = handler.getLobStorage().createClob(getReader(), -1);
       return copy;
     } else if (small != null) {
       return ValueLobDb.createSmallLob(t, small);
     }
   } else if (t == Value.BLOB) {
     if (handler != null) {
       Value copy = handler.getLobStorage().createBlob(getInputStream(), -1);
       return copy;
     } else if (small != null) {
       return ValueLobDb.createSmallLob(t, small);
     }
   }
   return super.convertTo(t);
 }
Пример #7
0
 @Override
 public Value createClob(Reader reader, long maxLength) {
   init();
   int type = Value.CLOB;
   if (maxLength < 0) {
     maxLength = Long.MAX_VALUE;
   }
   int max = (int) Math.min(maxLength, database.getMaxLengthInplaceLob());
   try {
     if (max != 0 && max < Integer.MAX_VALUE) {
       BufferedReader b = new BufferedReader(reader, max);
       b.mark(max);
       char[] small = new char[max];
       int len = IOUtils.readFully(b, small, max);
       if (len < max) {
         if (len < small.length) {
           small = Arrays.copyOf(small, len);
         }
         byte[] utf8 = new String(small, 0, len).getBytes(Constants.UTF8);
         return ValueLobDb.createSmallLob(type, utf8);
       }
       b.reset();
       reader = b;
     }
     CountingReaderInputStream in = new CountingReaderInputStream(reader, maxLength);
     ValueLobDb lob = createLob(in, type);
     // the length is not correct
     lob =
         ValueLobDb.create(type, database, lob.getTableId(), lob.getLobId(), null, in.getLength());
     return lob;
   } catch (IllegalStateException e) {
     throw DbException.get(ErrorCode.OBJECT_CLOSED, e);
   } catch (IOException e) {
     throw DbException.convertIOException(e, null);
   }
 }
Пример #8
0
 /**
  * Read a value.
  *
  * @return the value
  */
 public Value readValue() {
   int type = data[pos++] & 255;
   switch (type) {
     case Value.NULL:
       return ValueNull.INSTANCE;
     case BOOLEAN_TRUE:
       return ValueBoolean.get(true);
     case BOOLEAN_FALSE:
       return ValueBoolean.get(false);
     case INT_NEG:
       return ValueInt.get(-readVarInt());
     case Value.INT:
       return ValueInt.get(readVarInt());
     case LONG_NEG:
       return ValueLong.get(-readVarLong());
     case Value.LONG:
       return ValueLong.get(readVarLong());
     case Value.BYTE:
       return ValueByte.get(readByte());
     case Value.SHORT:
       return ValueShort.get(readShortInt());
     case DECIMAL_0_1:
       return (ValueDecimal) ValueDecimal.ZERO;
     case DECIMAL_0_1 + 1:
       return (ValueDecimal) ValueDecimal.ONE;
     case DECIMAL_SMALL_0:
       return ValueDecimal.get(BigDecimal.valueOf(readVarLong()));
     case DECIMAL_SMALL:
       {
         int scale = readVarInt();
         return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale));
       }
     case Value.DECIMAL:
       {
         int scale = readVarInt();
         int len = readVarInt();
         byte[] buff = DataUtils.newBytes(len);
         read(buff, 0, len);
         BigInteger b = new BigInteger(buff);
         return ValueDecimal.get(new BigDecimal(b, scale));
       }
     case LOCAL_DATE:
       {
         return ValueDate.fromDateValue(readVarLong());
       }
     case Value.DATE:
       {
         long x = readVarLong() * MILLIS_PER_MINUTE;
         return ValueDate.get(new Date(DateTimeUtils.getTimeUTCWithoutDst(x)));
       }
     case LOCAL_TIME:
       {
         long nanos = readVarLong() * 1000000 + readVarLong();
         return ValueTime.fromNanos(nanos);
       }
     case Value.TIME:
       // need to normalize the year, month and day
       return ValueTime.get(new Time(DateTimeUtils.getTimeUTCWithoutDst(readVarLong())));
     case LOCAL_TIMESTAMP:
       {
         long dateValue = readVarLong();
         long nanos = readVarLong() * 1000000 + readVarLong();
         return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
       }
     case Value.TIMESTAMP:
       {
         Timestamp ts = new Timestamp(DateTimeUtils.getTimeUTCWithoutDst(readVarLong()));
         ts.setNanos(readVarInt());
         return ValueTimestamp.get(ts);
       }
     case Value.BYTES:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueBytes.getNoCopy(b);
       }
     case Value.GEOMETRY:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueGeometry.get(b);
       }
     case Value.JAVA_OBJECT:
       {
         int len = readVarInt();
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueJavaObject.getNoCopy(null, b, handler);
       }
     case Value.UUID:
       return ValueUuid.get(readLong(), readLong());
     case Value.STRING:
       return ValueString.get(readString());
     case Value.STRING_IGNORECASE:
       return ValueStringIgnoreCase.get(readString());
     case Value.STRING_FIXED:
       return ValueStringFixed.get(readString());
     case FLOAT_0_1:
       return ValueFloat.get(0);
     case FLOAT_0_1 + 1:
       return ValueFloat.get(1);
     case DOUBLE_0_1:
       return ValueDouble.get(0);
     case DOUBLE_0_1 + 1:
       return ValueDouble.get(1);
     case Value.DOUBLE:
       return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong())));
     case Value.FLOAT:
       return ValueFloat.get(Float.intBitsToFloat(Integer.reverse(readVarInt())));
     case Value.BLOB:
     case Value.CLOB:
       {
         int smallLen = readVarInt();
         if (smallLen >= 0) {
           byte[] small = DataUtils.newBytes(smallLen);
           read(small, 0, smallLen);
           return ValueLobDb.createSmallLob(type, small);
         } else if (smallLen == -3) {
           int tableId = readVarInt();
           long lobId = readVarLong();
           long precision = readVarLong();
           ValueLobDb lob = ValueLobDb.create(type, handler, tableId, lobId, null, precision);
           return lob;
         } else {
           int tableId = readVarInt();
           int objectId = readVarInt();
           long precision = 0;
           boolean compression = false;
           // -1: regular; -2: regular, but not linked (in this case:
           // including file name)
           if (smallLen == -1 || smallLen == -2) {
             precision = readVarLong();
             compression = readByte() == 1;
           }
           if (smallLen == -2) {
             String filename = readString();
             return ValueLob.openUnlinked(
                 type, handler, tableId, objectId, precision, compression, filename);
           }
           return ValueLob.openLinked(type, handler, tableId, objectId, precision, compression);
         }
       }
     case Value.ARRAY:
       {
         int len = readVarInt();
         Value[] list = new Value[len];
         for (int i = 0; i < len; i++) {
           list[i] = readValue();
         }
         return ValueArray.get(list);
       }
     case Value.RESULT_SET:
       {
         SimpleResultSet rs = new SimpleResultSet();
         rs.setAutoClose(false);
         int columns = readVarInt();
         for (int i = 0; i < columns; i++) {
           rs.addColumn(readString(), readVarInt(), readVarInt(), readVarInt());
         }
         while (true) {
           if (readByte() == 0) {
             break;
           }
           Object[] o = new Object[columns];
           for (int i = 0; i < columns; i++) {
             o[i] = readValue().getObject();
           }
           rs.addRow(o);
         }
         return ValueResultSet.get(rs);
       }
     default:
       if (type >= INT_0_15 && type < INT_0_15 + 16) {
         return ValueInt.get(type - INT_0_15);
       } else if (type >= LONG_0_7 && type < LONG_0_7 + 8) {
         return ValueLong.get(type - LONG_0_7);
       } else if (type >= BYTES_0_31 && type < BYTES_0_31 + 32) {
         int len = type - BYTES_0_31;
         byte[] b = DataUtils.newBytes(len);
         read(b, 0, len);
         return ValueBytes.getNoCopy(b);
       } else if (type >= STRING_0_31 && type < STRING_0_31 + 32) {
         return ValueString.get(readString(type - STRING_0_31));
       }
       throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type);
   }
 }