Package com.opengamma.masterdb

Source Code of com.opengamma.masterdb.AbstractDbMaster

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.masterdb;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.support.TransactionTemplate;
import org.threeten.bp.Clock;
import org.threeten.bp.Instant;

import com.opengamma.elsql.ElSqlBundle;
import com.opengamma.id.ObjectIdentifiable;
import com.opengamma.id.UniqueId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.db.DbConnector;
import com.opengamma.util.db.DbDialect;
import com.opengamma.util.db.DbMapSqlParameterSource;

/**
* An abstract master for rapid implementation of a database backed master.
* <p>
* This combines the various configuration elements and convenience methods
* needed for most database masters.
* <p>
* This class is mutable but must be treated as immutable after configuration.
*/
public abstract class AbstractDbMaster {

  /** Logger. */
  private static final Logger s_logger = LoggerFactory.getLogger(AbstractDbMaster.class);

  /**
   * The database connector.
   */
  private final DbConnector _dbConnector;
  /**
   * The clock to use.
   */
  private Clock _clock;
  /**
   * The scheme in use for the unique identifier.
   */
  private String _uniqueIdScheme;

  /**
   * The maximum number of retries.
   */
  private int _maxRetries = 10;

  /**
   * External SQL bundle.
   */
  private ElSqlBundle _externalSqlBundle;
 
  /**
   * The Hibernate template.
   */
  private HibernateTemplate _hibernateTemplate;

  /**
   * Creates an instance.
   *
   * @param dbConnector  the database connector, not null
   * @param defaultScheme  the default scheme for unique identifier, not null
   */
  public AbstractDbMaster(final DbConnector dbConnector, final String defaultScheme) {
    ArgumentChecker.notNull(dbConnector, "dbConnector");
    s_logger.debug("installed DbConnector: {}", dbConnector);
    _dbConnector = dbConnector;
    _clock = dbConnector.timeSource();
    _uniqueIdScheme = defaultScheme;
    _hibernateTemplate = dbConnector.getHibernateTemplate();
  }

  /**
   * Gets the maximum number of retries.
   * The default is ten.
   *
   * @return the maximum number of retries, not null
   */
  public int getMaxRetries() {
    return _maxRetries;
  }

  /**
   * Sets the maximum number of retries.
   * The default is ten.
   *
   * @param maxRetries  the maximum number of retries, not negative
   */
  public void setMaxRetries(final int maxRetries) {
    ArgumentChecker.notNegative(maxRetries, "maxRetries");
    _maxRetries = maxRetries;
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the database connector.
   *
   * @return the database connector, not null
   */
  public DbConnector getDbConnector() {
    return _dbConnector;
  }
 
  /**
   * Gets the Hibernate Session factory.
   *
   * @return the session factory, not null
   */
  public SessionFactory getSessionFactory() {
    return getDbConnector().getHibernateSessionFactory();
  }
 
  /**
   * Gets the local Hibernate template.
   *
   * @return the template, not null
   */
  public HibernateTemplate getHibernateTemplate() {
    return _hibernateTemplate;
  }
 
  //-------------------------------------------------------------------------
  /**
   * Gets the external SQL bundle.
   *
   * @return the external SQL bundle, not null
   */
  public ElSqlBundle getElSqlBundle() {
    return _externalSqlBundle;
  }

  /**
   * Sets the external SQL bundle.
   *
   * @param bundle  the external SQL bundle, not null
   */
  public void setElSqlBundle(ElSqlBundle bundle) {
    _externalSqlBundle = bundle;
  }
 
  //-------------------------------------------------------------------------
  /**
   * Gets the next database id.
   *
   * @param sequenceName  the name of the sequence to query, not null
   * @return the next database id
   */
  protected long nextId(String sequenceName) {
    return getJdbcTemplate().getJdbcOperations().queryForObject(getDialect().sqlNextSequenceValueSelect(sequenceName), Long.class);
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the clock that determines the current time.
   *
   * @return the clock, not null
   */
  public Clock getClock() {
    return _clock;
  }

  /**
   * Sets the clock that determines the current time.
   *
   * @param clock  the clock, not null
   */
  public void setClock(final Clock clock) {
    ArgumentChecker.notNull(clock, "clock");
    s_logger.debug("installed Clock: {}", clock);
    _clock = clock;
  }
 
  /**
   * Resets the clock that determines the current time to the default.
   */
  public void resetClock() {
    setClock(getDbConnector().timeSource());
  }

  /**
   * Gets the current instant using the clock.
   *
   * @return the current instant, not null
   */
  protected Instant now() {
    return Instant.now(getClock());
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the database template.
   *
   * @return the database template, not null if correctly initialized
   */
  protected NamedParameterJdbcTemplate getJdbcTemplate() {
    return getDbConnector().getJdbcTemplate();
  }

  /**
   * Gets the transaction template.
   *
   * @return the transaction template, not null if correctly initialized
   */
  protected TransactionTemplate getTransactionTemplate() {
    return getDbConnector().getTransactionTemplate();
  }

  /**
   * Gets the retrying transaction template.
   *
   * @param retries number of retries of execution before considering the execution failed
   * @return the transaction template, not null if correctly initialized
   */
  protected DbConnector.TransactionTemplateRetrying getTransactionTemplateRetrying(int retries) {
    return getDbConnector().getTransactionTemplateRetrying(retries);
  }
 
  /**
   * Gets the hibernate template wrapped in new transaction.
   *
   * @return the hibernate template wrapped in new transaction, not null if correctly initialized
   */
  protected DbConnector.HibernateTransactionTemplate getHibernateTransactionTemplate() {
    return getDbConnector().getHibernateTransactionTemplate();
  }

  /**
   * Gets the retrying hibernate transaction template.
   *
   * @param retries number of retries of execution before considering the execution failed
   * @return the hibernate transaction template, not null if correctly initialized
   */
  protected DbConnector.HibernateTransactionTemplateRetrying getHibernateTransactionTemplateRetrying(int retries) {
    return getDbConnector().getHibernateTransactionTemplateRetrying(retries);
  }
 
  /**
   * Gets the database dialect.
   *
   * @return the dialect, not null if correctly initialized
   */
  protected DbDialect getDialect() {
    return getDbConnector().getDialect();
  }

  //-------------------------------------------------------------------------
  /**
   * Gets the scheme in use for unique identifier.
   *
   * @return the scheme, not null
   */
  public String getUniqueIdScheme() {
    return _uniqueIdScheme;
  }

  /**
   * Sets the scheme in use for unique identifier.
   *
   * @param scheme  the scheme for unique identifier, not null
   */
  public void setUniqueIdScheme(final String scheme) {
    ArgumentChecker.notNull(scheme, "scheme");
    s_logger.debug("installed scheme: {}", scheme);
    _uniqueIdScheme = scheme;
  }

  /**
   * Checks the unique identifier scheme is valid.
   *
   * @param objectId  the object identifier, not null
   */
  protected void checkScheme(final ObjectIdentifiable objectId) {
    if (getUniqueIdScheme().equals(objectId.getObjectId().getScheme()) == false) {
      throw new IllegalArgumentException("UniqueId is not from this master (" + toString() + "): " + objectId);
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Extracts the row identifier.
   *
   * @param id  the identifier to extract from, not null
   * @return the extracted row id
   */
  protected long extractRowId(final UniqueId id) {
    try {
      return Long.parseLong(id.getValue()) + Long.parseLong(id.getVersion());
    } catch (NumberFormatException ex) {
      throw new IllegalArgumentException("UniqueId is not from this master (non-numeric row id): " + id, ex);
    }
  }

  /**
   * Extracts the object identifier.
   *
   * @param objectId  the identifier to extract from, not null
   * @return the extracted oid
   */
  protected long extractOid(final ObjectIdentifiable objectId) {
    try {
      return Long.parseLong(objectId.getObjectId().getValue());
    } catch (NumberFormatException ex) {
      throw new IllegalArgumentException("UniqueId is not from this master (non-numeric object id): " + objectId, ex);
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Creates an object identifier.
   *
   * @param oid  the object identifier
   * @return the unique identifier, not null
   */
  public UniqueId createObjectId(final long oid) {
    return UniqueId.of(getUniqueIdScheme(), Long.toString(oid));
  }

  /**
   * Creates a unique identifier.
   *
   * @param oid  the object identifier
   * @param rowId  the node unique row identifier, null if object identifier
   * @return the unique identifier, not null
   */
  public UniqueId createUniqueId(final long oid, final long rowId) {
    return UniqueId.of(getUniqueIdScheme(), Long.toString(oid), Long.toString(rowId - oid));
  }

  //-------------------------------------------------------------------------
  /**
   * Extracts a BigDecimal handling DB annoyances.
   *
   * @param rs  the result set, not null
   * @param columnName  the column name, not null
   * @return the extracted value, may be null
   * @throws SQLException
   */
  protected BigDecimal extractBigDecimal(final ResultSet rs, final String columnName) throws SQLException {
    BigDecimal value = rs.getBigDecimal(columnName);
    if (value == null) {
      return null;
    }
    BigDecimal stripped = value.stripTrailingZeros()// Derby, and maybe others, add trailing zeroes
    if (stripped.scale() < 0) {
      return stripped.setScale(0);
    }
    return stripped;
  }
 
  //-------------------------------------------------------------------------
  /**
   * Retrieves the version of the master schema from the database.
   * 
   * @return the schema version, or null if not found
   */
  public Integer getSchemaVersion() {
    try {
      final DbMapSqlParameterSource args = new DbMapSqlParameterSource().addValue("version_key", "schema_patch");
      final String sql = getElSqlBundle().getSql("GetSchemaVersion", args);
      String version = getJdbcTemplate().queryForObject(sql, args, String.class);
      return Integer.parseInt(version);
    } catch (Exception e) {
      s_logger.debug("Error reading schema version from database", e);
      return null;
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Returns a string summary of this master.
   *
   * @return the string summary, not null
   */
  @Override
  public String toString() {
    return getClass().getSimpleName() + "[" + getUniqueIdScheme() + "]";
  }

}
TOP

Related Classes of com.opengamma.masterdb.AbstractDbMaster

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.