Skip to content

Commit bafb2de

Browse files
Fixed an issue where loading from a fresh datastore would throw an error
Fixes #163
1 parent e4fe1fa commit bafb2de

File tree

2 files changed

+57
-34
lines changed

2 files changed

+57
-34
lines changed

Sources/CodableDatastore/Datastore/Datastore.swift

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ extension Datastore {
476476
return instance
477477
} catch DatastoreInterfaceError.instanceNotFound {
478478
return nil
479+
} catch DatastoreInterfaceError.datastoreKeyNotFound {
480+
/// There isn't a datastore yet, so no entries would exist either.
481+
return nil
479482
} catch {
480483
throw error
481484
}
@@ -496,12 +499,16 @@ extension Datastore {
496499
actionName: nil,
497500
options: [.readOnly]
498501
) { transaction, _ in
499-
try await transaction.primaryIndexScan(range: range.applying(order), datastoreKey: self.key) { versionData, instanceData in
500-
let entryVersion = try Version(versionData)
501-
let decoder = try await self.decoder(for: entryVersion)
502-
let decodedValue = try await decoder(instanceData)
503-
504-
try await provider.yield(decodedValue)
502+
do {
503+
try await transaction.primaryIndexScan(range: range.applying(order), datastoreKey: self.key) { versionData, instanceData in
504+
let entryVersion = try Version(versionData)
505+
let decoder = try await self.decoder(for: entryVersion)
506+
let decodedValue = try await decoder(instanceData)
507+
508+
try await provider.yield(decodedValue)
509+
}
510+
} catch DatastoreInterfaceError.datastoreKeyNotFound {
511+
/// There isn't a datastore yet, so no entries would exist either. Do nothing and let the stream end.
505512
}
506513
}
507514
}
@@ -542,34 +549,38 @@ extension Datastore {
542549
actionName: nil,
543550
options: [.readOnly]
544551
) { transaction, _ in
545-
let isDirectIndex = self.directIndexes.contains { $0.path == indexPath.path }
546-
547-
if isDirectIndex {
548-
try await transaction.directIndexScan(
549-
range: range.applying(order),
550-
indexName: indexPath.path,
551-
datastoreKey: self.key
552-
) { versionData, instanceData in
553-
let entryVersion = try Version(versionData)
554-
let decoder = try await self.decoder(for: entryVersion)
555-
let instance = try await decoder(instanceData).instance
556-
557-
try await provider.yield(instance)
558-
}
559-
} else {
560-
try await transaction.secondaryIndexScan(
561-
range: range.applying(order),
562-
indexName: indexPath.path,
563-
datastoreKey: self.key
564-
) { (identifier: IdentifierType) in
565-
let persistedEntry = try await transaction.primaryIndexCursor(for: identifier, datastoreKey: self.key)
566-
567-
let entryVersion = try Version(persistedEntry.versionData)
568-
let decoder = try await self.decoder(for: entryVersion)
569-
let instance = try await decoder(persistedEntry.instanceData).instance
570-
571-
try await provider.yield(instance)
552+
do {
553+
let isDirectIndex = self.directIndexes.contains { $0.path == indexPath.path }
554+
555+
if isDirectIndex {
556+
try await transaction.directIndexScan(
557+
range: range.applying(order),
558+
indexName: indexPath.path,
559+
datastoreKey: self.key
560+
) { versionData, instanceData in
561+
let entryVersion = try Version(versionData)
562+
let decoder = try await self.decoder(for: entryVersion)
563+
let instance = try await decoder(instanceData).instance
564+
565+
try await provider.yield(instance)
566+
}
567+
} else {
568+
try await transaction.secondaryIndexScan(
569+
range: range.applying(order),
570+
indexName: indexPath.path,
571+
datastoreKey: self.key
572+
) { (identifier: IdentifierType) in
573+
let persistedEntry = try await transaction.primaryIndexCursor(for: identifier, datastoreKey: self.key)
574+
575+
let entryVersion = try Version(persistedEntry.versionData)
576+
let decoder = try await self.decoder(for: entryVersion)
577+
let instance = try await decoder(persistedEntry.instanceData).instance
578+
579+
try await provider.yield(instance)
580+
}
572581
}
582+
} catch DatastoreInterfaceError.datastoreKeyNotFound {
583+
/// There isn't a datastore yet, so no entries would exist either. Do nothing and let the stream end.
573584
}
574585
}
575586
}

Tests/CodableDatastoreTests/DiskPersistenceDatastoreTests.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ final class DiskPersistenceDatastoreTests: XCTestCase {
7575
]
7676
)
7777

78+
let count = try await datastore.count
79+
XCTAssertEqual(count, 0)
80+
81+
let entry0 = try await datastore.load("0")
82+
XCTAssertNil(entry0)
83+
7884
try await datastore.persist(TestStruct(id: "3", value: "My name is Dimitri"))
7985
try await datastore.persist(TestStruct(id: "1", value: "Hello, World!"))
8086
try await datastore.persist(TestStruct(id: "2", value: "Twenty Three is Number One"))
@@ -96,6 +102,8 @@ final class DiskPersistenceDatastoreTests: XCTestCase {
96102
let count = try await datastore.count
97103
XCTAssertEqual(count, 3)
98104

105+
let entry0 = try await datastore.load("0")
106+
XCTAssertNil(entry0)
99107
let entry1 = try await datastore.load("1")
100108
XCTAssertEqual(entry1?.value, "Hello, World!")
101109
let entry2 = try await datastore.load("2")
@@ -215,6 +223,10 @@ final class DiskPersistenceDatastoreTests: XCTestCase {
215223
]
216224
)
217225

226+
/// Read before persisting anything
227+
var values = try await datastore.load(...).map { $0.value }.reduce(into: []) { $0.append($1) }
228+
XCTAssertEqual(values, [])
229+
218230
for n in 0..<200 {
219231
try await datastore.persist(TestStruct(id: n*2, value: "\(n*2)"))
220232
}
@@ -223,7 +235,7 @@ final class DiskPersistenceDatastoreTests: XCTestCase {
223235
XCTAssertEqual(count, 200)
224236

225237
/// Simple ranges
226-
var values = try await datastore.load(5..<9).map { $0.value }.reduce(into: []) { $0.append($1) }
238+
values = try await datastore.load(5..<9).map { $0.value }.reduce(into: []) { $0.append($1) }
227239
XCTAssertEqual(values, ["6", "8"])
228240

229241
values = try await datastore.load((5..<9).reversed).map { $0.value }.reduce(into: []) { $0.append($1) }

0 commit comments

Comments
 (0)