Package com.j256.ormlite.support

Source Code of com.j256.ormlite.support.BaseConnectionSource$NestedConnection

package com.j256.ormlite.support;

import java.sql.SQLException;

import com.j256.ormlite.logger.Logger;

/**
* Connection source base class which provides the save/clear mechanism using a thread local.
*
* @author graywatson
*/
public abstract class BaseConnectionSource implements ConnectionSource {

  protected boolean usedSpecialConnection = false;
  private ThreadLocal<NestedConnection> specialConnection = new ThreadLocal<NestedConnection>();

  public DatabaseConnection getSpecialConnection() {
    return getSpecial();
  }

  /**
   * Returns the connection that has been saved or null if none.
   */
  protected DatabaseConnection getSavedConnection() throws SQLException {
    if (!usedSpecialConnection) {
      return null;
    }
    NestedConnection nested = specialConnection.get();
    if (nested == null) {
      return null;
    } else {
      return nested.connection;
    }
  }

  /**
   * Return true if the connection being released is the one that has been saved.
   */
  protected boolean isSavedConnection(DatabaseConnection connection) throws SQLException {
    if (!usedSpecialConnection) {
      return false;
    }
    NestedConnection currentSaved = specialConnection.get();
    if (currentSaved == null) {
      return false;
    } else if (currentSaved.connection == connection) {
      // ignore the release when we have a saved connection
      return true;
    } else {
      return false;
    }
  }

  /**
   * Save this connection as our special connection to be returned by the {@link #getSavedConnection()} method.
   *
   * @return True if the connection was saved or false if it was already saved.
   */
  protected boolean saveSpecial(DatabaseConnection connection) throws SQLException {
    // check for a connection already saved
    NestedConnection currentSaved = specialConnection.get();
    if (currentSaved == null) {
      /*
       * This is fine to not be synchronized since it is only this thread we care about. Other threads will set
       * this or have it synchronized in over time.
       */
      usedSpecialConnection = true;
      specialConnection.set(new NestedConnection(connection));
      return true;
    } else {
      if (currentSaved.connection != connection) {
        throw new SQLException("trying to save connection " + connection
            + " but already have saved connection " + currentSaved.connection);
      }
      // we must have a save call within another save
      currentSaved.increment();
      return false;
    }
  }

  /**
   * Clear the connection that was previously saved.
   *
   * @return True if the connection argument had been saved.
   */
  protected boolean clearSpecial(DatabaseConnection connection, Logger logger) {
    NestedConnection currentSaved = specialConnection.get();
    boolean cleared = false;
    if (currentSaved == null) {
      logger.error("no connection has been saved when clear() called");
    } else if (currentSaved.connection == connection) {
      if (currentSaved.decrementAndGet() == 0) {
        // we only clear the connection if nested counter is 0
        specialConnection.set(null);
      }
      cleared = true;
    } else {
      logger.error("connection saved {} is not the one being cleared {}", currentSaved.connection, connection);
    }
    // release should then be called after clear
    return cleared;
  }

  /**
   * Get the currently saved.
   */
  protected DatabaseConnection getSpecial() {
    NestedConnection currentSaved = specialConnection.get();
    if (currentSaved == null) {
      return null;
    } else {
      return currentSaved.connection;
    }
  }

  private static class NestedConnection {
    public final DatabaseConnection connection;
    private int nestedC;

    public NestedConnection(DatabaseConnection connection) {
      this.connection = connection;
      this.nestedC = 1;
    }

    public void increment() {
      nestedC++;
    }

    public int decrementAndGet() {
      nestedC--;
      return nestedC;
    }
  }
}
TOP

Related Classes of com.j256.ormlite.support.BaseConnectionSource$NestedConnection

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.