The fetchAll
method returns a regular Swift array, that you iterate like all other arrays:
let rows = try Row.fetchAll(db, sql, arguments:arguments) // [Row]
for row in rows {
// use row
}
The next
method belongs to cursors, that you get with the fetchCursor
method. Cursors are not arrays because they don't load all database results in one step. Instead, cursors are iterated row after row:
let rows = try Row.fetchCursor(db, sql, arguments:arguments) // DatabaseCursor<Row>
while let row = try rows.next() {
// use row
}
You see that both arrays and cursors can iterate database results. How do you choose one or the other? Look at the differences:
- Arrays contain copies of database values and may be consumed on any thread.
- Arrays can can take a lot of memory, if the number of fetched results is high.
- Arrays can be iterated many times.
- Cursors iterate over database results in a lazy fashion, and don't consume much memory.
- Cursors are faster because they go straight to SQLite and don't copy database values unless necessary.
- Cursors can not be used on any thread.
- Cursors can be iterated only one time.
Compare:
// On the main thread:
let (rowArray, rowCursor) = try dbQueue.inDatabase { db -> ([Row], DatabaseCursor<Row>) in
let rowArray = try Row.fetchAll(db, "SELECT ...")
let rowCursor = try Row.fetchCursor(db, "SELECT ...")
// OK
for row in rowArray { ... }
while let row = try rowCursor.next() { ... }
// Second iteration
for row in rowArray { ... } // the same rows
while let row = try rowCursor.next() { ... } // no result
return (rowArray, rowCursor)
}
// OK: arrays can be consumed on any thread
for row in rowArray { ... }
DispatchQueue.global(.default).async {
for row in rowArray { ... }
}
// DON'T DO THAT, NEVER
while let row = try rowCursor.next() { ... }
DispatchQueue.global(.default).async {
while let row = try rowCursor.next() { ... }
}
If you don't see, or don't care about the difference, use arrays. If you care about memory and performance, use cursors when appropriate.
Link to the documentation: https://github.com/groue/GRDB.swift/blob/master/README.md#fetching-methods