
play.api.db.DB.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2009-2013 Typesafe Inc.
*/
package play.api.db
import scala.language.reflectiveCalls
import play.api._
import java.sql._
import javax.sql._
import scala.util.control.{ NonFatal, ControlThrowable }
/**
* The Play Database API manages several connection pools.
*/
trait DBApi {
val datasources: List[(DataSource, String)]
/**
* Shutdown pool for given datasource
*/
def shutdownPool(ds: DataSource)
/**
* Retrieves a JDBC connection, with auto-commit set to `true`.
*
* Don't forget to release the connection at some point by calling close().
*
* @param name the data source name
* @return a JDBC connection
* @throws Throwable an error if the required data source is not registered
*/
def getDataSource(name: String): DataSource
/**
* Retrieves the JDBC connection URL for a particular data source.
*
* @param name the data source name
* @return The JDBC URL connection string, i.e. `jdbc:...`
* @throws Throwable an error if the required data source is not registered
*/
def getDataSourceURL(name: String): String = {
val connection = getDataSource(name).getConnection
val url = connection.getMetaData.getURL
connection.close()
url
}
/**
* Retrieves a JDBC connection.
*
* Don't forget to release the connection at some point by calling close().
*
* @param name the data source name
* @param autocommit when `true`, sets this connection to auto-commit
* @return a JDBC connection
* @throws Throwable an error if the required data source is not registered
*/
def getConnection(name: String, autocommit: Boolean = true): Connection = {
val connection = getDataSource(name).getConnection
connection.setAutoCommit(autocommit)
connection
}
/**
* Execute a block of code, providing a JDBC connection. The connection and all created statements are
* automatically released.
*
* @param name The datasource name.
* @param block Code block to execute.
*/
def withConnection[A](name: String)(block: Connection => A): A = {
val connection = getConnection(name)
try {
block(connection)
} finally {
connection.close()
}
}
/**
* Execute a block of code, in the scope of a JDBC transaction.
* The connection and all created statements are automatically released.
* The transaction is automatically committed, unless an exception occurs.
*
* @param name The datasource name.
* @param block Code block to execute.
*/
def withTransaction[A](name: String)(block: Connection => A): A = {
withConnection(name) { connection =>
try {
connection.setAutoCommit(false)
val r = block(connection)
connection.commit()
r
} catch {
case e: ControlThrowable =>
connection.commit(); throw e
case NonFatal(e) => connection.rollback(); throw e
}
}
}
}
/**
* Provides a high-level API for getting JDBC connections.
*
* For example:
* {{{
* val conn = DB.getConnection("customers")
* }}}
*/
object DB {
/** The exception we are throwing. */
private def error = throw new Exception("DB plugin is not registered.")
/**
* Retrieves a JDBC connection.
*
* @param name data source name
* @param autocommit when `true`, sets this connection to auto-commit
* @return a JDBC connection
* @throws Throwable an error if the required data source is not registered
*/
def getConnection(name: String = "default", autocommit: Boolean = true)(implicit app: Application): Connection = app.plugin[DBPlugin].map(_.api.getConnection(name, autocommit)).getOrElse(error)
/**
* Retrieves a JDBC connection (autocommit is set to true).
*
* @param name data source name
* @return a JDBC connection
* @throws Throwable an error if the required data source is not registered
*/
def getDataSource(name: String = "default")(implicit app: Application): DataSource = app.plugin[DBPlugin].map(_.api.getDataSource(name)).getOrElse(error)
/**
* Execute a block of code, providing a JDBC connection. The connection is
* automatically released.
*
* @param name The datasource name.
* @param block Code block to execute.
*/
def withConnection[A](name: String)(block: Connection => A)(implicit app: Application): A = {
app.plugin[DBPlugin].map(_.api.withConnection(name)(block)).getOrElse(error)
}
/**
* Execute a block of code, providing a JDBC connection. The connection and all created statements are
* automatically released.
*
* @param block Code block to execute.
*/
def withConnection[A](block: Connection => A)(implicit app: Application): A = {
app.plugin[DBPlugin].map(_.api.withConnection("default")(block)).getOrElse(error)
}
/**
* Execute a block of code, in the scope of a JDBC transaction.
* The connection and all created statements are automatically released.
* The transaction is automatically committed, unless an exception occurs.
*
* @param name The datasource name.
* @param block Code block to execute.
*/
def withTransaction[A](name: String = "default")(block: Connection => A)(implicit app: Application): A =
app.plugin[DBPlugin].map(_.api.withTransaction(name)(block)).getOrElse(error)
/**
* Execute a block of code, in the scope of a JDBC transaction.
* The connection and all created statements are automatically released.
* The transaction is automatically committed, unless an exception occurs.
*
* @param block Code block to execute.
*/
def withTransaction[A](block: Connection => A)(implicit app: Application): A =
app.plugin[DBPlugin].map(_.api.withTransaction("default")(block)).getOrElse(error)
}
/**
* Generic DBPlugin interface
*/
trait DBPlugin extends Plugin {
def api: DBApi
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy