Skip to content

Commit 2321496

Browse files
committed
AI feedback, more tests
1 parent f73de9f commit 2321496

5 files changed

Lines changed: 65 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* Add `opDataTyped` and `previousValuesTyped` to `CrudEntry`, providing typed values instead of strings.
66
* Make `CrudBatch`, `CrudEntry` and `CrudTransaction` a concrete struct. Note that these can no longer be created in user code.
77
* Remove the internal `withSession` API.
8+
* Remove internal dependency on the PowerSync Kotlin SDK. Going forward, the Swift SDK is implemented in Swift!
9+
* Breaking (for internal `SQLiteConnectionPoolProtocol` implementers): Make callbacks generic.
10+
* Breaking (for internal `SQLiteConnectionLease` implementers): Add methods to run statements.
811

912
## 1.13.1
1013

Sources/PowerSync/Implementation/AsyncConnectionPool.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ final class AsyncConnectionPool: SQLiteConnectionPoolProtocol {
125125
}
126126
}
127127

128-
func write<T>(onConnection: @escaping @Sendable (any SQLiteConnectionLease) throws -> T) async throws -> T{
128+
func write<T>(onConnection: @escaping @Sendable (any SQLiteConnectionLease) throws -> T) async throws -> T {
129129
let pool = try await obtainInner()
130130
return try await pool.write { connection in
131131
try await runBlocking { try onConnection(connection) }

Sources/PowerSync/Implementation/sqlite3/NativeConnectionPool.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ final class NativeConnectionPool: Sendable {
6868
return result
6969
}
7070

71-
func withAllConnections<T>(onConnection: (NativeConnectionLease, [NativeConnectionLease]) async throws -> T) async throws -> T{
71+
func withAllConnections<T>(onConnection: (NativeConnectionLease, [NativeConnectionLease]) async throws -> T) async throws -> T {
7272
let write = try await writer.acquire(count: 1)
7373
let writeLease = write.acquiredItems[0].asLease()
7474
defer { dispatchWrites(lease: writeLease) }
@@ -134,6 +134,8 @@ struct RawSqliteConnection: ~Copyable {
134134
}
135135
}
136136

137+
// We mark this as Sendable because it's only used in a mutex from `ConnectionLeaseContext`.
138+
// We can't generally assume SQLite connections to be thread-safe.
137139
struct NativeConnectionLease: SQLiteConnectionLease, @unchecked Sendable {
138140
let pointer: OpaquePointer
139141

Sources/PowerSync/Implementation/sqlite3/NativeStatement.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ struct NativeSqliteStatement: ~Copyable {
3737
}
3838

3939
var columnNames: [String : Int] {
40-
return resolvedColumnNames!
40+
guard let resolvedColumnNames else {
41+
fatalError("columnNames is only available after step()")
42+
}
43+
return resolvedColumnNames
4144
}
4245

4346
borrowing func bindValues(_ parameters: [PowerSyncDataType?]) throws(PowerSyncError) {
@@ -79,17 +82,21 @@ struct NativeSqliteStatement: ~Copyable {
7982
case .double(let value):
8083
rc = sqlite3_bind_double(self.stmt, index, value)
8184
case .data(let value):
82-
// Data object can be made up of multiple memory regions, so copy once.
83-
let buffer = malloc(value.count)!
84-
value.copyBytes(to: buffer.assumingMemoryBound(to: UInt8.self), count: value.count)
85+
if value.count == 0 {
86+
rc = sqlite3_bind_zeroblob(self.stmt, index, 0)
87+
} else {
88+
// Data object can be made up of multiple memory regions, so copy once.
89+
let buffer = malloc(value.count)!
90+
value.copyBytes(to: buffer.assumingMemoryBound(to: UInt8.self), count: value.count)
8591

86-
rc = sqlite3_bind_blob(
87-
self.stmt,
88-
index,
89-
buffer,
90-
Int32(value.count),
91-
free,
92-
)
92+
rc = sqlite3_bind_blob(
93+
self.stmt,
94+
index,
95+
buffer,
96+
Int32(value.count),
97+
free,
98+
)
99+
}
93100
}
94101

95102
if rc != 0 {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import Foundation
2+
@testable import PowerSync
3+
import Testing
4+
5+
struct StatementTests {
6+
@Test func bindValues() throws {
7+
let connection = try DatabaseLocation.inMemory.openConnection(writer: true)
8+
let lease = connection.asLease()
9+
try lease.withIterator(
10+
sql: "SELECT ?, ?, ?, ?, ?, ?, typeof(?), typeof(?)",
11+
parameters: [
12+
nil,
13+
.bool(false),
14+
.int32(32),
15+
.int64(64),
16+
.double(3.14),
17+
.string("hello"),
18+
.data(Data()),
19+
.data(Data([1, 2, 3]))
20+
],
21+
callback: { iterator in
22+
var hadRow = false
23+
try iterator.next { cursor in
24+
hadRow = true
25+
26+
try #require(cursor.getStringOptional(index: 0) == nil)
27+
try #require(cursor.getBoolean(index: 1) == false)
28+
try #require(cursor.getInt(index: 2) == 32)
29+
try #require(cursor.getInt(index: 3) == 64)
30+
try #require(cursor.getDouble(index: 4) == 3.14)
31+
try #require(cursor.getString(index: 5) == "hello")
32+
try #require(cursor.getString(index: 6) == "blob")
33+
try #require(cursor.getString(index: 7) == "blob")
34+
}
35+
36+
try #require(hadRow)
37+
}
38+
)
39+
}
40+
}

0 commit comments

Comments
 (0)