Skip to content

Commit cbfde30

Browse files
committed
Add 'everythingBefore' date based cache clearing policy
1 parent 1b9d1d2 commit cbfde30

4 files changed

Lines changed: 34 additions & 0 deletions

File tree

Sources/Apollo/NormalizedCache.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public struct CacheClearingPolicy: Equatable {
1313
/// Clears the the last (most recent) records in the cache up to the given limit.
1414
/// - Parameter k: The number of records to remove from the cache.
1515
public static func last(_ k: Int) -> CacheClearingPolicy { .init(.last(k)) }
16+
/// Clears all records from the cache that was pulled in before the date provided.
17+
public static func everythingBefore(_ date: Date) -> CacheClearingPolicy { .init(.everythingBefore(date)) }
1618

1719
// actual policy storage
1820

@@ -28,13 +30,15 @@ public struct CacheClearingPolicy: Equatable {
2830
case allMatchingKeyPattern(String)
2931
case first(Int)
3032
case last(Int)
33+
case everythingBefore(Date)
3134

3235
public static func ==(lhs: _Policy, rhs: _Policy) -> Bool {
3336
switch (lhs, rhs) {
3437
case (.allRecords, .allRecords): return true
3538
case let (.allMatchingKeyPattern(left), .allMatchingKeyPattern(right)): return left == right
3639
case let (.first(left), .first(right)): return left == right
3740
case let (.last(left), .last(right)): return left == right
41+
case let (.everythingBefore(left), .everythingBefore(right)): return left == right
3842
default: return false
3943
}
4044
}

Sources/Apollo/RecordSet.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public struct RecordSet {
3131

3232
case let .allMatchingKeyPattern(pattern): self.storage = self.storage.filter { !$0.key.contains(pattern) }
3333

34+
case let .everythingBefore(date): self.storage = self.storage.filter {
35+
let comparison = Calendar.current.compare($0.value.lastReceivedAt, to: date, toGranularity: .minute)
36+
return comparison != .orderedAscending
37+
}
38+
3439
case .allRecords: fallthrough
3540
default: self.storage.removeAll()
3641
}

Sources/ApolloSQLite/SQLiteNormalizedCache.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ public final class SQLiteNormalizedCache {
141141
)
142142
try self.db.run(matchingRecords.delete())
143143

144+
case let .everythingBefore(date):
145+
let oldRecords = records.where(
146+
self.lastReceivedAt < Int64(date.timeIntervalSince1970)
147+
)
148+
try self.db.run(oldRecords.delete())
149+
144150
case .allRecords: fallthrough
145151
default:
146152
try self.db.run(records.delete())

Tests/ApolloSQLiteTests/CachePersistenceTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,25 @@ extension CachePersistenceTests {
9494
}
9595
}
9696

97+
func testClearByDate() {
98+
let emptyCacheExpectation = self.expectation(description: "empty cache")
99+
100+
self.testCacheClearing(withPolicy: .allMatchingKeyPattern("*hero*")) { client, _ in
101+
client.store.withinReadTransaction {
102+
$0.loadRecords(forKeys: ["QUERY_ROOT.hero", "QUERY_ROOT.hero(episode:EMPIRE)"]) { result in
103+
defer { emptyCacheExpectation.fulfill() }
104+
105+
do {
106+
let results = try result.get()
107+
XCTAssertTrue(results.allSatisfy({ $0 == nil }))
108+
} catch {
109+
XCTFail("Unexpected error: \(error)")
110+
}
111+
}
112+
}
113+
}
114+
}
115+
97116
private func testCacheClearing(
98117
withPolicy policy: CacheClearingPolicy,
99118
validateAssumptions: @escaping (ApolloClient, TwoHeroesQuery) throws -> Void,

0 commit comments

Comments
 (0)