Skip to content

Commit 12f061c

Browse files
BobaFettersgh-action-runner
authored andcommitted
Adding batching to sqlite selects (#725)
1 parent 05cc940 commit 12f061c

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

apollo-ios/Sources/ApolloSQLite/ApolloSQLiteDatabase.swift

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,39 +86,49 @@ public final class ApolloSQLiteDatabase: SQLiteDatabase {
8686
}
8787

8888
public func selectRawRows(forKeys keys: Set<CacheKey>) throws -> [DatabaseRow] {
89-
guard !keys.isEmpty else { return [] }
90-
91-
return try performSync {
92-
let placeholders = keys.map { _ in "?" }.joined(separator: ", ")
93-
let sql = """
94-
SELECT \(Self.keyColumnName), \(Self.recordColumName) FROM \(Self.tableName)
95-
WHERE \(Self.keyColumnName) IN (\(placeholders))
96-
"""
97-
98-
let stmt = try prepareStatement(sql, errorMessage: "Failed to prepare select statement")
99-
defer { sqlite3_finalize(stmt) }
100-
101-
for (index, key) in keys.enumerated() {
102-
sqlite3_bind_text(stmt, Int32(index + 1), key, -1, SQLITE_TRANSIENT)
103-
}
89+
guard !keys.isEmpty else { return [] }
90+
91+
let batchSize = 500
92+
var allRows = [DatabaseRow]()
93+
let keyBatches = keys.chunked(into: batchSize)
94+
95+
for batch in keyBatches {
96+
let rows = try performSync {
97+
let placeholders = batch.map { _ in "?" }.joined(separator: ", ")
98+
let sql = """
99+
SELECT \(Self.keyColumnName), \(Self.recordColumName)
100+
FROM \(Self.tableName)
101+
WHERE \(Self.keyColumnName) IN (\(placeholders))
102+
"""
103+
104+
let stmt = try prepareStatement(sql, errorMessage: "Failed to prepare select statement")
105+
defer { sqlite3_finalize(stmt) }
106+
107+
for (index, key) in batch.enumerated() {
108+
sqlite3_bind_text(stmt, Int32(index + 1), key, -1, SQLITE_TRANSIENT)
109+
}
104110

105-
var rows = [DatabaseRow]()
106-
var result: Int32
107-
repeat {
108-
result = sqlite3_step(stmt)
109-
if result == SQLITE_ROW {
111+
var rows = [DatabaseRow]()
112+
var result: Int32
113+
repeat {
114+
result = sqlite3_step(stmt)
115+
if result == SQLITE_ROW {
110116
let key = String(cString: sqlite3_column_text(stmt, 0))
111117
let record = String(cString: sqlite3_column_text(stmt, 1))
112118
rows.append(DatabaseRow(cacheKey: key, storedInfo: record))
113-
} else if result != SQLITE_DONE {
119+
} else if result != SQLITE_DONE {
114120
let errorMsg = String(cString: sqlite3_errmsg(db))
115121
throw SQLiteError.step(message: "Failed to step raw row select: \(errorMsg)")
116-
}
117-
} while result != SQLITE_DONE
122+
}
123+
} while result != SQLITE_DONE
118124

125+
return rows
126+
}
119127

120-
return rows
121-
}
128+
allRows.append(contentsOf: rows)
129+
}
130+
131+
return allRows
122132
}
123133

124134
public func addOrUpdate(records: [(cacheKey: CacheKey, recordString: String)]) throws {
@@ -202,3 +212,20 @@ public final class ApolloSQLiteDatabase: SQLiteDatabase {
202212
}
203213
}
204214
}
215+
216+
// MARK: - Extensions
217+
218+
extension Array {
219+
func chunked(into size: Int) -> [[Element]] {
220+
stride(from: 0, to: count, by: size).map {
221+
Array(self[$0..<Swift.min($0 + size, count)])
222+
}
223+
}
224+
}
225+
226+
extension Set {
227+
func chunked(into size: Int) -> [[Element]] {
228+
Array(self).chunked(into: size)
229+
}
230+
}
231+

0 commit comments

Comments
 (0)