Beispiel #1
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;
 }
 /**
  * Create a new random xid.
  *
  * @return the new object
  */
 public static SimpleXid createRandom() {
   int formatId = next.getAndIncrement();
   byte[] bq = new byte[MAXBQUALSIZE];
   MathUtils.randomBytes(bq);
   byte[] gt = new byte[MAXGTRIDSIZE];
   MathUtils.randomBytes(gt);
   return new SimpleXid(formatId, bq, gt);
 }
 private void init() throws IOException {
   if (xts != null) {
     return;
   }
   this.size = base.size() - HEADER_LENGTH;
   boolean newFile = size < 0;
   byte[] salt;
   if (newFile) {
     byte[] header = Arrays.copyOf(HEADER, BLOCK_SIZE);
     salt = MathUtils.secureRandomBytes(SALT_LENGTH);
     System.arraycopy(salt, 0, header, SALT_POS, salt.length);
     DataUtils.writeFully(base, 0, ByteBuffer.wrap(header));
     size = 0;
   } else {
     salt = new byte[SALT_LENGTH];
     DataUtils.readFully(base, SALT_POS, ByteBuffer.wrap(salt));
     if ((size & BLOCK_SIZE_MASK) != 0) {
       size -= BLOCK_SIZE;
     }
   }
   AES cipher = new AES();
   cipher.setKey(SHA256.getPBKDF2(encryptionKey, salt, HASH_ITERATIONS, 16));
   encryptionKey = null;
   xts = new XTS(cipher);
 }
Beispiel #4
0
 /**
  * Fill up the buffer with empty space and an (initially empty) checksum until the size is a
  * multiple of Constants.FILE_BLOCK_SIZE.
  */
 public void fillAligned() {
   // 0..6 > 8, 7..14 > 16, 15..22 > 24, ...
   int len = MathUtils.roundUpInt(pos + 2, Constants.FILE_BLOCK_SIZE);
   pos = len;
   if (data.length < len) {
     checkCapacity(len - data.length);
   }
 }
 /**
  * Returns the parameter precision. The value 0 is returned if the precision is not known.
  *
  * @param param the column index (1,2,...)
  * @return the precision
  */
 public int getPrecision(int param) throws SQLException {
   try {
     debugCodeCall("getPrecision", param);
     ParameterInterface p = getParameter(param);
     return MathUtils.convertLongToInt(p.getPrecision());
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
Beispiel #6
0
 private static int getBufferSize(DataHandler handler, boolean compress, long remaining) {
   if (remaining < 0 || remaining > Integer.MAX_VALUE) {
     remaining = Integer.MAX_VALUE;
   }
   int inplace = handler.getMaxLengthInplaceLob();
   long m = compress ? Constants.IO_BUFFER_SIZE_COMPRESS : Constants.IO_BUFFER_SIZE;
   if (m < remaining && m <= inplace) {
     // using "1L" to force long arithmetic because
     // inplace could be Integer.MAX_VALUE
     m = Math.min(remaining, inplace + 1L);
     // the buffer size must be bigger than the inplace lob, otherwise we
     // can't know if it must be stored in-place or not
     m = MathUtils.roundUpLong(m, Constants.IO_BUFFER_SIZE);
   }
   m = Math.min(remaining, m);
   m = MathUtils.convertLongToInt(m);
   if (m < 0) {
     m = Integer.MAX_VALUE;
   }
   return (int) m;
 }
Beispiel #7
0
 /**
  * Compare the positions of two rows.
  *
  * @param rowData the first row
  * @param compare the second row
  * @return 0 if both rows are equal, -1 if the first row is smaller, otherwise 1
  */
 int compareKeys(SearchRow rowData, SearchRow compare) {
   long k1 = rowData.getKey();
   long k2 = compare.getKey();
   if (k1 == k2) {
     if (isMultiVersion) {
       int v1 = rowData.getVersion();
       int v2 = compare.getVersion();
       return MathUtils.compareInt(v2, v1);
     }
     return 0;
   }
   return k1 > k2 ? 1 : -1;
 }
 private void changeLength(long len) {
   length = len;
   len = MathUtils.roundUpLong(len, BLOCK_SIZE);
   int blocks = (int) (len >>> BLOCK_SIZE_SHIFT);
   if (blocks != data.length) {
     ByteBuffer[] n = new ByteBuffer[blocks];
     System.arraycopy(data, 0, n, 0, Math.min(data.length, n.length));
     for (int i = data.length; i < blocks; i++) {
       n[i] = COMPRESSED_EMPTY_BLOCK;
     }
     data = n;
   }
 }
 /**
  * Truncate the file.
  *
  * @param newLength the new length
  */
 void truncate(long newLength) {
   changeLength(newLength);
   long end = MathUtils.roundUpLong(newLength, BLOCK_SIZE);
   if (end != newLength) {
     int lastPage = (int) (newLength >>> BLOCK_SIZE_SHIFT);
     expand(data, lastPage);
     ByteBuffer d = data[lastPage];
     for (int i = (int) (newLength & BLOCK_SIZE_MASK); i < BLOCK_SIZE; i++) {
       d.put(i, (byte) 0);
     }
     if (compress) {
       compressLater(data, lastPage);
     }
   }
 }
 protected int compareSecure(Value o, CompareMode mode) {
   return MathUtils.compareLong(nanos, ((ValueTime) o).nanos);
 }
 @Override
 public boolean next() {
   synchronized (sync) {
     if (SysProperties.CHECK && end) {
       DbException.throwInternalError();
     }
     while (true) {
       if (needNewDelta) {
         loadNext(false);
         needNewDelta = false;
       }
       if (needNewBase) {
         loadNext(true);
         needNewBase = false;
       }
       if (deltaRow == null) {
         if (baseRow == null) {
           end = true;
           return false;
         }
         onBase = true;
         needNewBase = true;
         return true;
       }
       int sessionId = deltaRow.getSessionId();
       boolean isThisSession = sessionId == session.getId();
       boolean isDeleted = deltaRow.isDeleted();
       if (isThisSession && isDeleted) {
         needNewDelta = true;
         continue;
       }
       if (baseRow == null) {
         if (isDeleted) {
           if (isThisSession) {
             end = true;
             return false;
           }
           // the row was deleted by another session: return it
           onBase = false;
           needNewDelta = true;
           return true;
         }
         DbException.throwInternalError();
       }
       int compare = index.compareRows(deltaRow, baseRow);
       if (compare == 0) {
         // can't use compareKeys because the
         // version would be compared as well
         long k1 = deltaRow.getKey();
         long k2 = baseRow.getKey();
         compare = MathUtils.compareLong(k1, k2);
       }
       if (compare == 0) {
         if (isDeleted) {
           if (isThisSession) {
             DbException.throwInternalError();
           }
           // another session updated the row
         } else {
           if (isThisSession) {
             onBase = false;
             needNewBase = true;
             needNewDelta = true;
             return true;
           }
           // another session inserted the row: ignore
           needNewBase = true;
           needNewDelta = true;
           continue;
         }
       }
       if (compare > 0) {
         onBase = true;
         needNewBase = true;
         return true;
       }
       onBase = false;
       needNewDelta = true;
       return true;
     }
   }
 }
Beispiel #12
0
 /**
  * Get the next temporary file name part (the part in the middle).
  *
  * @param newRandom if the random part of the filename should change
  * @return the file name part
  */
 protected static synchronized String getNextTempFileNamePart(boolean newRandom) {
   if (newRandom || tempRandom == null) {
     tempRandom = MathUtils.randomInt(Integer.MAX_VALUE) + ".";
   }
   return tempRandom + tempSequence++;
 }
 public boolean next() {
   synchronized (this.sync) {
     if ((SysProperties.CHECK) && (this.end)) {
       DbException.throwInternalError();
     }
     int compare;
     for (; ; ) {
       if (this.needNewDelta) {
         loadNext(false);
         this.needNewDelta = false;
       }
       if (this.needNewBase) {
         loadNext(true);
         this.needNewBase = false;
       }
       if (this.deltaRow == null) {
         if (this.baseRow == null) {
           this.end = true;
           return false;
         }
         this.onBase = true;
         this.needNewBase = true;
         return true;
       }
       int sessionId = this.deltaRow.getSessionId();
       boolean isThisSession = sessionId == this.session.getId();
       boolean isDeleted = this.deltaRow.isDeleted();
       if ((isThisSession) && (isDeleted)) {
         this.needNewDelta = true;
       } else {
         if (this.baseRow == null) {
           if (isDeleted) {
             if (isThisSession) {
               this.end = true;
               return false;
             }
             this.onBase = false;
             this.needNewDelta = true;
             return true;
           }
           DbException.throwInternalError();
         }
         compare = this.index.compareRows(this.deltaRow, this.baseRow);
         if (compare == 0) {
           long k1 = this.deltaRow.getKey();
           long k2 = this.baseRow.getKey();
           compare = MathUtils.compareLong(k1, k2);
         }
         if (compare != 0) {
           break;
         }
         if (isDeleted) {
           if (!isThisSession) {
             break;
           }
           DbException.throwInternalError();
           break;
         }
         if (isThisSession) {
           this.onBase = false;
           this.needNewBase = true;
           this.needNewDelta = true;
           return true;
         }
         this.needNewBase = true;
         this.needNewDelta = true;
       }
     }
     if (compare > 0) {
       this.onBase = true;
       this.needNewBase = true;
       return true;
     }
     this.onBase = false;
     this.needNewDelta = true;
     return true;
   }
 }
Beispiel #14
0
 @Override
 public int getDisplaySize() {
   return MathUtils.convertLongToInt(getPrecision());
 }
Beispiel #15
0
 @Override
 protected int compareSecure(Value o, CompareMode mode) {
   ValueByte v = (ValueByte) o;
   return MathUtils.compareInt(value, v.value);
 }
Beispiel #16
0
 private void connectServer(ConnectionInfo ci) {
   String name = ci.getName();
   if (name.startsWith("//")) {
     name = name.substring("//".length());
   }
   int idx = name.indexOf('/');
   if (idx < 0) {
     throw ci.getFormatException();
   }
   databaseName = name.substring(idx + 1);
   String server = name.substring(0, idx);
   traceSystem = new TraceSystem(null);
   String traceLevelFile = ci.getProperty(SetTypes.TRACE_LEVEL_FILE, null);
   if (traceLevelFile != null) {
     int level = Integer.parseInt(traceLevelFile);
     String prefix = getFilePrefix(SysProperties.CLIENT_TRACE_DIRECTORY);
     try {
       traceSystem.setLevelFile(level);
       if (level > 0 && level < 4) {
         String file = FileUtils.createTempFile(prefix, Constants.SUFFIX_TRACE_FILE, false, false);
         traceSystem.setFileName(file);
       }
     } catch (IOException e) {
       throw DbException.convertIOException(e, prefix);
     }
   }
   String traceLevelSystemOut = ci.getProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT, null);
   if (traceLevelSystemOut != null) {
     int level = Integer.parseInt(traceLevelSystemOut);
     traceSystem.setLevelSystemOut(level);
   }
   trace = traceSystem.getTrace(Trace.JDBC);
   String serverList = null;
   if (server.indexOf(',') >= 0) {
     serverList = StringUtils.quoteStringSQL(server);
     ci.setProperty("CLUSTER", Constants.CLUSTERING_ENABLED);
   }
   autoReconnect = Boolean.parseBoolean(ci.getProperty("AUTO_RECONNECT", "false"));
   // AUTO_SERVER implies AUTO_RECONNECT
   boolean autoServer = Boolean.parseBoolean(ci.getProperty("AUTO_SERVER", "false"));
   if (autoServer && serverList != null) {
     throw DbException.getUnsupportedException("autoServer && serverList != null");
   }
   autoReconnect |= autoServer;
   if (autoReconnect) {
     String className = ci.getProperty("DATABASE_EVENT_LISTENER");
     if (className != null) {
       className = StringUtils.trim(className, true, true, "'");
       try {
         eventListener = (DatabaseEventListener) JdbcUtils.loadUserClass(className).newInstance();
       } catch (Throwable e) {
         throw DbException.convert(e);
       }
     }
   }
   cipher = ci.getProperty("CIPHER");
   if (cipher != null) {
     fileEncryptionKey = MathUtils.secureRandomBytes(32);
   }
   String[] servers = StringUtils.arraySplit(server, ',', true);
   int len = servers.length;
   transferList.clear();
   sessionId = StringUtils.convertBytesToHex(MathUtils.secureRandomBytes(32));
   // TODO cluster: support more than 2 connections
   boolean switchOffCluster = false;
   try {
     for (int i = 0; i < len; i++) {
       String s = servers[i];
       try {
         Transfer trans = initTransfer(ci, databaseName, s);
         transferList.add(trans);
       } catch (IOException e) {
         if (len == 1) {
           throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, e, e + ": " + s);
         }
         switchOffCluster = true;
       }
     }
     checkClosed();
     if (switchOffCluster) {
       switchOffCluster();
     }
     checkClusterDisableAutoCommit(serverList);
   } catch (DbException e) {
     traceSystem.close();
     throw e;
   }
 }