All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rdbc.sapi.Connection.scala Maven / Gradle / Ivy

There is a newer version: 0.0.82
Show newest version
/*
 * Copyright 2016 rdbc contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.rdbc.sapi

import scala.concurrent.Future

/** Represents a database connection (session).
  *
  * Instances of implementations of this trait can be obtained using a
  * [[ConnectionFactory]]. When clients are done with the connection, they are
  * required to call a `release` method co clean up resources such as open sockets.
  *
  * Invoking any method of this trait when any previous operation has not
  * completed yet is not allowed. Operation is considered complete when a resulting
  * [[scala.concurrent.Future Future]] completes.
  *
  * Transaction management has to be done using `beginTx`, `commitTx` and
  * `rollbackTx` methods. Using SQL statements to manage transaction state is
  * not allowed.
  *
  * [[SqlWithParams]] instances passed to `Connection`'s methods can be created
  * using `sql` string interpolator, for example:
  * {{{
  *   import io.rdbc.sapi._
  *
  *   val conn: Connection = ???
  *   val login = "jdoe"
  *   conn.statement(sql"select * from users where login = \$login").executeForStream()
  * }}}
  *
  * Alternatively, when bare Strings are used as SQL statements, parameters
  * are specified by name. Parameter name is an alphanumeric string starting
  * with a letter, prefixed with a colon. Example:
  *
  * {{{
  *   import io.rdbc.sapi._
  *
  *   val conn: Connection = ???
  *   val login = "jdoe"
  *   conn.statement(sql"select * from users where login = :login")
  *       .bind("login" -> login)
  *       .executable.executeForStream()
  * }}}
  *
  * @groupname tx Transaction management
  * @groupprio tx 10
  * @groupname stmtInter Statement producers (string interpolation)
  * @groupprio stmtInter 20
  * @groupname stmtBare Statement producers (bare strings)
  * @groupprio stmtBare 30
  * @define timeoutInfo
  *  After the operation takes longer time than `timeout`, operation will be
  *  aborted. Note however, that it may not be feasible to abort the operation
  *  immediately.
  * @define statementExceptions
  * Throws:
  *  - [[io.rdbc.sapi.exceptions.MixedParamTypesException MixedParamTypesException]]
  *  when statement uses both positional and named parameters
  *  - [[io.rdbc.sapi.exceptions.UncategorizedRdbcException UncategorizedRdbcException]]
  *  when general error occurs
  * @define timeoutException
  *  - [[io.rdbc.sapi.exceptions.TimeoutException TimeoutException]]
  *  when maximum operation time has been exceeded
  * @define bindExceptions
  *  - [[io.rdbc.sapi.exceptions.MissingParamValException MissingParamValException]]
  *  when some parameter value was not provided
  *  - [[io.rdbc.sapi.exceptions.NoSuitableConverterFoundException NoSuitableConverterFoundException]]
  *  when some parameter value's type is not convertible to a database type
  * @define statementParametrization
  *  For syntax of statement parametrization see a [[Connection]] documentation.
  * @define interpolatorExample
  *  [[SqlWithParams]] parameter instance is meant to be constructed using `sql`
  *  string interpolator, for example:
  *  {{{
  *      import io.rdbc.sapi.Interpolators._
  *      val x = 1
  *      val y = 10
  *      val stmt = conn.statement(sql"select * from table where colx > \$x and coly < \$y")
  *  }}}
  * @define withTransaction
  * Executes a function (which can be passed as a code block) in a context
  * of a transaction. Before the function is executed, transaction is started.
  * After the function finishes, transaction is committed in case of a success
  * and rolled back in case of a failure.
  *
  * Because managing transaction state requires invoking functions that
  * require specifying a timeout, this function requires an implicit timeout
  * instance.
  */
trait Connection {

  /** Begins a database transaction.
    *
    * Using this method is a preferred way of starting a transaction, using SQL
    * statements to manage transaction state may lead to undefined behavior.
    *
    * $timeoutInfo
    *
    * Returned future can fail with:
    *  - [[io.rdbc.sapi.exceptions.BeginTxException BeginTxException]]
    * when general error occurs
    * $timeoutException
    *
    * @group tx
    */
  def beginTx()(implicit timeout: Timeout): Future[Unit]

  /** Commits a database transaction.
    *
    * Using this method is a preferred way of committing a transaction, using
    * SQL statements to manage transaction state may lead to undefined behavior.
    *
    * $timeoutInfo
    *
    * Returned future can fail with:
    *  - [[io.rdbc.sapi.exceptions.BeginTxException CommmitTxException]]
    * when general error occurs
    * $timeoutException
    *
    * @group tx
    */
  def commitTx()(implicit timeout: Timeout): Future[Unit]

  /** Rolls back a database transaction.
    *
    * Using this method is a preferred way of rolling back a transaction, using
    * SQL statements to manage transaction state may lead to undefined behavior.
    *
    * $timeoutInfo
    *
    * Returned future can fail with:
    *  - [[io.rdbc.sapi.exceptions.BeginTxException RollbackTxException]]
    * when general error occurs
    * $timeoutException
    *
    * @group tx
    */
  def rollbackTx()(implicit timeout: Timeout): Future[Unit]

  /** Executes a function in a context of a transaction.
    *
    * $withTransaction
    */
  def withTransaction[A](body: => Future[A])
                        (implicit timeout: Timeout): Future[A]

  /** Releases the connection and underlying resources.
    *
    * Only idle connections can be released using this method. To forcibly
    * release the connection use [[forceRelease]] method.
    *
    * After calling this method no future operations on the instance are allowed.
    *
    * Returned future can fail with:
    *  - [[io.rdbc.sapi.exceptions.ConnectionReleaseException ConnectionReleaseException]]
    * when general error occurs
    */
  def release(): Future[Unit]

  /** Releases the connection and underlying resources regardless of whether
    * the connection is currently in use or not.
    *
    * After calling this method no future operations on the instance are allowed.
    *
    * Returned future can fail with:
    *  - [[io.rdbc.sapi.exceptions.ConnectionReleaseException ConnectionReleaseException]]
    * when general error occurs
    */
  def forceRelease(): Future[Unit]

  /** Checks whether the connection is still usable.
    *
    * If checking takes longer than `timeout`, connection is considered unusable.
    *
    * @return Successful future of `unit` iff connection is usable, future failed
    *         with ConnectionValidationException otherwise.
    */
  def validate()(implicit timeout: Timeout): Future[Unit]

  /** Returns a [[Statement]] instance bound to this connection that
    * represents any SQL statement.
    *
    * $statementParametrization
    *
    * $statementExceptions
    *
    * @group stmtBare
    */
  def statement(sql: String, statementOptions: StatementOptions): Statement

  /** Returns a [[Statement]] instance bound to this connection that
    * represents any SQL statement.
    *
    * $statementParametrization
    *
    * $statementExceptions
    *
    * @group stmtBare
    */
  def statement(sql: String): Statement

  /** Returns a [[ExecutableStatement]] instance bound to this connection
    * that represents any parametrized SQL statement.
    *
    * It's a shortcut for calling `statement` and then `bind`.
    *
    * $interpolatorExample
    *
    * $statementExceptions
    * $bindExceptions
    *
    * @group stmtInter
    */
  def statement(sqlWithParams: SqlWithParams, statementOptions: StatementOptions): ExecutableStatement

  /** Returns a [[ExecutableStatement]] instance bound to this connection
    * that represents any parametrized SQL statement.
    *
    * It's a shortcut for calling `statement` and then `bind`.
    *
    * $interpolatorExample
    *
    * $statementExceptions
    * $bindExceptions
    *
    * @group stmtInter
    */
  def statement(sqlWithParams: SqlWithParams): ExecutableStatement

  /** Returns a future that is complete when this connection is idle and ready
    * for accepting queries. */
  def watchForIdle: Future[Unit]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy