Refactoring
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import Foundation
|
||||
import DataLiteCore
|
||||
|
||||
/// A type that provides encryption keys to a database connection service.
|
||||
///
|
||||
/// ## Overview
|
||||
///
|
||||
/// This type manages how encryption keys are obtained and applied when establishing or restoring a
|
||||
/// connection. Implementations can use static, dynamic, hardware-backed, or biometric key sources.
|
||||
///
|
||||
/// - The service requests a key when establishing or restoring a connection.
|
||||
/// - If decryption fails, the service may ask whether it should attempt to reconnect.
|
||||
/// - If applying a key fails (for example, the key is invalid or ``connectionService(keyFor:)``
|
||||
/// throws), the error is reported through ``connectionService(_:didReceive:)``.
|
||||
///
|
||||
/// - Important: The provider does not receive general database errors.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Providing Keys and Handling Errors
|
||||
///
|
||||
/// - ``connectionService(keyFor:)``
|
||||
/// - ``connectionService(shouldReconnect:)``
|
||||
/// - ``connectionService(_:didReceive:)``
|
||||
public protocol ConnectionServiceKeyProvider: AnyObject, Sendable {
|
||||
/// Returns the encryption key for the specified database service.
|
||||
///
|
||||
/// - Parameter service: The service requesting the key.
|
||||
/// - Returns: The encryption key.
|
||||
/// - Throws: An error if the key cannot be retrieved.
|
||||
func connectionService(keyFor service: ConnectionServiceProtocol) throws -> Connection.Key
|
||||
|
||||
/// Indicates whether the service should attempt to reconnect if applying the key fails.
|
||||
///
|
||||
/// - Parameter service: The database service.
|
||||
/// - Returns: `true` to attempt reconnection. Defaults to `false`.
|
||||
func connectionService(shouldReconnect service: ConnectionServiceProtocol) -> Bool
|
||||
|
||||
/// Notifies the provider of an error that occurred during key retrieval or application.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - service: The database service reporting the error.
|
||||
/// - error: The error encountered during key retrieval or application.
|
||||
func connectionService(_ service: ConnectionServiceProtocol, didReceive error: Error)
|
||||
}
|
||||
56
Sources/DataRaft/Protocols/ConnectionServiceProtocol.swift
Normal file
56
Sources/DataRaft/Protocols/ConnectionServiceProtocol.swift
Normal file
@@ -0,0 +1,56 @@
|
||||
import Foundation
|
||||
import DataLiteCore
|
||||
|
||||
/// A type that manages the lifecycle of a database connection.
|
||||
///
|
||||
/// ## Overview
|
||||
///
|
||||
/// Conforming types implement the mechanisms required to open, configure, reconnect, and safelyuse
|
||||
/// a database connection across multiple threads or tasks. This abstraction allows higher-level
|
||||
/// services to execute operations without dealing with low-level connection handling.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Key Management
|
||||
///
|
||||
/// - ``ConnectionServiceKeyProvider``
|
||||
/// - ``keyProvider``
|
||||
///
|
||||
/// ### Connection Lifecycle
|
||||
///
|
||||
/// - ``setNeedsReconnect()``
|
||||
///
|
||||
/// ### Performing Operations
|
||||
///
|
||||
/// - ``Perform``
|
||||
/// - ``perform(_:)``
|
||||
public protocol ConnectionServiceProtocol: AnyObject, Sendable {
|
||||
/// A closure type that performs an operation using an active database connection.
|
||||
///
|
||||
/// - Parameter connection: The active database connection used for the operation.
|
||||
/// - Returns: The result produced by the closure.
|
||||
/// - Throws: Any error thrown by the closure or connection layer.
|
||||
typealias Perform<T> = (ConnectionProtocol) throws -> T
|
||||
|
||||
/// The provider responsible for supplying encryption keys to the service.
|
||||
var keyProvider: ConnectionServiceKeyProvider? { get set }
|
||||
|
||||
/// Marks the service as requiring reconnection before the next operation.
|
||||
///
|
||||
/// The reconnection behavior depends on the key provider’s implementation of
|
||||
/// ``ConnectionServiceKeyProvider/connectionService(shouldReconnect:)``.
|
||||
///
|
||||
/// - Returns: `true` if the reconnection flag was set; otherwise, `false`.
|
||||
@discardableResult
|
||||
func setNeedsReconnect() -> Bool
|
||||
|
||||
/// Executes a closure within the context of an active database connection.
|
||||
///
|
||||
/// Implementations ensure that a valid connection is available before executing the operation.
|
||||
/// If the connection is not available or fails, this method throws an error.
|
||||
///
|
||||
/// - Parameter closure: The operation to perform using the connection.
|
||||
/// - Returns: The result produced by the closure.
|
||||
/// - Throws: Any error thrown by the closure or the underlying connection.
|
||||
func perform<T>(_ closure: Perform<T>) throws -> T
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import Foundation
|
||||
import DataLiteCore
|
||||
|
||||
/// A protocol for providing encryption keys to a database service.
|
||||
///
|
||||
/// `DatabaseServiceKeyProvider` is responsible for managing encryption keys used
|
||||
/// by a database service. This makes it possible to implement different strategies for storing
|
||||
/// and retrieving keys: static, dynamic, hardware-backed, biometric, and others.
|
||||
///
|
||||
/// - The service requests a key when establishing or restoring a connection.
|
||||
/// - If decryption fails, the service may ask the provider whether it should attempt to reconnect.
|
||||
/// - If applying a key fails (for example, the key does not match or the
|
||||
/// ``databaseService(keyFor:)`` method throws an error), this error is reported
|
||||
/// to the provider through ``databaseService(_:didReceive:)``.
|
||||
///
|
||||
/// - Important: The provider does not receive notifications about general database errors.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Instance Methods
|
||||
///
|
||||
/// - ``databaseService(keyFor:)``
|
||||
/// - ``databaseService(shouldReconnect:)``
|
||||
/// - ``databaseService(_:didReceive:)``
|
||||
public protocol DatabaseServiceKeyProvider: AnyObject, Sendable {
|
||||
/// Returns the encryption key for the specified database service.
|
||||
///
|
||||
/// This method must either return a valid encryption key or throw an error if
|
||||
/// the key cannot be retrieved.
|
||||
///
|
||||
/// - Parameter service: The service requesting the key.
|
||||
/// - Returns: The encryption key.
|
||||
/// - Throws: An error if the key cannot be retrieved.
|
||||
func databaseService(keyFor service: DatabaseServiceProtocol) throws -> Connection.Key
|
||||
|
||||
/// Indicates whether the service should attempt to reconnect if applying the key fails.
|
||||
///
|
||||
/// - Parameter service: The database service.
|
||||
/// - Returns: `true` to attempt reconnection. Defaults to `false`.
|
||||
func databaseService(shouldReconnect service: DatabaseServiceProtocol) -> Bool
|
||||
|
||||
/// Notifies the provider of an error that occurred while retrieving or applying the key.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - service: The database service reporting the error.
|
||||
/// - error: The error encountered during key retrieval or application.
|
||||
func databaseService(_ service: DatabaseServiceProtocol, didReceive error: Error)
|
||||
}
|
||||
|
||||
public extension DatabaseServiceKeyProvider {
|
||||
func databaseService(shouldReconnect service: DatabaseServiceProtocol) -> Bool { false }
|
||||
func databaseService(_ service: DatabaseServiceProtocol, didReceive error: Error) {}
|
||||
}
|
||||
@@ -1,67 +1,45 @@
|
||||
import Foundation
|
||||
import DataLiteCore
|
||||
|
||||
/// A protocol for a database service.
|
||||
/// A type that extends connection management with transactional database operations.
|
||||
///
|
||||
/// `DatabaseServiceProtocol` defines the core capabilities required for
|
||||
/// reliable interaction with a database. Conforming implementations provide
|
||||
/// execution of client closures with a live connection, transaction wrapping,
|
||||
/// reconnection logic, and flexible encryption key management.
|
||||
/// ## Overview
|
||||
///
|
||||
/// This enables building safe and extensible service layers on top of
|
||||
/// a database.
|
||||
/// This type builds on ``ConnectionServiceProtocol`` by adding the ability to execute closures
|
||||
/// within explicit transactions. Conforming types manage transaction boundaries and ensure that all
|
||||
/// operations within a transaction are committed or rolled back consistently.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Key Management
|
||||
/// ### Performing Operations
|
||||
///
|
||||
/// - ``DatabaseServiceKeyProvider``
|
||||
/// - ``keyProvider``
|
||||
///
|
||||
/// ### Database Operations
|
||||
///
|
||||
/// - ``Perform``
|
||||
/// - ``perform(_:)``
|
||||
/// - ``ConnectionServiceProtocol/Perform``
|
||||
/// - ``perform(in:closure:)``
|
||||
public protocol DatabaseServiceProtocol: AnyObject, Sendable {
|
||||
/// A closure executed with an active database connection.
|
||||
public protocol DatabaseServiceProtocol: ConnectionServiceProtocol {
|
||||
/// Executes a closure inside a transaction if the connection is in autocommit mode.
|
||||
///
|
||||
/// Used by the service to safely provide access to `Connection`
|
||||
/// within the appropriate execution context.
|
||||
/// If the connection operates in autocommit mode, this method starts a new transaction of the
|
||||
/// specified type, executes the closure, and commits the changes on success. If the closure
|
||||
/// throws an error, the transaction is rolled back.
|
||||
///
|
||||
/// - Parameter connection: The active database connection.
|
||||
/// - Returns: The value returned by the closure.
|
||||
/// - Throws: An error if the closure execution fails.
|
||||
typealias Perform<T> = (Connection) throws -> T
|
||||
|
||||
/// The encryption key provider for the database service.
|
||||
/// Implementations may attempt to re-establish the connection and reapply the encryption key if
|
||||
/// an error indicates a lost or invalid database state (for example, `SQLiteError` with code
|
||||
/// `SQLITE_NOTADB`). In such cases, the service can retry the transaction block once after a
|
||||
/// successful reconnection. If reconnection fails or is disallowed by the key provider, the
|
||||
/// original error is propagated.
|
||||
///
|
||||
/// Enables external management of encryption keys.
|
||||
/// When set, the service can request a key when establishing or
|
||||
/// restoring a connection, and can also notify about errors
|
||||
/// encountered while applying a key.
|
||||
var keyProvider: DatabaseServiceKeyProvider? { get set }
|
||||
|
||||
/// Executes the given closure with an active connection.
|
||||
///
|
||||
/// The closure receives the connection and may perform any
|
||||
/// database operations within the current context.
|
||||
///
|
||||
/// - Parameter closure: The closure that accepts a connection.
|
||||
/// - Returns: The value returned by the closure.
|
||||
/// - Throws: An error if one occurs during closure execution.
|
||||
func perform<T>(_ closure: Perform<T>) throws -> T
|
||||
|
||||
/// Executes the given closure within a transaction.
|
||||
///
|
||||
/// If the connection is in autocommit mode, the method automatically
|
||||
/// begins a transaction, executes the closure, and commits the changes.
|
||||
/// In case of failure, the transaction is rolled back.
|
||||
/// If a transaction is already active, the closure is executed directly without starting a new
|
||||
/// transaction.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - transaction: The type of transaction to begin.
|
||||
/// - closure: The closure that accepts a connection.
|
||||
/// - transaction: The type of transaction to start.
|
||||
/// - closure: A closure that takes the active connection and returns a result.
|
||||
/// - Returns: The value returned by the closure.
|
||||
/// - Throws: An error if one occurs during closure execution.
|
||||
/// - Throws: Errors from connection creation, key application, configuration, transaction
|
||||
/// management, or from the closure itself.
|
||||
///
|
||||
/// - Important: The closure may be executed more than once if a reconnection occurs. Ensure it
|
||||
/// performs only database operations and does not produce external side effects (such as
|
||||
/// sending network requests or posting notifications).
|
||||
func perform<T>(in transaction: TransactionType, closure: Perform<T>) throws -> T
|
||||
}
|
||||
|
||||
@@ -1,48 +1,58 @@
|
||||
import Foundation
|
||||
|
||||
/// Protocol for managing and executing database schema migrations.
|
||||
/// A type that manages and executes database schema migrations.
|
||||
///
|
||||
/// Conforming types are responsible for registering migrations, applying
|
||||
/// encryption keys (if required), and executing pending migrations in
|
||||
/// ascending version order.
|
||||
/// ## Overview
|
||||
///
|
||||
/// Migrations ensure that the database schema evolves consistently across
|
||||
/// application versions without requiring manual intervention.
|
||||
/// Conforming types are responsible for registering migration steps, applying encryption keys
|
||||
/// (if required), and executing pending migrations in ascending version order. Migrations ensure
|
||||
/// that the database schema evolves consistently across application versions without manual
|
||||
/// intervention.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Associated Types
|
||||
/// - ``Version``
|
||||
///
|
||||
/// ### Properties
|
||||
/// - ``keyProvider``
|
||||
///
|
||||
/// ### Instance Methods
|
||||
/// - ``add(_:)``
|
||||
/// - ``migrate()``
|
||||
/// - ``migrate()-18x5r``
|
||||
public protocol MigrationServiceProtocol: AnyObject, Sendable {
|
||||
/// Type representing the schema version used for migrations.
|
||||
/// The type representing a schema version used for migrations.
|
||||
associatedtype Version: VersionRepresentable
|
||||
|
||||
/// Encryption key provider for the database service.
|
||||
var keyProvider: DatabaseServiceKeyProvider? { get set }
|
||||
/// The provider responsible for supplying encryption keys to the service.
|
||||
var keyProvider: ConnectionServiceKeyProvider? { get set }
|
||||
|
||||
/// Registers a migration to be executed by the service.
|
||||
///
|
||||
/// - Parameter migration: The migration to register.
|
||||
/// - Throws: ``MigrationError/duplicateMigration(_:)`` if a migration with
|
||||
/// the same version or script URL is already registered.
|
||||
/// - Throws: ``MigrationError/duplicateMigration(_:)`` if a migration with the same version
|
||||
/// or script URL is already registered.
|
||||
func add(_ migration: Migration<Version>) throws(MigrationError<Version>)
|
||||
|
||||
/// Executes all pending migrations in ascending version order.
|
||||
///
|
||||
/// - Throws: ``MigrationError/emptyMigrationScript(_:)`` if a migration
|
||||
/// script is empty.
|
||||
/// - Throws: ``MigrationError/migrationFailed(_:_:)`` if a script execution
|
||||
/// or version update fails.
|
||||
/// - Throws: ``MigrationError/emptyMigrationScript(_:)`` if a migration script is empty.
|
||||
/// - Throws: ``MigrationError/migrationFailed(_:_:)`` if a migration step fails to execute
|
||||
/// or update the stored version.
|
||||
func migrate() throws(MigrationError<Version>)
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
@available(macOS 10.15, *)
|
||||
@available(iOS 13.0, macOS 10.15, *)
|
||||
public extension MigrationServiceProtocol {
|
||||
/// Asynchronously executes all pending migrations in ascending order.
|
||||
/// Asynchronously executes all pending migrations in ascending version order.
|
||||
///
|
||||
/// Performs the same logic as ``migrate()``, but runs asynchronously
|
||||
/// on a background task with `.utility` priority.
|
||||
/// Performs the same logic as ``migrate()``, but runs asynchronously on a background task with
|
||||
/// `.utility` priority.
|
||||
///
|
||||
/// - Throws: ``MigrationError/emptyMigrationScript(_:)`` if a migration
|
||||
/// script is empty.
|
||||
/// - Throws: ``MigrationError/migrationFailed(_:_:)`` if a script execution
|
||||
/// or version update fails.
|
||||
/// - Throws: ``MigrationError/emptyMigrationScript(_:)`` if a migration script is empty.
|
||||
/// - Throws: ``MigrationError/migrationFailed(_:_:)`` if a migration step fails to execute
|
||||
/// or update the stored version.
|
||||
func migrate() async throws {
|
||||
try await Task(priority: .utility) {
|
||||
try self.migrate()
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import Foundation
|
||||
import DataLiteCoder
|
||||
|
||||
/// A protocol for database services that support row encoding and decoding.
|
||||
///
|
||||
/// Conforming types provide `RowEncoder` and `RowDecoder` instances for serializing
|
||||
/// and deserializing model types to and from SQLite row representations.
|
||||
///
|
||||
/// This enables strongly typed, reusable, and safe access to database records
|
||||
/// using Swift's `Codable` system.
|
||||
public protocol RowDatabaseServiceProtocol: DatabaseServiceProtocol {
|
||||
/// The encoder used to serialize values into database rows.
|
||||
var encoder: RowEncoder { get }
|
||||
|
||||
/// The decoder used to deserialize database rows into typed models.
|
||||
var decoder: RowDecoder { get }
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/// A constraint that defines the requirements for a type used as a database schema version.
|
||||
///
|
||||
/// This type alias specifies the minimal set of capabilities a version type must have
|
||||
/// to participate in schema migrations. Conforming types must be:
|
||||
///
|
||||
/// - `Equatable`: to check whether two versions are equal
|
||||
/// - `Comparable`: to compare versions and determine ordering
|
||||
/// - `Hashable`: to use versions as dictionary keys or in sets
|
||||
/// - `Sendable`: to ensure safe use in concurrent contexts
|
||||
///
|
||||
/// Use this alias as a base constraint when defining custom version types
|
||||
/// for use with ``VersionStorage``.
|
||||
///
|
||||
/// ```swift
|
||||
/// struct SemanticVersion: VersionRepresentable {
|
||||
/// let major: Int
|
||||
/// let minor: Int
|
||||
/// let patch: Int
|
||||
///
|
||||
/// static func < (lhs: Self, rhs: Self) -> Bool {
|
||||
/// if lhs.major != rhs.major {
|
||||
/// return lhs.major < rhs.major
|
||||
/// }
|
||||
/// if lhs.minor != rhs.minor {
|
||||
/// return lhs.minor < rhs.minor
|
||||
/// }
|
||||
/// return lhs.patch < rhs.patch
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
public typealias VersionRepresentable = Equatable & Comparable & Hashable & Sendable
|
||||
@@ -1,36 +1,33 @@
|
||||
import Foundation
|
||||
import DataLiteCore
|
||||
|
||||
/// A protocol that defines how the database version is stored and retrieved.
|
||||
/// A type that defines how a database schema version is stored and retrieved.
|
||||
///
|
||||
/// This protocol decouples the concept of version representation from
|
||||
/// the way the version is stored. It enables flexible implementations
|
||||
/// that can store version values in different forms and places.
|
||||
/// ## Overview
|
||||
///
|
||||
/// The associated `Version` type determines how the version is represented
|
||||
/// (e.g. as an integer, a semantic string, or a structured object), while the
|
||||
/// conforming type defines how that version is persisted.
|
||||
/// This protocol separates the concept of version representation from its persistence mechanism,
|
||||
/// allowing flexible implementations that store version values in different formats or locations.
|
||||
///
|
||||
/// Use this protocol to implement custom strategies for version tracking:
|
||||
/// - Store an integer version in SQLite's `user_version` field.
|
||||
/// The associated ``Version`` type specifies how the version is represented (for example, as an
|
||||
/// integer, a semantic string, or a structured object), while the conforming type defines how that
|
||||
/// version is persisted.
|
||||
///
|
||||
/// ## Usage
|
||||
///
|
||||
/// Implement this type to define a custom strategy for schema version tracking:
|
||||
/// - Store an integer version in SQLite’s `user_version` field.
|
||||
/// - Store a string in a dedicated metadata table.
|
||||
/// - Store structured data in a JSON column.
|
||||
///
|
||||
/// To define your own versioning mechanism, implement `VersionStorage`
|
||||
/// and choose a `Version` type that conforms to ``VersionRepresentable``.
|
||||
///
|
||||
/// You can implement this protocol to define a custom way of storing the version
|
||||
/// of a database schema. For example, the version could be a string stored in a metadata table.
|
||||
///
|
||||
/// Below is an example of a simple implementation that stores the version string
|
||||
/// in a table named `schema_version`.
|
||||
/// The example below shows an implementation that stores the version string in a `schema_version`
|
||||
/// table:
|
||||
///
|
||||
/// ```swift
|
||||
/// final class StringVersionStorage: VersionStorage {
|
||||
/// typealias Version = String
|
||||
///
|
||||
/// func prepare(_ connection: Connection) throws {
|
||||
/// let script: SQLScript = """
|
||||
/// func prepare(_ connection: ConnectionProtocol) throws {
|
||||
/// let script = """
|
||||
/// CREATE TABLE IF NOT EXISTS schema_version (
|
||||
/// version TEXT NOT NULL
|
||||
/// );
|
||||
@@ -42,7 +39,7 @@ import DataLiteCore
|
||||
/// try connection.execute(sql: script)
|
||||
/// }
|
||||
///
|
||||
/// func getVersion(_ connection: Connection) throws -> Version {
|
||||
/// func getVersion(_ connection: ConnectionProtocol) throws -> Version {
|
||||
/// let query = "SELECT version FROM schema_version LIMIT 1"
|
||||
/// let stmt = try connection.prepare(sql: query)
|
||||
/// guard try stmt.step(), let value: Version = stmt.columnValue(at: 0) else {
|
||||
@@ -51,7 +48,7 @@ import DataLiteCore
|
||||
/// return value
|
||||
/// }
|
||||
///
|
||||
/// func setVersion(_ connection: Connection, _ version: Version) throws {
|
||||
/// func setVersion(_ connection: ConnectionProtocol, _ version: Version) throws {
|
||||
/// let query = "UPDATE schema_version SET version = ?"
|
||||
/// let stmt = try connection.prepare(sql: query)
|
||||
/// try stmt.bind(version, at: 0)
|
||||
@@ -60,17 +57,6 @@ import DataLiteCore
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This implementation works as follows:
|
||||
///
|
||||
/// - `prepare(_:)` creates the `schema_version` table if it does not exist, and ensures that it
|
||||
/// contains exactly one row with an initial version value (`"0.0.0"`).
|
||||
///
|
||||
/// - `getVersion(_:)` reads the current version string from the single row in the table.
|
||||
/// If the row is missing, it throws an error.
|
||||
///
|
||||
/// - `setVersion(_:_:)` updates the version string in that row. A `WHERE` clause is not necessary
|
||||
/// because the table always contains exactly one row.
|
||||
///
|
||||
/// ## Topics
|
||||
///
|
||||
/// ### Associated Types
|
||||
@@ -83,58 +69,54 @@ import DataLiteCore
|
||||
/// - ``getVersion(_:)``
|
||||
/// - ``setVersion(_:_:)``
|
||||
public protocol VersionStorage {
|
||||
/// A type representing the database schema version.
|
||||
/// The type representing the database schema version.
|
||||
associatedtype Version: VersionRepresentable
|
||||
|
||||
/// Creates a new instance of the version storage.
|
||||
init()
|
||||
|
||||
/// Prepares the storage mechanism for tracking the schema version.
|
||||
///
|
||||
/// This method is called before any version operations. Use it to create required tables
|
||||
/// or metadata structures needed for version management.
|
||||
/// Called before any version operations. Use this method to create required tables or metadata
|
||||
/// structures for version management.
|
||||
///
|
||||
/// - Important: This method is executed within an active migration transaction.
|
||||
/// Do not issue `BEGIN` or `COMMIT` manually. If this method throws an error,
|
||||
/// the entire migration process will be aborted and rolled back.
|
||||
/// - Important: Executed within an active migration transaction. Do not issue `BEGIN` or
|
||||
/// `COMMIT` manually. If this method throws an error, the migration process will be aborted
|
||||
/// and rolled back.
|
||||
///
|
||||
/// - Parameter connection: The database connection used for schema preparation.
|
||||
/// - Throws: An error if preparation fails.
|
||||
func prepare(_ connection: Connection) throws
|
||||
func prepare(_ connection: ConnectionProtocol) throws
|
||||
|
||||
/// Returns the current schema version stored in the database.
|
||||
///
|
||||
/// This method must return a valid version previously stored by the migration system.
|
||||
/// Must return a valid version previously stored by the migration system.
|
||||
///
|
||||
/// - Important: This method is executed within an active migration transaction.
|
||||
/// Do not issue `BEGIN` or `COMMIT` manually. If this method throws an error,
|
||||
/// the entire migration process will be aborted and rolled back.
|
||||
/// - Important: Executed within an active migration transaction. Do not issue `BEGIN` or
|
||||
/// `COMMIT` manually. If this method throws an error, the migration process will be aborted
|
||||
/// and rolled back.
|
||||
///
|
||||
/// - Parameter connection: The database connection used to fetch the version.
|
||||
/// - Returns: The version currently stored in the database.
|
||||
/// - Throws: An error if reading fails or the version is missing.
|
||||
func getVersion(_ connection: Connection) throws -> Version
|
||||
func getVersion(_ connection: ConnectionProtocol) throws -> Version
|
||||
|
||||
/// Stores the given version as the current schema version.
|
||||
///
|
||||
/// This method is called at the end of the migration process to persist
|
||||
/// the final schema version after all migration steps have completed successfully.
|
||||
/// Called at the end of the migration process to persist the final schema version after all
|
||||
/// migration steps complete successfully.
|
||||
///
|
||||
/// - Important: This method is executed within an active migration transaction.
|
||||
/// Do not issue `BEGIN` or `COMMIT` manually. If this method throws an error,
|
||||
/// the entire migration process will be aborted and rolled back.
|
||||
/// - Important: Executed within an active migration transaction. Do not issue `BEGIN` or
|
||||
/// `COMMIT` manually. If this method throws an error, the migration process will be aborted
|
||||
/// and rolled back.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - connection: The database connection used to write the version.
|
||||
/// - version: The version to store.
|
||||
/// - Throws: An error if writing fails.
|
||||
func setVersion(_ connection: Connection, _ version: Version) throws
|
||||
func setVersion(_ connection: ConnectionProtocol, _ version: Version) throws
|
||||
}
|
||||
|
||||
public extension VersionStorage {
|
||||
/// A default implementation that performs no preparation.
|
||||
///
|
||||
/// Override this method if your storage implementation requires any setup,
|
||||
/// such as creating a version table or inserting an initial value.
|
||||
///
|
||||
/// If you override this method and it throws an error, the migration process
|
||||
/// will be aborted and rolled back.
|
||||
func prepare(_ connection: Connection) throws {}
|
||||
func prepare(_ connection: ConnectionProtocol) throws {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user