database.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 189 行

SCALA
189
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2003-2007, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id:Database.scala 6853 2006-03-20 16:58:47 +0100 (Mon, 20 Mar 2006) dubochet $package scala.dbcimport java.sql._/** A link to a database. The <code>Database</code> abstract class must *  be specialised for every different DBMS. * *  @author  Gilles Dubochet */case class Database(dbms: Vendor) {    class Closed extends Exception {}    /** A lock used for operations that need to be atomic for this database   *  instance. */  private val lock: scala.concurrent.Lock = new scala.concurrent.Lock()  /** The vendor of the DBMS that contains this database. */  private val vendor: Vendor = dbms  /** The Database connections available to use. */  private var availableConnections: List[Connection] = Nil  /** The connections that are currently in use. */  private var usedConnections: List[Connection] = Nil  /** Whether the database no longer accepts new connections. */  private var closing: Boolean = false;    /** Retrieves a connection from the available connection pool or creates   *  a new one.   *   *  @return A connection that can be used to access the database.   */  private def getConnection: Connection = {    if (closing) {      throw new Closed;    } else {      availableConnections match {        case Nil => {          lock.acquire;          val connection = vendor.getConnection;          usedConnections = connection :: usedConnections;          lock.release;          connection        }        case connection :: cs => {          lock.acquire;          availableConnections = cs;          usedConnections = connection :: usedConnections;          lock.release;          connection;        }      }    }  }    /** Closes a connection to this database. A closed connection might   *  also return to the available connection pool if the latter is depleted.   *   *  @param connection The connection that should be closed.   */  private def closeConnection(connection: Connection): Unit = {    if (closing) {      connection.close()    } else {      lock.acquire      usedConnections = usedConnections.remove(e => (e.equals(connection)));      if (availableConnections.length < vendor.retainedConnections)        availableConnections = connection :: availableConnections      else        connection.close()      lock.release    }  }  /** ..   */  def close {    closing = true    for (conn <- availableConnections) conn.close()  }  /** Executes a statement that returns a relation on this database.   *   *  @param  relationStatement The statement to execute.   *  @return The relation returned by the database for this statement.   */  def executeStatement(relationStatement: statement.Relation): result.Relation =    executeStatement(relationStatement, false);  /** Executes a statement that returns a relation on this database.   *   *  @param relationStatement The statement to execute.   *  @param debug Whether debugging information should be printed on the console.   *  @return The relation returned by the database for this statement.   */  def executeStatement(relationStatement: statement.Relation,                       debug: Boolean): result.Relation =    new scala.dbc.result.Relation {      val statement = relationStatement      if (debug) Console.println("## " + statement.sqlString)      private val connection = getConnection      val sqlResult = connection.createStatement().executeQuery(statement.sqlString)      closeConnection(connection)      statement.typeCheck(this)    }    /** Executes a statement that updates the state of the database.    * @param statusStatement The statement to execute.    * @return The status of the database after the statement has been executed. */  def executeStatement(statusStatement: statement.Status): result.Status[Unit] =    executeStatement(statusStatement, false);  /** Executes a statement that updates the state of the database.   *   *  @param  statusStatement The statement to execute.   *  @param  debug Whether debugging information should be printed on the console.   *  @return The status of the database after the statement has been executed.   */  def executeStatement(statusStatement: statement.Status,                       debug: Boolean): result.Status[Unit] =    new scala.dbc.result.Status[Unit] {      val statement = statusStatement;      if (debug) Console.println("## " + statement.sqlString);      def result = ();      private val connection = getConnection;      val jdbcStatement: java.sql.Statement = connection.createStatement();      jdbcStatement.execute(statement.sqlString);      val touchedCount = Some(jdbcStatement.getUpdateCount());      closeConnection(connection);    }    /** Executes a list of statements or other operations inside a transaction.   *  Only statements are protected in a transaction, other Scala code is not.   *   *  @param  transactionStatement The transaction to execute as a closure.   *  @return The status of the database after the transaction has been executed.   */  def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType]): result.Status[ResultType] =    executeStatement(transactionStatement, false);    /** Executes a list of statements or other operations inside a transaction.   *  Only statements are protected in a transaction, other Scala code is not.   *   *  @param  transactionStatement The transaction to execute as a closure.   *  @param  debug Whether debugging information should be printed on the console.   *  @return The status of the database after the transaction has been executed.   */  def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType], debug: Boolean): result.Status[ResultType] = {    new scala.dbc.result.Status[ResultType] {      val touchedCount = None      val statement = transactionStatement      private val connection = getConnection      connection.setAutoCommit(false)      val jdbcStatement: java.sql.Statement = connection.createStatement();      if (debug) Console.println("## " + transactionStatement.sqlStartString);      jdbcStatement.execute(transactionStatement.sqlStartString);      val result: ResultType = try {        val buffer = transactionStatement.transactionBody(Database.this);        if (debug) Console.println("## " + transactionStatement.sqlCommitString);        jdbcStatement.execute(transactionStatement.sqlCommitString);        buffer      } catch {        case e: Throwable => {          if (debug) Console.println("## " + transactionStatement.sqlAbortString);          jdbcStatement.execute(transactionStatement.sqlAbortString);          throw e        }      }      connection.setAutoCommit(true)      closeConnection(connection)    }  }  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?