@@ -86,39 +86,49 @@ public final class ApolloSQLiteDatabase: SQLiteDatabase {
86
86
}
87
87
88
88
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
+ }
104
110
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 {
110
116
let key = String ( cString: sqlite3_column_text ( stmt, 0 ) )
111
117
let record = String ( cString: sqlite3_column_text ( stmt, 1 ) )
112
118
rows. append ( DatabaseRow ( cacheKey: key, storedInfo: record) )
113
- } else if result != SQLITE_DONE {
119
+ } else if result != SQLITE_DONE {
114
120
let errorMsg = String ( cString: sqlite3_errmsg ( db) )
115
121
throw SQLiteError . step ( message: " Failed to step raw row select: \( errorMsg) " )
116
- }
117
- } while result != SQLITE_DONE
122
+ }
123
+ } while result != SQLITE_DONE
118
124
125
+ return rows
126
+ }
119
127
120
- return rows
121
- }
128
+ allRows. append ( contentsOf: rows)
129
+ }
130
+
131
+ return allRows
122
132
}
123
133
124
134
public func addOrUpdate( records: [ ( cacheKey: CacheKey , recordString: String ) ] ) throws {
@@ -202,3 +212,20 @@ public final class ApolloSQLiteDatabase: SQLiteDatabase {
202
212
}
203
213
}
204
214
}
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