Package com.avaje.ebeaninternal.server.query

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

package com.avaje.ebeaninternal.server.query;

import java.sql.SQLException;

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

import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionTouched;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebeaninternal.api.BeanIdList;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
import com.avaje.ebeaninternal.server.lib.util.Str;
import com.avaje.ebeaninternal.server.persist.Binder;
import com.avaje.ebeaninternal.server.transaction.TransactionManager;

/**
* Handles the Object Relational fetching.
*/
public class CQueryEngine {

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

  private final DatabasePlatform dbPlatform;
 
  private final CQueryBuilder queryBuilder;

  private final int defaultSecondaryQueryBatchSize = 100;

  public CQueryEngine(DatabasePlatform dbPlatform, Binder binder) {
    this.dbPlatform = dbPlatform;
    this.queryBuilder = new CQueryBuilder(dbPlatform, binder);
  }

  public <T> CQuery<T> buildQuery(OrmQueryRequest<T> request) {
    return queryBuilder.buildQuery(request);
  }

  /**
   * Build and execute the find Id's query.
   */
  public <T> BeanIdList findIds(OrmQueryRequest<T> request) {

    CQueryFetchIds rcQuery = queryBuilder.buildFetchIdsQuery(request);
    try {

     
      BeanIdList list = rcQuery.findIds();

      if (request.isLogSql()) {
        String logSql = rcQuery.getGeneratedSql();
        if (TransactionManager.SQL_LOGGER.isTraceEnabled()) {
          logSql = Str.add(logSql, "; --bind(", rcQuery.getBindLog(), ")");
        }
        request.logSql(logSql);
      }

      if (request.isLogSummary()) {
        request.getTransaction().logSummary(rcQuery.getSummary());
      }

      if (!list.isFetchingInBackground() && request.getQuery().isFutureFetch()) {
        // end the transaction for futureFindIds (it had it's own one)
        logger.debug("Future findIds completed!");
        request.getTransaction().end();
      }

      return list;

    } catch (SQLException e) {
      throw CQuery.createPersistenceException(e, request.getTransaction(), rcQuery.getBindLog(), rcQuery.getGeneratedSql());
    }
  }

  /**
   * Build and execute the row count query.
   */
  public <T> int findRowCount(OrmQueryRequest<T> request) {

    CQueryRowCount rcQuery = queryBuilder.buildRowCountQuery(request);
    try {
    
      int rowCount = rcQuery.findRowCount();

      if (request.isLogSql()) {
        String logSql = rcQuery.getGeneratedSql();
        if (TransactionManager.SQL_LOGGER.isTraceEnabled()) {
          logSql= Str.add(logSql, "; --bind(", rcQuery.getBindLog(), ")");
        }
        request.logSql(logSql);
      }

      if (request.isLogSummary()) {
        request.getTransaction().logSummary(rcQuery.getSummary());
      }

      if (request.getQuery().isFutureFetch()) {
        logger.debug("Future findRowCount completed!");
        request.getTransaction().end();
      }

      return rowCount;

    } catch (SQLException e) {
      throw CQuery.createPersistenceException(e, request.getTransaction(), rcQuery.getBindLog(), rcQuery.getGeneratedSql());
    }
  }

  /**
   * Read many beans using an iterator (except you need to close() the iterator
   * when you have finished).
   */
  public <T> QueryIterator<T> findIterate(OrmQueryRequest<T> request) {

    CQuery<T> cquery = queryBuilder.buildQuery(request);
    request.setCancelableQuery(cquery);

    try {

      if (!cquery.prepareBindExecuteQueryForwardOnly(dbPlatform.isForwardOnlyHintOnFindIterate())) {
        // query has been cancelled already
        logger.trace("Future fetch already cancelled");
        return null;
      }

      if (request.isLogSql()) {
        logSql(cquery);
      }

      int iterateBufferSize = request.getSecondaryQueriesMinBatchSize(defaultSecondaryQueryBatchSize);

      QueryIterator<T> readIterate = cquery.readIterate(iterateBufferSize, request);

      if (request.isLogSummary()) {
        logFindManySummary(cquery);
      }

      return readIterate;

    } catch (SQLException e) {
      throw cquery.createPersistenceException(e);
    }
  }

  /**
   * Find a list/map/set of beans.
   */
  public <T> BeanCollection<T> findMany(OrmQueryRequest<T> request) {

    CQuery<T> cquery = queryBuilder.buildQuery(request);
    request.setCancelableQuery(cquery);

    try {
      if (!cquery.prepareBindExecuteQuery()) {
        // query has been cancelled already
        logger.trace("Future fetch already cancelled");
        return null;
      }
     
      if (request.isLogSql()) {
        logSql(cquery);
      }

      BeanCollection<T> beanCollection = cquery.readCollection();

      BeanCollectionTouched collectionTouched = request.getQuery().getBeanCollectionTouched();
      if (collectionTouched != null) {
        // register a listener that wants to be notified when the
        // bean collection is first used
        beanCollection.setBeanCollectionTouched(collectionTouched);
      }

      if (request.isLogSummary()) {
        logFindManySummary(cquery);
      }

      request.executeSecondaryQueries(defaultSecondaryQueryBatchSize);

      return beanCollection;

    } catch (SQLException e) {
      throw cquery.createPersistenceException(e);
     
    } finally {
      if (cquery != null) {
        cquery.close();
      }
      if (request.getQuery().isFutureFetch()) {
        // end the transaction for futureFindIds
        // as it had it's own transaction
        logger.debug("Future fetch completed!");
        request.getTransaction().end();
      }
    }
  }

  /**
   * Find and return a single bean using its unique id.
   */
  @SuppressWarnings("unchecked")
  public <T> T find(OrmQueryRequest<T> request) {

    EntityBean bean = null;

    CQuery<T> cquery = queryBuilder.buildQuery(request);

    try {
      cquery.prepareBindExecuteQuery();

      if (request.isLogSql()) {
        logSql(cquery);
      }

      if (cquery.readBean()) {
        bean = cquery.getLoadedBean();
      }

      if (request.isLogSummary()) {
        logFindBeanSummary(cquery);
      }

      request.executeSecondaryQueries(defaultSecondaryQueryBatchSize);

      return (T)bean;

    } catch (SQLException e) {
      throw cquery.createPersistenceException(e);

    } finally {
      cquery.close();
    }
  }

  /**
   * Log the generated SQL to the transaction log.
   */
  private void logSql(CQuery<?> query) {

    String sql = query.getGeneratedSql();
    if (TransactionManager.SQL_LOGGER.isTraceEnabled()) {
      sql= Str.add(sql, "; --bind(", query.getBindLog(), ")");
    }
    query.getTransaction().logSql(sql);
  }

  /**
   * Log the FindById summary to the transaction log.
   */
  private void logFindBeanSummary(CQuery<?> q) {

    SpiQuery<?> query = q.getQueryRequest().getQuery();
    String loadMode = query.getLoadMode();
    String loadDesc = query.getLoadDescription();
    String lazyLoadProp = query.getLazyLoadProperty();
    ObjectGraphNode node = query.getParentNode();
    String originKey;
    if (node == null || node.getOriginQueryPoint() == null) {
      originKey = null;
    } else {
      originKey = node.getOriginQueryPoint().getKey();
    }

    StringBuilder msg = new StringBuilder(200);
    msg.append("FindBean ");
    if (loadMode != null) {
      msg.append("mode[").append(loadMode).append("] ");
    }
    msg.append("type[").append(q.getBeanName()).append("] ");
    if (query.isAutofetchTuned()) {
      msg.append("tuned[true] ");
    }
    if (originKey != null) {
      msg.append("origin[").append(originKey).append("] ");
    }
    if (lazyLoadProp != null) {
      msg.append("lazyLoadProp[").append(lazyLoadProp).append("] ");
    }
    if (loadDesc != null) {
      msg.append("load[").append(loadDesc).append("] ");
    }
    msg.append("exeMicros[").append(q.getQueryExecutionTimeMicros());
    msg.append("] rows[").append(q.getLoadedRowDetail());
    msg.append("] bind[").append(q.getBindLog()).append("]");

    q.getTransaction().logSummary(msg.toString());
  }

  /**
   * Log the FindMany to the transaction log.
   */
  private void logFindManySummary(CQuery<?> q) {

    SpiQuery<?> query = q.getQueryRequest().getQuery();
    String loadMode = query.getLoadMode();
    String loadDesc = query.getLoadDescription();
    String lazyLoadProp = query.getLazyLoadProperty();
    ObjectGraphNode node = query.getParentNode();

    String originKey;
    if (node == null || node.getOriginQueryPoint() == null) {
      originKey = null;
    } else {
      originKey = node.getOriginQueryPoint().getKey();
    }

    StringBuilder msg = new StringBuilder(200);
    msg.append("FindMany ");
    if (loadMode != null) {
      msg.append("mode[").append(loadMode).append("] ");
    }
    msg.append("type[").append(q.getBeanName()).append("] ");
    if (query.isAutofetchTuned()) {
      msg.append("tuned[true] ");
    }
    if (originKey != null) {
      msg.append("origin[").append(originKey).append("] ");
    }
    if (lazyLoadProp != null) {
      msg.append("lazyLoadProp[").append(lazyLoadProp).append("] ");
    }
    if (loadDesc != null) {
      msg.append("load[").append(loadDesc).append("] ");
    }
    msg.append("exeMicros[").append(q.getQueryExecutionTimeMicros());
    msg.append("] rows[").append(q.getLoadedRowDetail());
    msg.append("] name[").append(q.getName());
    msg.append("] predicates[").append(q.getLogWhereSql());
    msg.append("] bind[").append(q.getBindLog()).append("]");

    q.getTransaction().logSummary(msg.toString());
  }
}
TOP

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

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.