Class Database

java.lang.Object
com.pyranid.Database

@ThreadSafe public final class Database extends Object
Main class for performing database access operations.
Since:
1.0.0
Author:
Mark Allen
  • Method Details

    • withDataSource

      public static @NonNull Database.Builder withDataSource(@NonNull DataSource dataSource)
      Provides a Database builder for the given DataSource.
      Parameters:
      dataSource - data source used to create the Database builder
      Returns:
      a Database builder
    • currentTransaction

      Gets a reference to the current transaction, if any.
      Returns:
      the current transaction
    • transaction

      public void transaction(@NonNull TransactionalOperation transactionalOperation)
      Performs an operation transactionally.

      The transaction will be automatically rolled back if an exception bubbles out of transactionalOperation.

      Nested calls to transaction(...) are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Use participate(Transaction, TransactionalOperation) to join an existing transaction explicitly. A transaction is scoped to the DataSource instance that created it; a Database using a different DataSource fails fast instead of joining it.

      Parameters:
      transactionalOperation - the operation to perform transactionally
    • transaction

      public void transaction(@NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation)
      Performs an operation transactionally with the given options.

      The transaction will be automatically rolled back if an exception bubbles out of transactionalOperation.

      Nested calls to transaction(...) are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Use participate(Transaction, TransactionalOperation) to join an existing transaction explicitly. A transaction is scoped to the DataSource instance that created it; a Database using a different DataSource fails fast instead of joining it.

      Parameters:
      transactionOptions - options to apply to the transaction
      transactionalOperation - the operation to perform transactionally
      Since:
      4.2.0
    • transaction

      public <T> @NonNull Optional<T> transaction(@NonNull ReturningTransactionalOperation<T> transactionalOperation)
      Performs an operation transactionally and optionally returns a value.

      The transaction will be automatically rolled back if an exception bubbles out of transactionalOperation.

      Nested calls to transaction(...) are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Use participate(Transaction, ReturningTransactionalOperation) to join an existing transaction explicitly. A transaction is scoped to the DataSource instance that created it; a Database using a different DataSource fails fast instead of joining it.

      Type Parameters:
      T - the type to be returned
      Parameters:
      transactionalOperation - the operation to perform transactionally
      Returns:
      the result of the transactional operation
    • transaction

      public <T> @NonNull Optional<T> transaction(@NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation)
      Performs an operation transactionally with the given options, optionally returning a value.

      The transaction will be automatically rolled back if an exception bubbles out of transactionalOperation.

      Nested calls to transaction(...) are independent transactions with independent JDBC connections; they do not automatically join an outer transaction. Use participate(Transaction, ReturningTransactionalOperation) to join an existing transaction explicitly. A transaction is scoped to the DataSource instance that created it; a Database using a different DataSource fails fast instead of joining it.

      Type Parameters:
      T - the type to be returned
      Parameters:
      transactionOptions - options to apply to the transaction
      transactionalOperation - the operation to perform transactionally
      Returns:
      the result of the transactional operation
      Since:
      4.2.0
    • transactionWithRetry

      public @NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionalOperation transactionalOperation)
      Performs an operation transactionally, retrying according to the given retry policy.

      The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.

      Unlike transaction(TransactionalOperation) and related transaction methods, retrying methods return TransactionRetryResult so callers can inspect failures that were recovered before success.

      This method fails fast if called inside an active transaction for this Database. Retrying a nested unit cannot restart the outer transaction safely.

      Parameters:
      retryPolicy - retry policy to apply
      transactionalOperation - the operation to perform transactionally
      Returns:
      retry result containing any failures retried before success
      Since:
      4.4.0
    • transactionWithRetry

      public @NonNull TransactionRetryResult<Void> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull TransactionalOperation transactionalOperation)
      Performs an operation transactionally with the given options, retrying according to the given retry policy.

      The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.

      Unlike transaction(TransactionOptions, TransactionalOperation) and related transaction methods, retrying methods return TransactionRetryResult so callers can inspect failures that were recovered before success.

      This method fails fast if called inside an active transaction for this Database. Retrying a nested unit cannot restart the outer transaction safely.

      Parameters:
      retryPolicy - retry policy to apply
      transactionOptions - options to apply to each transaction attempt
      transactionalOperation - the operation to perform transactionally
      Returns:
      retry result containing any failures retried before success
      Since:
      4.4.0
    • transactionWithRetry

      public <T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull ReturningTransactionalOperation<T> transactionalOperation)
      Performs an operation transactionally and optionally returns a value, retrying according to the given retry policy.

      The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.

      Unlike transaction(ReturningTransactionalOperation) and related transaction methods, retrying methods return TransactionRetryResult so callers can inspect failures that were recovered before success.

      This method fails fast if called inside an active transaction for this Database. Retrying a nested unit cannot restart the outer transaction safely.

      Type Parameters:
      T - the type to be returned
      Parameters:
      retryPolicy - retry policy to apply
      transactionalOperation - the operation to perform transactionally
      Returns:
      retry result containing the successful transaction value and any failures retried before success
      Since:
      4.4.0
    • transactionWithRetry

      public <T> @NonNull TransactionRetryResult<T> transactionWithRetry(@NonNull RetryPolicy retryPolicy, @NonNull TransactionOptions transactionOptions, @NonNull ReturningTransactionalOperation<T> transactionalOperation)
      Performs an operation transactionally with the given options and optionally returns a value, retrying according to the given retry policy.

      The entire transaction closure may run more than once. Keep non-idempotent external side effects outside the closure unless they are safe to repeat.

      Unlike transaction(TransactionOptions, ReturningTransactionalOperation) and related transaction methods, retrying methods return TransactionRetryResult so callers can inspect failures that were recovered before success.

      This method fails fast if called inside an active transaction for this Database. Retrying a nested unit cannot restart the outer transaction safely.

      Type Parameters:
      T - the type to be returned
      Parameters:
      retryPolicy - retry policy to apply
      transactionOptions - options to apply to each transaction attempt
      transactionalOperation - the operation to perform transactionally
      Returns:
      retry result containing the successful transaction value and any failures retried before success
      Since:
      4.4.0
    • participate

      public void participate(@NonNull Transaction transaction, @NonNull TransactionalOperation transactionalOperation)
      Performs an operation in the context of a pre-existing transaction.

      No commit or rollback on the transaction will occur when transactionalOperation completes.

      However, if an exception bubbles out of transactionalOperation, the transaction will be marked as rollback-only.

      The transaction must have been created by this Database, or by another Database using the same DataSource instance.

      If this thread is interrupted while waiting for another participant to release the transaction connection, Pyranid restores the interrupt flag and throws DatabaseException.

      Parameters:
      transaction - the transaction in which to participate
      transactionalOperation - the operation that should participate in the transaction
    • participate

      public <T> @NonNull Optional<T> participate(@NonNull Transaction transaction, @NonNull ReturningTransactionalOperation<T> transactionalOperation)
      Performs an operation in the context of a pre-existing transaction, optionally returning a value.

      No commit or rollback on the transaction will occur when transactionalOperation completes.

      However, if an exception bubbles out of transactionalOperation, the transaction will be marked as rollback-only.

      The transaction must have been created by this Database, or by another Database using the same DataSource instance.

      If this thread is interrupted while waiting for another participant to release the transaction connection, Pyranid restores the interrupt flag and throws DatabaseException.

      Type Parameters:
      T - the type to be returned
      Parameters:
      transaction - the transaction in which to participate
      transactionalOperation - the operation that should participate in the transaction
      Returns:
      the result of the transactional operation
    • query

      public @NonNull Query query(@NonNull String sql)
      Creates a fluent builder for executing SQL.

      Named parameters use the :paramName syntax and are bound via Query.bind(String, Object). Positional parameters via ? are not supported. Pyranid ignores parameter-looking text inside SQL string literals, quoted identifiers, comments, PostgreSQL dollar-quoted strings, and SQL Server-style bracket-quoted identifiers. PostgreSQL JSONB/hstore ?, ?|, and ?& operators are supported; when running against DatabaseType.POSTGRESQL, Pyranid emits pgjdbc's escaped ?? form automatically. Unterminated quotes and comments fail fast.

      Example:

      Optional<Employee> employee = database.query("SELECT * FROM employee WHERE id = :id")
        .bind("id", 42)
        .fetchObject(Employee.class);
      
      Parameters:
      sql - SQL containing :paramName placeholders
      Returns:
      a fluent builder for binding parameters and executing
      Since:
      4.0.0
    • performHealthCheck

      public void performHealthCheck(@NonNull Duration timeout)
      Performs a portable connectivity check using JDBC Connection.isValid(int).

      This method borrows a fresh connection from this database's DataSource, calls Connection.isValid(int), and closes the connection before returning. It does not participate in an active Pyranid transaction, if one exists.

      JDBC accepts timeout values in whole seconds. Positive sub-second durations are rounded up to one second; Duration.ZERO passes a timeout of 0 to the driver.

      Parameters:
      timeout - maximum time to wait for driver validation
      Throws:
      IllegalArgumentException - if timeout is negative or too large for JDBC's integer-second timeout
      DatabaseException - if connection acquisition fails, validation throws, or the driver reports the connection is not valid
      Since:
      4.2.0
    • readDatabaseMetaData

      public void readDatabaseMetaData(@NonNull DatabaseMetaDataReader databaseMetaDataReader)
      Exposes a temporary handle to JDBC DatabaseMetaData, which provides comprehensive vendor-specific information about this database as a whole.

      This method acquires DatabaseMetaData on its own newly-borrowed connection, which it manages internally.

      It does not participate in the active transaction, if one exists.

      The connection is closed as soon as DatabaseMetaDataReader.read(DatabaseMetaData) completes.

      See DatabaseMetaData Javadoc for details.

    • useRawConnection

      public <T> @NonNull Optional<T> useRawConnection(@NonNull RawConnectionOperation<T> rawConnectionOperation)
      Performs raw JDBC work with a Pyranid-managed Connection.

      If called inside a Pyranid transaction, this operation uses the transaction's connection and participates in that transaction. Otherwise, Pyranid borrows a connection for the duration of the callback and closes it afterwards.

      The Connection passed to rawConnectionOperation is a guarded handle. Normal JDBC operations are delegated to the underlying driver connection, but lifecycle, transaction-management, and connection-wide state methods such as Connection.close(), Connection.commit(), Connection.rollback(), Connection.setAutoCommit(boolean), Connection.setCatalog(String), Connection.setSchema(String), and Connection.setNetworkTimeout(java.util.concurrent.Executor, int) throw IllegalStateException. Use Pyranid transaction APIs instead. JDBC objects created from this handle are also guarded: Statement.getConnection() and DatabaseMetaData.getConnection() return the Pyranid-managed handle, and ResultSet.getStatement() returns a guarded statement. Guarded statements, resultsets, and metadata refuse driver-specific unwrap(...) calls that could expose the driver's underlying connection.

      The connection handle is valid only for the duration of the callback. Do not close it, retain it, or use it after this method returns.

      Type Parameters:
      T - the type to be returned
      Parameters:
      rawConnectionOperation - the raw JDBC operation to perform
      Returns:
      the operation result
      Throws:
      DatabaseException - if connection acquisition, callback execution, or cleanup fails
      Since:
      4.2.0
    • getDatabaseType

      public @NonNull DatabaseType getDatabaseType()
      Gets the database type for this database.

      If Database.Builder.databaseType(DatabaseType) was not configured and the database type has not already been detected, this method may acquire a connection and inspect DatabaseMetaData. Configure an explicit database type to avoid runtime detection.

      Returns:
      the database type
      Throws:
      DatabaseException - if automatic database type detection fails
      Since:
      3.0.0
    • getTimeZone

      public @NonNull ZoneId getTimeZone()
      Since:
      3.0.0
    • getAmbiguousTimestampBindingStrategy

      How should Pyranid bind Instant and OffsetDateTime parameters when JDBC parameter metadata cannot identify whether the target is TIMESTAMP or TIMESTAMP WITH TIME ZONE?
      Returns:
      behavior to use when timestamp target metadata is unavailable or non-identifying
      Since:
      4.2.0
    • getParameterRedactor

      Gets the configured redactor used for non-secure parameters in diagnostics.
      Returns:
      the configured parameter redactor
      Since:
      4.4.0
    • getMetricsCollector