Package com.netflix.astyanax.cql.reads

Source Code of com.netflix.astyanax.cql.reads.QueryGenCache

package com.netflix.astyanax.cql.reads;

import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;

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

import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.Session;

/**
* Template for {@link PreparedStatement} caching for a query Q.
* The class provides the basic functionality to store a cached reference to the PreparedStatement
* that is generated by the extending class. Hence actual logic for constructing the PrepatedStatement
* and binding values to that statement is not defined here. That must be provided by the extending classes. 
*
* @author poberai
*
* @param <Q>
*/
public abstract class QueryGenCache<Q> {
 
  private static final Logger LOG = LoggerFactory.getLogger(QueryGenCache.class);

  // reference to the session object. This is required for "preparing" a statement
  private AtomicReference<Session> sessionRef = new AtomicReference<Session>(null);
  // The cached reference to the query constructed by extending classes
  private final AtomicReference<PreparedStatement> cachedStatement = new AtomicReference<PreparedStatement>(null);

  /**
   * Constructor
   * @param sessionR
   */
  public QueryGenCache(AtomicReference<Session> sessionR) {
    this.sessionRef = sessionR;
  }

  /**
   * Get the bound statement from the prepared statement
   * @param query
   * @param useCaching
   * @return BoundStatement
   */
  public BoundStatement getBoundStatement(Q query, boolean useCaching) {

    PreparedStatement pStatement = getPreparedStatement(query, useCaching);
    return bindValues(pStatement, query);
  }

  /**
   * Get the bound statemnent by either constructing the query or using the cached statement underneath.
   * Note that the caller can provide useCaching as a knob to turn caching ON/OFF.
   * If false, then the query is just constructed using the extending class and returned.
   * If true, then the cached reference is consulted. If the cache is empty, then the query is constructed
   * and used to seed the cache.
   *
   * @param query
   * @param useCaching
   * @return PreparedStatement
   */
  public PreparedStatement getPreparedStatement(Q query, boolean useCaching) {

    PreparedStatement pStatement = null;

    if (useCaching) {
      pStatement = cachedStatement.get();
    }

    if (pStatement == null) {
      try {
        RegularStatement stmt = getQueryGen(query).call();
        if (LOG.isDebugEnabled()) {
          LOG.debug("Query: " + stmt.getQueryString());
        }
        pStatement = sessionRef.get().prepare(stmt.getQueryString());
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }

    if (useCaching && cachedStatement.get() == null) {
      cachedStatement.set(pStatement);
    }
    return pStatement;
  }
 
  /**
   * Extending classes must implement this with logic for constructing the java driver query from the given Astyanax query
   * @param query
   * @return Callable<RegularStatement>
   */
  public abstract Callable<RegularStatement> getQueryGen(Q query);

  /**
   * Extending classes must implement this with logic for binding the right Astyanax query data with the pre-constructed
   * prepared statement in the right order.
   * @param pStatement
   * @param query
   * @return BoundStatement
   */
  public abstract BoundStatement bindValues(PreparedStatement pStatement, Q query);
}
TOP

Related Classes of com.netflix.astyanax.cql.reads.QueryGenCache

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.