Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/GRDBTests/AssociationParallelDecodableRecordTests.swift

232 lines
8.0 KiB
Swift

import XCTest
import GRDB
// A -> B
// A -> D
private struct A: Codable, FetchableRecord, PersistableRecord {
static let databaseTableName = "a"
static let b = belongsTo(B.self)
static let d = belongsTo(D.self)
var id: Int64
var bid: Int64?
var did: Int64?
var name: String
}
private struct B: Codable, FetchableRecord, PersistableRecord {
static let a = hasOne(A.self)
static let databaseTableName = "b"
var id: Int64
var name: String
}
private struct D: Codable, FetchableRecord, PersistableRecord {
static let a = hasOne(A.self)
static let databaseTableName = "d"
var id: Int64
var name: String
}
private struct AWithRequiredBD: Decodable, FetchableRecord {
var a: A
var b: B
var d: D
static let b = A.b.forKey(CodingKeys.b)
static let d = A.d.forKey(CodingKeys.d)
}
private struct AWithOptionalBD: Decodable, FetchableRecord {
var a: A
var b: B?
var d: D?
static let b = A.b.forKey(CodingKeys.b)
static let d = A.d.forKey(CodingKeys.d)
}
/// Test support for Decodable records
class AssociationParallelDecodableRecordTests: GRDBTestCase {
override func setup(_ dbWriter: some DatabaseWriter) throws {
try dbWriter.write { db in
try db.create(table: "b") { t in
t.primaryKey("id", .integer)
t.column("name", .text)
}
try db.create(table: "d") { t in
t.primaryKey("id", .integer)
t.column("name", .text)
}
try db.create(table: "a") { t in
t.primaryKey("id", .integer)
t.column("bid", .integer).references("b")
t.column("did", .integer).references("d")
t.column("name", .text)
}
try B(id: 1, name: "b1").insert(db)
try B(id: 2, name: "b2").insert(db)
try B(id: 3, name: "b3").insert(db)
try D(id: 1, name: "d1").insert(db)
try A(id: 1, bid: 1, did: 1, name: "a1").insert(db)
try A(id: 2, bid: 1, did: nil, name: "a2").insert(db)
try A(id: 3, bid: 2, did: 1, name: "a3").insert(db)
try A(id: 4, bid: 2, did: nil, name: "a4").insert(db)
try A(id: 5, bid: nil, did: 1, name: "a5").insert(db)
try A(id: 6, bid: nil, did: nil, name: "a6").insert(db)
}
}
func testParallelTwoIncludingRequired() throws {
let dbQueue = try makeDatabaseQueue()
let request = A
.including(required: AWithRequiredBD.b)
.including(required: AWithRequiredBD.d)
.order(sql: "a.id, b.id, d.id")
.asRequest(of: AWithRequiredBD.self)
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
XCTAssertEqual(records.count, 2)
XCTAssertEqual(records[0].a.id, 1)
XCTAssertEqual(records[0].a.bid, 1)
XCTAssertEqual(records[0].a.did, 1)
XCTAssertEqual(records[0].a.name, "a1")
XCTAssertEqual(records[0].b.id, 1)
XCTAssertEqual(records[0].b.name, "b1")
XCTAssertEqual(records[0].d.id, 1)
XCTAssertEqual(records[0].d.name, "d1")
XCTAssertEqual(records[1].a.id, 3)
XCTAssertEqual(records[1].a.bid, 2)
XCTAssertEqual(records[1].a.did, 1)
XCTAssertEqual(records[1].a.name, "a3")
XCTAssertEqual(records[1].b.id, 2)
XCTAssertEqual(records[1].b.name, "b2")
XCTAssertEqual(records[1].d.id, 1)
XCTAssertEqual(records[1].d.name, "d1")
}
func testParallelTwoIncludingOptional() throws {
let dbQueue = try makeDatabaseQueue()
let request = A
.including(optional: AWithOptionalBD.b)
.including(optional: AWithOptionalBD.d)
.order(sql: "a.id, b.id, d.id")
.asRequest(of: AWithOptionalBD.self)
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
XCTAssertEqual(records.count, 6)
XCTAssertEqual(records[0].a.id, 1)
XCTAssertEqual(records[0].a.bid, 1)
XCTAssertEqual(records[0].a.did, 1)
XCTAssertEqual(records[0].a.name, "a1")
XCTAssertEqual(records[0].b!.id, 1)
XCTAssertEqual(records[0].b!.name, "b1")
XCTAssertEqual(records[0].d!.id, 1)
XCTAssertEqual(records[0].d!.name, "d1")
XCTAssertEqual(records[1].a.id, 2)
XCTAssertEqual(records[1].a.bid, 1)
XCTAssertEqual(records[1].a.did, nil)
XCTAssertEqual(records[1].a.name, "a2")
XCTAssertEqual(records[1].b!.id, 1)
XCTAssertEqual(records[1].b!.name, "b1")
XCTAssertNil(records[1].d)
XCTAssertEqual(records[2].a.id, 3)
XCTAssertEqual(records[2].a.bid, 2)
XCTAssertEqual(records[2].a.did, 1)
XCTAssertEqual(records[2].a.name, "a3")
XCTAssertEqual(records[2].b!.id, 2)
XCTAssertEqual(records[2].b!.name, "b2")
XCTAssertEqual(records[2].d!.id, 1)
XCTAssertEqual(records[2].d!.name, "d1")
XCTAssertEqual(records[3].a.id, 4)
XCTAssertEqual(records[3].a.bid, 2)
XCTAssertEqual(records[3].a.did, nil)
XCTAssertEqual(records[3].a.name, "a4")
XCTAssertEqual(records[3].b!.id, 2)
XCTAssertEqual(records[3].b!.name, "b2")
XCTAssertNil(records[3].d)
XCTAssertEqual(records[4].a.id, 5)
XCTAssertEqual(records[4].a.bid, nil)
XCTAssertEqual(records[4].a.did, 1)
XCTAssertEqual(records[4].a.name, "a5")
XCTAssertNil(records[4].b)
XCTAssertEqual(records[4].d!.id, 1)
XCTAssertEqual(records[4].d!.name, "d1")
XCTAssertEqual(records[5].a.id, 6)
XCTAssertEqual(records[5].a.bid, nil)
XCTAssertEqual(records[5].a.did, nil)
XCTAssertEqual(records[5].a.name, "a6")
XCTAssertNil(records[5].b)
XCTAssertNil(records[5].d)
}
func testParallelTwoJoiningRequired() throws {
let dbQueue = try makeDatabaseQueue()
let request = A
.joining(required: A.b)
.joining(required: A.d)
.order(sql: "a.id, b.id, d.id")
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
XCTAssertEqual(records.count, 2)
XCTAssertEqual(records[0].id, 1)
XCTAssertEqual(records[0].bid, 1)
XCTAssertEqual(records[0].did, 1)
XCTAssertEqual(records[0].name, "a1")
XCTAssertEqual(records[1].id, 3)
XCTAssertEqual(records[1].bid, 2)
XCTAssertEqual(records[1].did, 1)
XCTAssertEqual(records[1].name, "a3")
}
func testParallelTwoJoiningOptional() throws {
let dbQueue = try makeDatabaseQueue()
let request = A
.joining(optional: A.b)
.joining(optional: A.d)
.order(sql: "a.id, b.id, d.id")
let records = try dbQueue.inDatabase { try request.fetchAll($0) }
XCTAssertEqual(records.count, 6)
XCTAssertEqual(records[0].id, 1)
XCTAssertEqual(records[0].bid, 1)
XCTAssertEqual(records[0].did, 1)
XCTAssertEqual(records[0].name, "a1")
XCTAssertEqual(records[1].id, 2)
XCTAssertEqual(records[1].bid, 1)
XCTAssertEqual(records[1].did, nil)
XCTAssertEqual(records[1].name, "a2")
XCTAssertEqual(records[2].id, 3)
XCTAssertEqual(records[2].bid, 2)
XCTAssertEqual(records[2].did, 1)
XCTAssertEqual(records[2].name, "a3")
XCTAssertEqual(records[3].id, 4)
XCTAssertEqual(records[3].bid, 2)
XCTAssertEqual(records[3].did, nil)
XCTAssertEqual(records[3].name, "a4")
XCTAssertEqual(records[4].id, 5)
XCTAssertEqual(records[4].bid, nil)
XCTAssertEqual(records[4].did, 1)
XCTAssertEqual(records[4].name, "a5")
XCTAssertEqual(records[5].id, 6)
XCTAssertEqual(records[5].bid, nil)
XCTAssertEqual(records[5].did, nil)
XCTAssertEqual(records[5].name, "a6")
}
}