@@ -531,6 +531,7 @@ extension PostgresConnection {
531
531
}
532
532
}
533
533
534
+ #if compiler(>=6.0)
534
535
/// Puts the connection into an open transaction state, for the provided `closure`'s lifetime.
535
536
///
536
537
/// The function starts a transaction by running a `BEGIN` query on the connection against the database. It then
@@ -581,6 +582,57 @@ extension PostgresConnection {
581
582
throw transactionError
582
583
}
583
584
}
585
+ #else
586
+ /// Puts the connection into an open transaction state, for the provided `closure`'s lifetime.
587
+ ///
588
+ /// The function starts a transaction by running a `BEGIN` query on the connection against the database. It then
589
+ /// lends the connection to the user provided closure. The user can then modify the database as they wish. If the user
590
+ /// provided closure returns successfully, the function will attempt to commit the changes by running a `COMMIT`
591
+ /// query against the database. If the user provided closure throws an error, the function will attempt to rollback the
592
+ /// changes made within the closure.
593
+ ///
594
+ /// - Parameters:
595
+ /// - logger: The `Logger` to log into for the transaction.
596
+ /// - file: The file, the transaction was started in. Used for better error reporting.
597
+ /// - line: The line, the transaction was started in. Used for better error reporting.
598
+ /// - closure: The user provided code to modify the database. Use the provided connection to run queries.
599
+ /// The connection must stay in the transaction mode. Otherwise this method will throw!
600
+ /// - Returns: The closure's return value.
601
+ public func withTransaction< Result> (
602
+ logger: Logger ,
603
+ file: String = #file,
604
+ line: Int = #line,
605
+ _ process: ( PostgresConnection ) async throws -> Result
606
+ ) async throws -> Result {
607
+ do {
608
+ try await self . query ( " BEGIN; " , logger: logger)
609
+ } catch {
610
+ throw PostgresTransactionError ( file: file, line: line, beginError: error)
611
+ }
612
+
613
+ var closureHasFinished : Bool = false
614
+ do {
615
+ let value = try await process ( self )
616
+ closureHasFinished = true
617
+ try await self . query ( " COMMIT; " , logger: logger)
618
+ return value
619
+ } catch {
620
+ var transactionError = PostgresTransactionError ( file: file, line: line)
621
+ if !closureHasFinished {
622
+ transactionError. closureError = error
623
+ do {
624
+ try await self . query ( " ROLLBACK; " , logger: logger)
625
+ } catch {
626
+ transactionError. rollbackError = error
627
+ }
628
+ } else {
629
+ transactionError. commitError = error
630
+ }
631
+
632
+ throw transactionError
633
+ }
634
+ }
635
+ #endif
584
636
}
585
637
586
638
// MARK: EventLoopFuture interface
0 commit comments