alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Database.scala)

This example Scala source code file (Database.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

boolean, boolean, closed, closed, connection, connection, database, jdbc, list, nil, nil, none, sql, throwable, unit, vendor

The Scala Database.scala source code

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */



package scala.dbc


import java.sql._

/** A link to a database. The <code>Database abstract class must
 *  be specialised for every different DBMS.
 *
 *  @author  Gilles Dubochet
 */
@deprecated(DbcIsDeprecated, "2.9.0") 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.filterNot(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)
    }
  }
  
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Database.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.