Package com.avaje.ebeaninternal.server.query

Source Code of com.avaje.ebeaninternal.server.query.CQueryFetchIds

package com.avaje.ebeaninternal.server.query;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebeaninternal.api.BeanIdList;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.api.SpiQuery.Mode;
import com.avaje.ebeaninternal.api.SpiTransaction;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
import com.avaje.ebeaninternal.server.core.SpiOrmQueryRequest;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import com.avaje.ebeaninternal.server.deploy.DbReadContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import com.avaje.ebeaninternal.server.type.DataReader;
import com.avaje.ebeaninternal.server.type.RsetDataReader;

/**
* Executes the select row count query.
*/
public class CQueryFetchIds {

  private static final Logger logger = LoggerFactory.getLogger(CQueryFetchIds.class);

  /**
   * The overall find request wrapper object.
   */
  private final OrmQueryRequest<?> request;

  private final BeanDescriptor<?> desc;

  private final SpiQuery<?> query;

  /**
   * Where clause predicates.
   */
  private final CQueryPredicates predicates;

  /**
   * The final sql that is generated.
   */
  private final String sql;

  private RsetDataReader dataReader;
 
  /**
   * The statement used to create the resultSet.
   */
  private PreparedStatement pstmt;

  private String bindLog;

  private long startNano;
 
  private int executionTimeMicros;

  private int rowCount;
 
  private final int maxRows;
 
  /**
   * Create the Sql select based on the request.
   */
  public CQueryFetchIds(OrmQueryRequest<?> request, CQueryPredicates predicates, String sql) {

    this.request = request;
    this.query = request.getQuery();
    this.sql = sql;
    this.maxRows = query.getMaxRows();

    query.setGeneratedSql(sql);

    this.desc = request.getBeanDescriptor();
    this.predicates = predicates;

  }
 
  /**
   * Return a summary description of this query.
   */
  public String getSummary() {
    StringBuilder sb = new StringBuilder();
      sb.append("FindIds exeMicros[").append(executionTimeMicros)
      .append("] rows[").append(rowCount)
      .append("] type[").append(desc.getName())
      .append("] predicates[").append(predicates.getLogWhereSql())
      .append("] bind[").append(bindLog).append("]");
   
    return sb.toString();   
  }

  /**
   * Return the bind log.
   */
  public String getBindLog() {
        return bindLog;
    }

    /**
   * Return the generated sql.
   */
  public String getGeneratedSql() {
    return sql;
  }
 
  public SpiOrmQueryRequest<?> getQueryRequest() {
    return request;
  }

  /**
   * Execute the query returning the row count.
   */
  public BeanIdList findIds() throws SQLException {

    startNano = System.nanoTime();
   
    try {
      // get the list that we are going to put the id's into.
      // This was already set so that it is available to be
      // read by other threads (it is a synchronised list)
      List<Object> idList = query.getIdList();
      if (idList == null){
        // running in foreground thread (not FutureIds query)
        idList = Collections.synchronizedList(new ArrayList<Object>());
        query.setIdList(idList);
      }
     
      BeanIdList result = new BeanIdList(idList);
     
      SpiTransaction t = request.getTransaction();
      Connection conn = t.getInternalConnection();
      pstmt = conn.prepareStatement(sql);
     
      if (query.getBufferFetchSizeHint() > 0){
        pstmt.setFetchSize(query.getBufferFetchSizeHint());
      }
 
      if (query.getTimeout() > 0){
        pstmt.setQueryTimeout(query.getTimeout());
      }
 
      bindLog = predicates.bind(new DataBind(pstmt));
 
      ResultSet rset = pstmt.executeQuery();
      dataReader = new RsetDataReader(rset);
   
      boolean hitMaxRows = false;
      boolean hasMoreRows = false;
      rowCount = 0;
     
      DbReadContext ctx = new DbContext();
     
      while (rset.next()){
        Object idValue = desc.getIdBinder().read(ctx);
        idList.add(idValue);
        // reset back to 0
        dataReader.resetColumnPosition();
        rowCount++;
       
        if (maxRows > 0 && rowCount == maxRows) {
          hitMaxRows = true;
          hasMoreRows = rset.next();
          break;

        }
      }
     
      if (hitMaxRows){
        result.setHasMore(hasMoreRows);
      }
     
      long exeNano = System.nanoTime() - startNano;
      executionTimeMicros = (int)exeNano/1000;

      return result;
     
    } finally {
      close();
    }
  }

  /**
   * Close the resources.
   * <p>
   * The jdbc resultSet and statement need to be closed. Its important that
   * this method is called.
   * </p>
   */
  private void close() {
    try {
      if (dataReader != null) {
          dataReader.close();
          dataReader = null;
      }
    } catch (SQLException e) {
      logger.error(null, e);
    }
    try {
      if (pstmt != null) {
        pstmt.close();
        pstmt = null;
      }
    } catch (SQLException e) {
      logger.error(null, e);
    }
  }

 
  class DbContext implements DbReadContext {

        public void propagateState(Object e) {
            throw new RuntimeException("Not Called");
        }

        public Mode getQueryMode() {
      return Mode.NORMAL;
    }
   
    public DataReader getDataReader() {
            return dataReader;
        }

    public Boolean isReadOnly() {
      return Boolean.FALSE;
    }
   
    public boolean isRawSql() {
      return false;
    }

    public void register(String path, EntityBeanIntercept ebi){
    }

    public void register(String path, BeanCollection<?> bc){ 
    }

    public BeanPropertyAssocMany<?> getManyProperty() {
      // always null
      return null;
    }

    public PersistenceContext getPersistenceContext() {
      // always null
      return null;
    }

    public boolean isAutoFetchProfiling() {
      return false;
    }

    public void profileBean(EntityBeanIntercept ebi, String prefix) {
      // no-op     
    }

    public void setCurrentPrefix(String currentPrefix,Map<String, String> pathMap) {
      // no-op
    }

    public void setLoadedBean(EntityBean loadedBean, Object id, Object lazyLoadParentId) {
      // no-op
    }

    public void setLoadedManyBean(EntityBean loadedBean) {
      // no-op
    }
   
  }
 
}
TOP

Related Classes of com.avaje.ebeaninternal.server.query.CQueryFetchIds

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.