diff --git a/apollo-ios/Sources/ApolloSQLite/SQLiteDatabase.swift b/apollo-ios/Sources/ApolloSQLite/SQLiteDatabase.swift index fba6fb54a..509e93489 100644 --- a/apollo-ios/Sources/ApolloSQLite/SQLiteDatabase.swift +++ b/apollo-ios/Sources/ApolloSQLite/SQLiteDatabase.swift @@ -16,14 +16,25 @@ public protocol SQLiteDatabase { func selectRawRows(forKeys keys: Set) throws -> [DatabaseRow] - func addOrUpdateRecordString(_ recordString: String, for cacheKey: CacheKey) throws - + func addOrUpdate(records: [(cacheKey: CacheKey, recordString: String)]) throws + func deleteRecord(for cacheKey: CacheKey) throws func deleteRecords(matching pattern: CacheKey) throws func clearDatabase(shouldVacuumOnClear: Bool) throws + @available(*, deprecated, renamed: "addOrUpdate(records:)") + func addOrUpdateRecordString(_ recordString: String, for cacheKey: CacheKey) throws + +} + +extension SQLiteDatabase { + + public func addOrUpdateRecordString(_ recordString: String, for cacheKey: CacheKey) throws { + try addOrUpdate(records: [(cacheKey, recordString)]) + } + } public extension SQLiteDatabase { diff --git a/apollo-ios/Sources/ApolloSQLite/SQLiteDotSwiftDatabase.swift b/apollo-ios/Sources/ApolloSQLite/SQLiteDotSwiftDatabase.swift index 0210b8cb8..b973236a9 100644 --- a/apollo-ios/Sources/ApolloSQLite/SQLiteDotSwiftDatabase.swift +++ b/apollo-ios/Sources/ApolloSQLite/SQLiteDotSwiftDatabase.swift @@ -43,11 +43,17 @@ public final class SQLiteDotSwiftDatabase: SQLiteDatabase { return DatabaseRow(cacheKey: key, storedInfo: record) } } - - public func addOrUpdateRecordString(_ recordString: String, for cacheKey: CacheKey) throws { - try self.db.run(self.records.insert(or: .replace, self.keyColumn <- cacheKey, self.recordColumn <- recordString)) + + public func addOrUpdate(records: [(cacheKey: CacheKey, recordString: String)]) throws { + guard !records.isEmpty else { return } + + let setters = records.map { + [self.keyColumn <- $0.cacheKey, self.recordColumn <- $0.recordString] + } + + try self.db.run(self.records.insertMany(or: .replace, setters)) } - + public func deleteRecord(for cacheKey: CacheKey) throws { let query = self.records.filter(keyColumn == cacheKey) try self.db.run(query.delete()) diff --git a/apollo-ios/Sources/ApolloSQLite/SQLiteNormalizedCache.swift b/apollo-ios/Sources/ApolloSQLite/SQLiteNormalizedCache.swift index 04b552359..fde01188d 100644 --- a/apollo-ios/Sources/ApolloSQLite/SQLiteNormalizedCache.swift +++ b/apollo-ios/Sources/ApolloSQLite/SQLiteNormalizedCache.swift @@ -61,17 +61,21 @@ public final class SQLiteNormalizedCache { var recordSet = RecordSet(records: try self.selectRecords(for: records.keys)) let changedFieldKeys = recordSet.merge(records: records) let changedRecordKeys = changedFieldKeys.map { self.recordCacheKey(forFieldCacheKey: $0) } - for recordKey in Set(changedRecordKeys) { - if let recordFields = recordSet[recordKey]?.fields { - let recordData = try SQLiteSerialization.serialize(fields: recordFields) - guard let recordString = String(data: recordData, encoding: .utf8) else { - assertionFailure("Serialization should yield UTF-8 data") - continue + + let serializedRecords = try Set(changedRecordKeys) + .compactMap { recordKey -> (CacheKey, String)? in + if let recordFields = recordSet[recordKey]?.fields { + let recordData = try SQLiteSerialization.serialize(fields: recordFields) + guard let recordString = String(data: recordData, encoding: .utf8) else { + assertionFailure("Serialization should yield UTF-8 data") + return nil + } + return (recordKey, recordString) } - - try self.database.addOrUpdateRecordString(recordString, for: recordKey) + return nil } - } + + try self.database.addOrUpdate(records: serializedRecords) return Set(changedFieldKeys) }