/**
   * Method to apply any restrictions to the created ResultSet.
   *
   * @param ps The PreparedStatement
   * @param query The query
   * @param applyTimeout Whether to apply the query timeout (if any) direct to the PreparedStatement
   * @throws SQLException Thrown when an error occurs applying the constraints
   */
  public static void prepareStatementForExecution(
      PreparedStatement ps, Query query, boolean applyTimeout) throws SQLException {
    NucleusContext nucleusCtx = query.getExecutionContext().getNucleusContext();
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) query.getStoreManager();
    PersistenceConfiguration conf = nucleusCtx.getPersistenceConfiguration();

    if (applyTimeout) {
      Integer timeout = query.getDatastoreReadTimeoutMillis();
      if (timeout != null && timeout > 0) {
        ps.setQueryTimeout(timeout / 1000);
      }
    }

    // Apply any fetch size
    int fetchSize = 0;
    if (query.getFetchPlan().getFetchSize() > 0) {
      // FetchPlan has a size set so use that
      fetchSize = query.getFetchPlan().getFetchSize();
    }
    if (storeMgr.getDatastoreAdapter().supportsQueryFetchSize(fetchSize)) {
      ps.setFetchSize(fetchSize);
    }

    // Apply any fetch direction
    String fetchDir =
        conf.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_FETCH_DIRECTION);
    Object fetchDirExt =
        query.getExtension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_FETCH_DIRECTION);
    if (fetchDirExt != null) {
      fetchDir = (String) fetchDirExt;
      if (!fetchDir.equals("forward")
          && !fetchDir.equals("reverse")
          && !fetchDir.equals("unknown")) {
        throw new NucleusUserException(LOCALISER.msg("052512"));
      }
    }

    if (fetchDir.equals("reverse")) {
      ps.setFetchDirection(ResultSet.FETCH_REVERSE);
    } else if (fetchDir.equals("unknown")) {
      ps.setFetchDirection(ResultSet.FETCH_UNKNOWN);
    }

    // Add a limit on the number of rows to include the maximum we may need
    long toExclNo = query.getRangeToExcl();
    if (toExclNo != 0 && toExclNo != Long.MAX_VALUE) {
      if (toExclNo > Integer.MAX_VALUE) {
        // setMaxRows takes an int as input so limit to the correct range
        ps.setMaxRows(Integer.MAX_VALUE);
      } else {
        ps.setMaxRows((int) toExclNo);
      }
    }
  }
  public void setFetchDirection(int direction) throws SQLException {
    Profiler profiler = _profilerPoint.start();

    try {
      _preparedStatement.setFetchDirection(direction);
    } finally {
      profiler.finish();
    }
  }
 /**
  * 初始化真正的PreparedStatement,对当前对象的操作全部都设置到真正的PreparedStatement
  *
  * @throws SQLException
  */
 private void prepare() throws SQLException {
   DALFactory dalFactory = DALFactory.getDefault();
   List<Object> values = dalParameters.getValues();
   Map<String, Object> context = new HashMap<String, Object>();
   SQLStruct sqlStruct = dalFactory.getSqlAnalyzer().parse(sql, context);
   SQLInfo sqlInfo = null;
   if (sqlStruct.isCanParse()) {
     sqlInfo =
         dalFactory
             .getSqlAnalyzer()
             .analyse(sql, sqlStruct, values.toArray(new Object[values.size()]), context);
   }
   this.parsePartition(sqlStruct, sqlInfo);
   this.initRealPreparedStatement();
   if (this.maxFieldSize != 0) {
     ps.setMaxFieldSize(maxFieldSize);
   }
   if (this.maxRows != 0) {
     ps.setMaxRows(maxRows);
   }
   if (!this.escapeProcessing) {
     ps.setEscapeProcessing(escapeProcessing);
   }
   if (this.queryTimeout != 0) {
     ps.setQueryTimeout(queryTimeout);
   }
   if (this.cursorName != null) {
     ps.setCursorName(cursorName);
   }
   if (this.fetchDirection != 0) {
     ps.setFetchDirection(fetchDirection);
   }
   if (this.fetchSize != 0) {
     ps.setFetchSize(fetchSize);
   }
   if (!this.poolable) {
     ps.setPoolable(poolable);
   }
   this.dalParameters.initRealPreparedStatement(ps);
 }
  /**
   * Get the samples: <code>result_set</code> will have the samples, <code>value</code> will contain
   * the first sample
   *
   * @param start Start time
   * @param end End time
   * @throws Exception on error, including cancellation
   */
  private void determineInitialSample(final Timestamp start, final Timestamp end) throws Exception {
    java.sql.Timestamp start_stamp = TimestampHelper.toSQLTimestamp(start);
    final java.sql.Timestamp end_stamp = TimestampHelper.toSQLTimestamp(end);

    // Get time of initial sample
    final PreparedStatement statement =
        reader.getRDB().getConnection().prepareStatement(reader.getSQL().sample_sel_initial_time);
    reader.addForCancellation(statement);
    try {
      statement.setInt(1, channel_id);
      statement.setTimestamp(2, start_stamp);
      final ResultSet result = statement.executeQuery();
      if (result.next()) {
        // System.out.print("Start time corrected from " + start_stamp);
        start_stamp = result.getTimestamp(1);
        // Oracle has nanoseconds in TIMESTAMP, MySQL in separate column
        if (reader.getRDB().getDialect() == Dialect.MySQL
            || reader.getRDB().getDialect() == Dialect.PostgreSQL)
          start_stamp.setNanos(result.getInt(2));
        // System.out.println(" to " + start_stamp);
      }
    } finally {
      reader.removeFromCancellation(statement);
      statement.close();
    }

    // Fetch the samples
    if (reader.useArrayBlob())
      sel_samples =
          reader
              .getRDB()
              .getConnection()
              .prepareStatement(reader.getSQL().sample_sel_by_id_start_end_with_blob);
    else
      sel_samples =
          reader
              .getRDB()
              .getConnection()
              .prepareStatement(reader.getSQL().sample_sel_by_id_start_end);
    sel_samples.setFetchDirection(ResultSet.FETCH_FORWARD);

    // Test w/ ~170000 raw samples:
    //     10  17   seconds
    //    100   6   seconds
    //   1000   4.x seconds
    //  10000   4.x seconds
    // 100000   4.x seconds
    // So default is bad. 100 or 1000 are good.
    // Bigger numbers don't help much in repeated tests, but
    // just to be on the safe side, use a bigger number.
    sel_samples.setFetchSize(Preferences.getFetchSize());

    reader.addForCancellation(sel_samples);
    sel_samples.setInt(1, channel_id);
    sel_samples.setTimestamp(2, start_stamp);
    sel_samples.setTimestamp(3, end_stamp);
    result_set = sel_samples.executeQuery();
    // Get first sample
    if (result_set.next()) value = decodeSampleTableValue(result_set, true);
    // else leave value null to indicate end of samples
  }
 public void setFetchDirection(int direction) throws SQLException {
   this.fetchDirection = direction;
   if (ps != null) {
     ps.setFetchDirection(direction);
   }
 }
 public void setFetchDirection(int direction) throws SQLException {
   statement.setFetchDirection(direction);
 }
 public void setFetchDirection(int direction) throws SQLException {
   delegate.setFetchDirection(direction);
 }
 @Override
 public void setFetchDirection(int direction) throws SQLException {
   stmt.setFetchDirection(direction);
 }