Skip to content

Commit f67be2a

Browse files
committed
Merge remote-tracking branch 'origin/main' into swift-sync-client
2 parents 0f71c4a + 28ae63f commit f67be2a

6 files changed

Lines changed: 40 additions & 14 deletions

File tree

.github/workflows/build_and_test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ jobs:
88
build:
99
name: Build and test
1010
runs-on: macos-latest
11+
timeout-minutes: 30
1112
steps:
1213
- uses: actions/checkout@v4
1314
- name: Set up XCode

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 1.14.0 (unreleased)
44

55
* Add `opDataTyped` and `previousValuesTyped` to `CrudEntry`, providing typed values instead of strings.
6+
* Make `CrudBatch`, `CrudEntry` and `CrudTransaction` a concrete struct. Note that these can no longer be created in user code.
67

78
## 1.13.1
89

Sources/PowerSync/Protocol/Schema/RawTable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public struct RawTable: BaseTableProtocol, Encodable {
6969
// That could also throw an exception (which would crash the process), but that
7070
// was overlooked due to a missing @Throws annotation.
7171
// Now, we can't mark this as throws without breaking backwards compatibility.
72-
// We should conver this to be throwing in a future major release.
72+
// We should convert this to be throwing in a future major release.
7373
fatalError("Serializing a raw table failed: \(error)")
7474
}
7575
}

Sources/PowerSync/Protocol/db/CrudBatch.swift

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,9 @@ public struct CrudBatch: Sendable {
1919
/// Call to remove the changes from the local queue, once successfully uploaded.
2020
///
2121
/// `writeCheckpoint` is optional.
22-
public func complete(writeCheckpoint: String?) async throws {
22+
public func complete(writeCheckpoint: String? = nil) async throws {
2323
let lastId = crud.last!.clientId
24-
try await completeCrudItems(self.db, lastId)
25-
}
26-
27-
/// Call to remove the changes from the local queue, once successfully uploaded.
28-
public func complete() async throws {
29-
try await self.complete(
30-
writeCheckpoint: nil
31-
)
24+
try await completeCrudItems(self.db, lastId, writeCheckpoint: writeCheckpoint)
3225
}
3326
}
3427

@@ -42,6 +35,6 @@ internal func completeCrudItems(_ db: any PowerSyncDatabaseProtocol, _ lastItemI
4235
return
4336
}
4437
}
45-
try tx.execute(sql: "UPDATE ps_buckets SET target_op = ? WHERE name = '$local'", parameters: [KotlinPowerSyncDatabaseImpl.maxOpId])
38+
try tx.execute(sql: "UPDATE ps_buckets SET target_op = 9223372036854775807 WHERE name = '$local'", parameters: nil)
4639
}
4740
}

Sources/PowerSync/Protocol/db/CrudEntry.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ public struct CrudEntry: Sendable {
112112
}
113113

114114
let decoder = JSONDecoder()
115-
let entry = try decoder.decode(CrudJsonEntry.self, from: data.data(using: .utf8)!)
115+
guard let jsonData = data.data(using: .utf8) else {
116+
throw PowerSyncError.operationFailed(message: "Invalid UTF-8 in CRUD entry")
117+
}
118+
let entry = try decoder.decode(CrudJsonEntry.self, from: jsonData)
116119

117120
return CrudEntry(
118121
id: entry.id,
@@ -128,7 +131,9 @@ public struct CrudEntry: Sendable {
128131
}
129132

130133
private static func jsonValueToString(_ value: JsonValue?) throws -> String? {
131-
try value.map { value in
134+
// Older versions of the SDK were only able to export these values as strings, so we convert for
135+
// backwards compatibility.
136+
try value.flatMap { value in
132137
switch (value) {
133138
case .string(let value):
134139
return value
@@ -139,7 +144,7 @@ public struct CrudEntry: Sendable {
139144
case .bool(let value):
140145
return String(value)
141146
case .null:
142-
return "null"
147+
return nil
143148
case .array(_), .object(_):
144149
throw PowerSyncError.operationFailed(message: "Invalid array/object in CRUD data, should be string")
145150
}

Tests/PowerSyncTests/CrudTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,30 @@ final class CrudTests: XCTestCase {
318318
XCTAssertEqual(write.opData?["name"], "updated_name")
319319
XCTAssertEqual(write.previousValues?["name"], "user")
320320
}
321+
322+
func testCustomWriteCheckpoints() async throws {
323+
try await database.execute(
324+
sql: "INSERT INTO users (id, name) VALUES (uuid(), 'a')",
325+
parameters: []
326+
)
327+
328+
let tx = try await database.getNextCrudTransaction()!
329+
try await tx.complete(writeCheckpoint: "123")
330+
331+
let targetOp = try await database.get("SELECT target_op FROM ps_buckets WHERE name = '$local'") {
332+
try $0.getInt(index: 0)
333+
}
334+
XCTAssertEqual(targetOp, 123)
335+
336+
try await database.execute(
337+
sql: "INSERT INTO users (id, name) VALUES (uuid(), 'a')",
338+
parameters: []
339+
)
340+
let batch = try await database.getCrudBatch()!
341+
try await batch.complete(writeCheckpoint: "124")
342+
let newTargetOp = try await database.get("SELECT target_op FROM ps_buckets WHERE name = '$local'") {
343+
try $0.getInt(index: 0)
344+
}
345+
XCTAssertEqual(newTargetOp, 124)
346+
}
321347
}

0 commit comments

Comments
 (0)