Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/GRDBTests/FetchableRecord+QueryInterfaceRequestTests.swift
T
2025-01-28 12:28:03 +08:00

207 lines
7.4 KiB
Swift

import XCTest
import GRDB
private struct Reader: Hashable {
var id: Int64?
let name: String
let age: Int?
}
extension Reader : FetchableRecord {
init(row: Row) {
id = row["id"]
name = row["name"]
age = row["age"]
}
}
extension Reader : MutablePersistableRecord {
static let databaseTableName = "readers"
func encode(to container: inout PersistenceContainer) {
container["id"] = id
container["name"] = name
container["age"] = age
}
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
private struct AltReader {
var id: Int64?
let name: String
let age: Int?
}
extension AltReader : FetchableRecord {
init(row: Row) {
id = row["id"]
name = row["name"]
age = row["age"]
}
}
class FetchableRecordQueryInterfaceRequestTests: GRDBTestCase {
override func setup(_ dbWriter: some DatabaseWriter) throws {
var migrator = DatabaseMigrator()
migrator.registerMigration("createReaders") { db in
try db.execute(sql: """
CREATE TABLE readers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INT)
""")
}
try migrator.migrate(dbWriter)
}
// MARK: - Fetch FetchableRecord
func testAll() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var arthur = Reader(id: nil, name: "Arthur", age: 42)
try arthur.insert(db)
var barbara = Reader(id: nil, name: "Barbara", age: 36)
try barbara.insert(db)
let request = Reader.all()
do {
let readers = try request.fetchAll(db)
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
XCTAssertEqual(readers.count, 2)
XCTAssertEqual(readers[0].id!, arthur.id!)
XCTAssertEqual(readers[0].name, arthur.name)
XCTAssertEqual(readers[0].age, arthur.age)
XCTAssertEqual(readers[1].id!, barbara.id!)
XCTAssertEqual(readers[1].name, barbara.name)
XCTAssertEqual(readers[1].age, barbara.age)
}
do {
let reader = try request.fetchOne(db)!
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\" LIMIT 1")
XCTAssertEqual(reader.id!, arthur.id!)
XCTAssertEqual(reader.name, arthur.name)
XCTAssertEqual(reader.age, arthur.age)
}
do {
let names = try request.fetchCursor(db).map(\.name)
XCTAssertEqual(try names.next()!, arthur.name)
XCTAssertEqual(try names.next()!, barbara.name)
XCTAssertTrue(try names.next() == nil)
// validate query *after* cursor has retrieved a record
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
}
}
}
func testFetch() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var arthur = Reader(id: nil, name: "Arthur", age: 42)
try arthur.insert(db)
var barbara = Reader(id: nil, name: "Barbara", age: 36)
try barbara.insert(db)
do {
let readers = try Reader.fetchAll(db)
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
XCTAssertEqual(readers.count, 2)
XCTAssertEqual(readers[0].id!, arthur.id!)
XCTAssertEqual(readers[0].name, arthur.name)
XCTAssertEqual(readers[0].age, arthur.age)
XCTAssertEqual(readers[1].id!, barbara.id!)
XCTAssertEqual(readers[1].name, barbara.name)
XCTAssertEqual(readers[1].age, barbara.age)
}
do {
let readers = try Reader.fetchSet(db)
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
XCTAssertEqual(readers.count, 2)
XCTAssertEqual(Set(readers.map(\.id)), [arthur.id!, barbara.id!])
XCTAssertEqual(Set(readers.map(\.name)), [arthur.name, barbara.name])
XCTAssertEqual(Set(readers.map(\.age)), [arthur.age, barbara.age])
}
do {
let reader = try Reader.fetchOne(db)!
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\" LIMIT 1")
XCTAssertEqual(reader.id!, arthur.id!)
XCTAssertEqual(reader.name, arthur.name)
XCTAssertEqual(reader.age, arthur.age)
}
do {
let cursor = try Reader.fetchCursor(db)
let names = cursor.map(\.name)
XCTAssertEqual(try names.next()!, arthur.name)
XCTAssertEqual(try names.next()!, barbara.name)
XCTAssertTrue(try names.next() == nil)
// validate query *after* cursor has retrieved a record
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
}
do {
let reader = try Reader.limit(1, offset: 1).fetchOne(db)!
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\" LIMIT 1 OFFSET 1")
XCTAssertEqual(reader.id!, barbara.id!)
XCTAssertEqual(reader.name, barbara.name)
XCTAssertEqual(reader.age, barbara.age)
}
}
}
func testAlternativeFetch() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
var arthur = Reader(id: nil, name: "Arthur", age: 42)
try arthur.insert(db)
var barbara = Reader(id: nil, name: "Barbara", age: 36)
try barbara.insert(db)
let request = Reader.all()
do {
let readers = try AltReader.fetchAll(db, request)
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
XCTAssertEqual(readers.count, 2)
XCTAssertEqual(readers[0].id!, arthur.id!)
XCTAssertEqual(readers[0].name, arthur.name)
XCTAssertEqual(readers[0].age, arthur.age)
XCTAssertEqual(readers[1].id!, barbara.id!)
XCTAssertEqual(readers[1].name, barbara.name)
XCTAssertEqual(readers[1].age, barbara.age)
}
do {
let reader = try AltReader.fetchOne(db, request)!
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\" LIMIT 1")
XCTAssertEqual(reader.id!, arthur.id!)
XCTAssertEqual(reader.name, arthur.name)
XCTAssertEqual(reader.age, arthur.age)
}
do {
let names = try AltReader.fetchCursor(db, request).map(\.name)
XCTAssertEqual(try names.next()!, arthur.name)
XCTAssertEqual(try names.next()!, barbara.name)
XCTAssertTrue(try names.next() == nil)
// validate query *after* cursor has retrieved a record
XCTAssertEqual(lastSQLQuery, "SELECT * FROM \"readers\"")
}
}
}
}