Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
Postgres driver implementation for the abstract [Feather Database](https://github.com/feather-framework/feather-database) Swift API package.

[
![Release: 1.0.0-beta.5](https://img.shields.io/badge/Release-1%2E0%2E0--beta%2E5-F05138)
![Release: 1.0.0-beta.6](https://img.shields.io/badge/Release-1%2E0%2E0--beta%2E6-F05138)
](
https://github.com/feather-framework/feather-database-postgres/releases/tag/1.0.0-beta.5
https://github.com/feather-framework/feather-database-postgres/releases/tag/1.0.0-beta.6
)

## Features
Expand Down Expand Up @@ -37,7 +37,7 @@ Postgres driver implementation for the abstract [Feather Database](https://githu
Add the dependency to your `Package.swift`:

```swift
.package(url: "https://github.com/feather-framework/feather-database-postgres", exact: "1.0.0-beta.5"),
.package(url: "https://github.com/feather-framework/feather-database-postgres", exact: "1.0.0-beta.6"),
```

Then add `FeatherDatabasePostgres` to your target dependencies:
Expand Down
94 changes: 78 additions & 16 deletions Sources/FeatherDatabasePostgres/DatabaseClientPostgres.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public struct DatabaseClientPostgres: DatabaseClient {
public typealias Connection = DatabaseConnectionPostgres

var client: PostgresNIO.PostgresClient
var logger: Logger
let logger: Logger

/// Create a Postgres database client.
///
Expand Down Expand Up @@ -44,14 +44,18 @@ public struct DatabaseClientPostgres: DatabaseClient {
public func withConnection<T>(
_ closure: (Connection) async throws -> T,
) async throws(DatabaseError) -> T {
do {
return try await client.withConnection { connection in
let databaseConnection = DatabaseConnectionPostgres(
let logger = self.logger
let body: (PostgresConnection) async throws -> T = { connection in
try await closure(
DatabaseConnectionPostgres(
connection: connection,
logger: logger
)
return try await closure(databaseConnection)
}
)
}

do {
return try await client.withConnection(body)
}
catch let error as DatabaseError {
throw error
Expand All @@ -71,23 +75,81 @@ public struct DatabaseClientPostgres: DatabaseClient {
public func withTransaction<T>(
_ closure: (Connection) async throws -> T,
) async throws(DatabaseError) -> T {
let logger = self.logger
let beginQuery = PostgresQuery(unsafeSQL: "BEGIN", binds: .init())
let commitQuery = PostgresQuery(unsafeSQL: "COMMIT", binds: .init())
let rollbackQuery = PostgresQuery(unsafeSQL: "ROLLBACK", binds: .init())

do {
return try await client.withTransaction(
logger: logger
) { connection in
return try await client.withConnection { connection in
let databaseConnection = DatabaseConnectionPostgres(
connection: connection,
logger: logger
)
return try await closure(databaseConnection)

do {
_ = try await connection.query(beginQuery, logger: logger)
}
catch {
throw DatabaseError.transaction(
DatabaseTransactionErrorPostgres(
beginError: error
)
)
}

do {
let result = try await closure(databaseConnection)
do {
_ = try await connection.query(
commitQuery,
logger: logger
)
return result
}
catch {
let commitError = error
var rollbackError: (any Error)?
do {
_ = try await connection.query(
rollbackQuery,
logger: logger
)
}
catch {
rollbackError = error
}
throw DatabaseError.transaction(
DatabaseTransactionErrorPostgres(
commitError: commitError,
rollbackError: rollbackError
)
)
}
}
catch {
let closureError = error
var rollbackError: (any Error)?
do {
_ = try await connection.query(
rollbackQuery,
logger: logger
)
}
catch {
rollbackError = error
}
throw DatabaseError.transaction(
DatabaseTransactionErrorPostgres(
closureError: closureError,
rollbackError: rollbackError
)
)
}
}
}
catch let error as PostgresTransactionError {
throw .transaction(
DatabaseTransactionErrorPostgres(
underlyingError: error
)
)
catch let error as DatabaseError {
throw error
}
catch {
throw .connection(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,37 @@ import PostgresNIO

public struct DatabaseTransactionErrorPostgres: DatabaseTransactionError {

var underlyingError: PostgresTransactionError

public var file: String {
underlyingError.file
}

public var line: Int {
underlyingError.line
}

public var beginError: (any Error)? {
underlyingError.beginError
}

public var closureError: (any Error)? {
underlyingError.closureError
}

public var commitError: (any Error)? {
underlyingError.commitError
public let file: String
public let line: Int
public let beginError: (any Error)?
public let closureError: (any Error)?
public let commitError: (any Error)?
public let rollbackError: (any Error)?

init(
file: String = #fileID,
line: Int = #line,
beginError: (any Error)? = nil,
closureError: (any Error)? = nil,
commitError: (any Error)? = nil,
rollbackError: (any Error)? = nil
) {
self.file = file
self.line = line
self.beginError = beginError
self.closureError = closureError
self.commitError = commitError
self.rollbackError = rollbackError
}

public var rollbackError: (any Error)? {
underlyingError.rollbackError
init(
underlyingError: PostgresTransactionError
) {
self.file = underlyingError.file
self.line = underlyingError.line
self.beginError = underlyingError.beginError
self.closureError = underlyingError.closureError
self.commitError = underlyingError.commitError
self.rollbackError = underlyingError.rollbackError
}
}