Beispiel #1
0
 /**
  * Undo all operations back to the log position of the given savepoint.
  *
  * @param name the savepoint name
  */
 public void rollbackToSavepoint(String name) {
   checkCommitRollback();
   if (savepoints == null) {
     throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
   }
   Integer savepointIndex = savepoints.get(name);
   if (savepointIndex == null) {
     throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
   }
   int i = savepointIndex.intValue();
   rollbackTo(i, false);
 }
Beispiel #2
0
 /**
  * Commit or roll back the given transaction.
  *
  * @param transactionName the name of the transaction
  * @param commit true for commit, false for rollback
  */
 public void setPreparedTransaction(String transactionName, boolean commit) {
   if (currentTransactionName != null && currentTransactionName.equals(transactionName)) {
     if (commit) {
       commit(false);
     } else {
       rollback();
     }
   } else {
     ArrayList<InDoubtTransaction> list = database.getInDoubtTransactions();
     int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK;
     boolean found = false;
     if (list != null) {
       for (InDoubtTransaction p : list) {
         if (p.getTransaction().equals(transactionName)) {
           p.setState(state);
           found = true;
           break;
         }
       }
     }
     if (!found) {
       throw DbException.get(ErrorCode.TRANSACTION_NOT_FOUND_1, transactionName);
     }
   }
 }
Beispiel #3
0
 public synchronized Command prepareCommand(String sql) {
   if (closed) {
     throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "session closed");
   }
   Command command;
   if (queryCacheSize > 0) {
     if (queryCache == null) {
       queryCache = SmallLRUCache.newInstance(queryCacheSize);
     } else {
       command = queryCache.get(sql);
       if (command != null && command.canReuse()) {
         command.reuse();
         return command;
       }
     }
   }
   Parser parser = createParser();
   command = parser.prepareCommand(sql);
   if (queryCache != null) {
     if (command.isCacheable()) {
       queryCache.put(sql, command);
     }
   }
   return command;
 }
Beispiel #4
0
 /**
  * Add a local temporary index to this session.
  *
  * @param index the index to add
  * @throws DbException if a index with this name already exists
  */
 public void addLocalTempTableIndex(Index index) {
   if (localTempTableIndexes == null) {
     localTempTableIndexes = database.newStringMap();
   }
   if (localTempTableIndexes.get(index.getName()) != null) {
     throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, index.getSQL());
   }
   localTempTableIndexes.put(index.getName(), index);
 }
Beispiel #5
0
 /**
  * Add a local temporary constraint to this session.
  *
  * @param constraint the constraint to add
  * @throws DbException if a constraint with the same name already exists
  */
 public void addLocalTempTableConstraint(Constraint constraint) {
   if (localTempTableConstraints == null) {
     localTempTableConstraints = database.newStringMap();
   }
   String name = constraint.getName();
   if (localTempTableConstraints.get(name) != null) {
     throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraint.getSQL());
   }
   localTempTableConstraints.put(name, constraint);
 }
Beispiel #6
0
 /**
  * Add a local temporary table to this session.
  *
  * @param table the table to add
  * @throws DbException if a table with this name already exists
  */
 public void addLocalTempTable(Table table) {
   if (localTempTables == null) {
     localTempTables = database.newStringMap();
   }
   if (localTempTables.get(table.getName()) != null) {
     throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, table.getSQL());
   }
   modificationId++;
   localTempTables.put(table.getName(), table);
 }
Beispiel #7
0
 /**
  * Check if the current transaction is canceled by calling Statement.cancel() or because a session
  * timeout was set and expired.
  *
  * @throws DbException if the transaction is canceled
  */
 public void checkCanceled() {
   throttle();
   if (cancelAt == 0) {
     return;
   }
   long time = System.currentTimeMillis();
   if (time >= cancelAt) {
     cancelAt = 0;
     throw DbException.get(ErrorCode.STATEMENT_WAS_CANCELED);
   }
 }
Beispiel #8
0
 private static ServerSocket createServerSocketTry(int port, boolean ssl) {
   try {
     InetAddress bindAddress = getBindAddress();
     if (ssl) {
       return CipherFactory.createServerSocket(port, bindAddress);
     }
     if (bindAddress == null) {
       return new ServerSocket(port);
     }
     return new ServerSocket(port, 0, bindAddress);
   } catch (BindException be) {
     throw DbException.get(ErrorCode.EXCEPTION_OPENING_PORT_2, be, "" + port, be.toString());
   } catch (IOException e) {
     throw DbException.convertIOException(e, "port: " + port + " ssl: " + ssl);
   }
 }
Beispiel #9
0
 public FileStore openFile(String name, String mode, boolean mustExist) {
   if (mustExist && !FileUtils.exists(name)) {
     throw DbException.get(ErrorCode.FILE_NOT_FOUND_1, name);
   }
   FileStore store;
   if (cipher == null) {
     store = FileStore.open(this, name, mode);
   } else {
     store = FileStore.open(this, name, mode, cipher, fileEncryptionKey, 0);
   }
   store.setCheckedWriting(false);
   try {
     store.init();
   } catch (DbException e) {
     store.closeSilently();
     throw e;
   }
   return store;
 }
Beispiel #10
0
  /**
   * Called to flush the output after data has been sent to the server and just before receiving
   * data. This method also reads the status code from the server and throws any exception the
   * server sent.
   *
   * @param transfer the transfer object
   * @throws DbException if the server sent an exception
   * @throws IOException if there is a communication problem between client and server
   */
  public void done(Transfer transfer) throws IOException {
    // 正常来讲不会出现这种情况,如果出现了,说明存在bug,找出为什么transfer的输入流没正常读完的原因
    if (transfer.available() > 0) {
      throw DbException.throwInternalError(
          "before transfer flush, the available bytes was " + transfer.available());
    }

    transfer.flush();
    int status = transfer.readInt();
    if (status == STATUS_ERROR) {
      parseError(transfer);
    } else if (status == STATUS_CLOSED) {
      transferList = null;
    } else if (status == STATUS_OK_STATE_CHANGED) {
      sessionStateChanged = true;
    } else if (status == STATUS_OK) {
      // ok
    } else {
      throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "unexpected status " + status);
    }
  }
Beispiel #11
0
 /**
  * INTERNAL. Parse and set the CSV options.
  *
  * @param options the the options
  * @return the character set
  */
 public String setOptions(String options) {
   String charset = null;
   String[] keyValuePairs = StringUtils.arraySplit(options, ' ', false);
   for (String pair : keyValuePairs) {
     if (pair.length() == 0) {
       continue;
     }
     int index = pair.indexOf('=');
     String key = StringUtils.trim(pair.substring(0, index), true, true, " ");
     String value = pair.substring(index + 1);
     char ch = value.length() == 0 ? 0 : value.charAt(0);
     if (isParam(key, "escape", "esc", "escapeCharacter")) {
       setEscapeCharacter(ch);
     } else if (isParam(key, "fieldDelimiter", "fieldDelim")) {
       setFieldDelimiter(ch);
     } else if (isParam(key, "fieldSeparator", "fieldSep")) {
       setFieldSeparatorRead(ch);
       setFieldSeparatorWrite(value);
     } else if (isParam(key, "lineComment", "lineCommentCharacter")) {
       setLineCommentCharacter(ch);
     } else if (isParam(key, "lineSeparator", "lineSep")) {
       setLineSeparator(value);
     } else if (isParam(key, "null", "nullString")) {
       setNullString(value);
     } else if (isParam(key, "rowSeparator", "rowSep")) {
       setRowSeparatorWrite(value);
     } else if (isParam(key, "charset", "characterSet")) {
       charset = value;
     } else if (isParam(key, "preserveWhitespace")) {
       setPreserveWhitespace(Boolean.parseBoolean(value));
     } else if (isParam(key, "writeColumnHeader")) {
       setWriteColumnHeader(Boolean.parseBoolean(value));
     } else if (isParam(key, "caseSensitiveColumnNames")) {
       setCaseSensitiveColumnNames(Boolean.parseBoolean(value));
     } else {
       throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, key);
     }
   }
   return charset;
 }
Beispiel #12
0
 private void checkCommitRollback() {
   if (commitOrRollbackDisabled && locks.size() > 0) {
     throw DbException.get(ErrorCode.COMMIT_ROLLBACK_NOT_ALLOWED);
   }
 }
Beispiel #13
0
 private static SQLException convertException(String message, Exception e) {
   return DbException.get(ErrorCode.IO_EXCEPTION_1, e, message).getSQLException();
 }
Beispiel #14
0
 /**
  * Check if this session is closed and throws an exception if so.
  *
  * @throws DbException if the session is closed
  */
 public void checkClosed() {
   if (isClosed()) {
     throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "session closed");
   }
 }
Beispiel #15
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) {
          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.valueOf(ci.getProperty("AUTO_RECONNECT", "false")).booleanValue();
    // AUTO_SERVER implies AUTO_RECONNECT
    boolean autoServer = Boolean.valueOf(ci.getProperty("AUTO_SERVER", "false")).booleanValue();
    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) Utils.loadUserClass(className).newInstance();
        } catch (Throwable e) {
          throw DbException.convert(e);
        }
      }
    }
    cipher = ci.getProperty("CIPHER");
    if (cipher != null) {
      fileEncryptionKey = MathUtils.secureRandomBytes(32);
    }

    String[] servers;
    if (ci.isDynamic()) {
      servers = new String[] {ci.getOnlineServer(server)};
    } else {
      servers = StringUtils.arraySplit(server, ',', true);

      if (servers.length > 1 && !ci.removeProperty("USE_H2_CLUSTER_MODE", false))
        servers = new String[] {servers[random.nextInt(servers.length)]};
    }
    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;
    }
  }
Beispiel #16
0
 protected void checkParameterCount(int len) {
   if (len < 1) {
     throw DbException.get(ErrorCode.INVALID_PARAMETER_COUNT_2, getName(), ">0");
   }
 }