diff --git a/Documentation/Index.md b/Documentation/Index.md index 52affae4..b58bf995 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -1963,6 +1963,14 @@ using the following functions. } } ``` + Statements with results may be iterated over, using a `RowIterator` if + useful. + + ```swift + let emailColumn = Expression("email") + let stmt = try db.prepare("SELECT id, email FROM users") + let emails = try! stmt.prepareRowIterator().map { $0[emailColumn] } + ``` - `run` prepares a single `Statement` object from a SQL string, optionally binds values to it (using the statement’s `bind` function), executes, diff --git a/Sources/SQLite/Core/Statement.swift b/Sources/SQLite/Core/Statement.swift index 1e2489b5..5ec430cf 100644 --- a/Sources/SQLite/Core/Statement.swift +++ b/Sources/SQLite/Core/Statement.swift @@ -228,6 +228,21 @@ extension Statement: FailableIterator { } } +extension Statement { + public func prepareRowIterator() -> RowIterator { + return RowIterator(statement: self, columnNames: self.columnNameMap) + } + + var columnNameMap: [String: Int] { + var result = [String: Int]() + for (index, name) in self.columnNames.enumerated() { + result[name.quote()] = index + } + + return result + } +} + extension Statement: CustomStringConvertible { public var description: String { diff --git a/Tests/SQLiteTests/StatementTests.swift b/Tests/SQLiteTests/StatementTests.swift index b4ad7c28..aa05de34 100644 --- a/Tests/SQLiteTests/StatementTests.swift +++ b/Tests/SQLiteTests/StatementTests.swift @@ -23,4 +23,15 @@ class StatementTests: SQLiteTestCase { let blobValue = try! db.scalar(blobs.select(blobColumn).limit(1, offset: 0)) XCTAssertEqual([], blobValue.bytes) } + + func test_prepareRowIterator() { + let names = ["a", "b", "c"] + try! insertUsers(names) + + let emailColumn = Expression("email") + let statement = try! db.prepare("SELECT email FROM users") + let emails = try! statement.prepareRowIterator().map { $0[emailColumn] } + + XCTAssertEqual(names.map({ "\($0)@example.com" }), emails.sorted()) + } }