@@ -132,6 +132,16 @@ public actor SQLClient {
132132 public init ( ) { }
133133
134134 private let queue = DispatchQueue ( label: " com.sqlclient.serial " )
135+ private var activeTask : Task < Void , Never > ?
136+
137+ private func serialize< T: Sendable > ( _ operation: @escaping @Sendable ( ) async throws -> T ) async throws -> T {
138+ let newTask : Task < T , Error > = Task { [ activeTask] in
139+ _ = await activeTask? . result
140+ return try await operation ( )
141+ }
142+ activeTask = Task { _ = await newTask. result }
143+ return try await newTask. value
144+ }
135145
136146 public var maxTextSize : Int = 4096
137147 private var login : OpaquePointer ?
@@ -143,37 +153,43 @@ public actor SQLClient {
143153 }
144154
145155 public func connect( options: SQLClientConnectionOptions ) async throws {
146- guard !connected else { throw SQLClientError . alreadyConnected }
156+ try await serialize {
157+ guard !self . connected else { throw SQLClientError . alreadyConnected }
147158
148- let result = try await runBlocking {
159+ let result = try await self . runBlocking {
149160 return try self . _connectSync ( options: options)
150161 }
151162
152163 self . login = result. login. pointer
153164 self . connection = result. connection. pointer
154165 self . connected = true
155166 }
167+ }
156168
157169 public func disconnect( ) async {
158- guard connected else { return }
159- let lgn = self . login. map { TDSHandle ( pointer: $0) }
160- let conn = self . connection. map { TDSHandle ( pointer: $0) }
161- await runBlockingVoid {
162- self . _disconnectSync ( login: lgn, connection: conn)
170+ _ = try ? await serialize {
171+ guard self . connected else { return }
172+ let lgn = self . login. map { TDSHandle ( pointer: $0) }
173+ let conn = self . connection. map { TDSHandle ( pointer: $0) }
174+ await self . runBlockingVoid {
175+ self . _disconnectSync ( login: lgn, connection: conn)
176+ }
177+ self . login = nil
178+ self . connection = nil
179+ self . connected = false
163180 }
164- self . login = nil
165- self . connection = nil
166- self . connected = false
167181 }
168182
169183 public func execute( _ sql: String ) async throws -> SQLClientResult {
170- guard connected, let conn = connection else { throw SQLClientError . notConnected }
171- guard !sql. trimmingCharacters ( in: . whitespacesAndNewlines) . isEmpty else { throw SQLClientError . noCommandText }
172- let maxText = self . maxTextSize
173- let handle = TDSHandle ( pointer: conn)
174-
175- return try await runBlocking {
176- return try self . _executeSync ( sql: sql, connection: handle, maxTextSize: maxText)
184+ try await serialize {
185+ guard self . connected, let conn = self . connection else { throw SQLClientError . notConnected }
186+ guard !sql. trimmingCharacters ( in: . whitespacesAndNewlines) . isEmpty else { throw SQLClientError . noCommandText }
187+ let maxText = self . maxTextSize
188+ let handle = TDSHandle ( pointer: conn)
189+
190+ return try await self . runBlocking {
191+ return try self . _executeSync ( sql: sql, connection: handle, maxTextSize: maxText)
192+ }
177193 }
178194 }
179195
@@ -228,8 +244,8 @@ public actor SQLClient {
228244 }
229245 Thread . sleep ( forTimeInterval: 0.1 )
230246 }
231- CFReadStreamClose ( read)
232- CFWriteStreamClose ( write)
247+ CFReadStreamOpen ( read)
248+ CFWriteStreamOpen ( write)
233249
234250 if connected {
235251 cont. resume ( )
@@ -343,7 +359,7 @@ public actor SQLClient {
343359 return NSNumber ( value: data. load ( as: Double . self) )
344360 case 50 , 104 : // SYBBIT, SYBBITN
345361 return NSNumber ( value: data. load ( as: UInt8 . self) != 0 )
346- case 47 , 39 , 102 , 103 , 35 , 99 , 241 : // SYBCHAR, SYBVARCHAR, SYBNCHAR, SYBNVARCHAR, SYBTEXT, SYBNTEXT, SYBXML
362+ case 47 , 39 , 102 , 103 , 35 , 99 , 241 : // SYBCHAR, SYBVARCHAR, SYBTEXT, SYBNTEXT, SYBXML, SYBNCHAR, SYBNVARCHAR
347363 let buf = UnsafeBufferPointer < UInt8 > ( start: data. assumingMemoryBound ( to: UInt8 . self) , count: Int ( len) )
348364 return String ( bytes: buf, encoding: . utf8) ?? String ( bytes: buf, encoding: . windowsCP1252) ?? " "
349365 case 45 , 37 , 34 , 173 , 174 , 167 : // SYBBINARY, SYBVARBINARY, SYBIMAGE, SYBBIGBINARY, SYBBIGVARBINARY, SYBBLOB
@@ -360,7 +376,6 @@ public actor SQLClient {
360376 memcpy ( & bytes, dataPtr, 16 )
361377
362378 // SQL Server UniqueIdentifier mixed-endian -> RFC 4122 Big-Endian
363- // Data1 (4 bytes), Data2 (2 bytes), Data3 (2 bytes) are little-endian in TDS
364379 let swapped : [ UInt8 ] = [
365380 bytes [ 3 ] , bytes [ 2 ] , bytes [ 1 ] , bytes [ 0 ] ,
366381 bytes [ 5 ] , bytes [ 4 ] ,
0 commit comments