@@ -36,7 +36,8 @@ public actor ConnectionPool: Sendable {
3636 public init (
3737 path: String ,
3838 limit: Int ,
39- migrations: [ String ]
39+ migrations: [ String ] ,
40+ runMigrations: Bool = true
4041 ) throws {
4142 guard limit > 0 else {
4243 throw SQLError . poolCannotHaveZeroConnections
@@ -50,7 +51,11 @@ public actor ConnectionPool: Sendable {
5051
5152 // Turn on WAL mode
5253 try connection. execute ( sql: " PRAGMA journal_mode=WAL; " )
53- try MigrationRunner . execute ( migrations: migrations, connection: connection)
54+
55+ if runMigrations {
56+ try MigrationRunner . execute ( migrations: migrations, connection: connection)
57+ }
58+
5459 self . availableConnections = [ connection]
5560 }
5661
@@ -63,26 +68,32 @@ public actor ConnectionPool: Sendable {
6368 private func begin(
6469 _ kind: Transaction . Kind
6570 ) async throws ( SQLError) -> sending Transaction {
66- // Writes must be exclusive, make sure to wait on any pending writes.
67- if kind == . write {
68- await writeLock. lock ( )
69- }
70-
71- return try await Transaction ( connection: getConnection ( ) , kind: kind)
71+ return try await Transaction (
72+ connection: getConnection ( isWrite: kind == . write) ,
73+ kind: kind
74+ )
7275 }
7376
7477 /// Gives the connection back to the pool.
75- private func reclaim( connection: RawConnection , kind: Transaction . Kind ) async {
78+ private func reclaim(
79+ connection: RawConnection ,
80+ isWrite: Bool
81+ ) async {
7682 availableConnections. append ( connection)
7783 alertAnyWaitersOfAvailableConnection ( )
7884
79- if kind == . write {
85+ if isWrite {
8086 await writeLock. unlock ( )
8187 }
8288 }
8389
8490 /// Will get, wait or create a connection to the database
85- private func getConnection( ) async throws ( SQLError) -> RawConnection {
91+ private func getConnection( isWrite: Bool ) async throws ( SQLError) -> RawConnection {
92+ // Writes must be exclusive, make sure to wait on any pending writes.
93+ if isWrite {
94+ await writeLock. lock ( )
95+ }
96+
8697 guard availableConnections. isEmpty else {
8798 // Have an available connection, just use it
8899 return availableConnections. removeLast ( )
@@ -169,11 +180,22 @@ extension ConnectionPool: Connection {
169180
170181 do {
171182 let output = try await execute ( tx)
172- await reclaim ( connection: conn, kind : kind)
183+ await reclaim ( connection: conn, isWrite : kind == . write )
173184 return output
174185 } catch {
175- await reclaim ( connection: conn, kind : kind)
186+ await reclaim ( connection: conn, isWrite : kind == . write )
176187 throw error
177188 }
178189 }
190+
191+ /// Gets a connection to the database. No tx is started.
192+ public func withConnection< Output: Sendable > (
193+ isWrite: Bool ,
194+ execute: @Sendable ( borrowing RawConnection ) throws -> Output
195+ ) async throws -> Output {
196+ let conn = try await getConnection ( isWrite: isWrite)
197+ let output = try execute ( conn)
198+ await reclaim ( connection: conn, isWrite: isWrite)
199+ return output
200+ }
179201}
0 commit comments