177 lines
5.6 KiB
Swift
177 lines
5.6 KiB
Swift
import XCTest
|
|
import GRDB
|
|
|
|
private struct A: Codable, FetchableRecord, PersistableRecord {
|
|
static let b = belongsTo(B.self)
|
|
static let c = hasOne(C.self, through: b, using: B.c)
|
|
var id: Int64
|
|
var bId: Int64?
|
|
var name: String
|
|
}
|
|
|
|
private struct B: Codable, FetchableRecord, PersistableRecord {
|
|
static let c = belongsTo(C.self)
|
|
var id: Int64
|
|
var cId: Int64?
|
|
var name: String
|
|
}
|
|
|
|
private struct C: Codable, FetchableRecord, PersistableRecord {
|
|
var id: Int64
|
|
var name: String
|
|
}
|
|
|
|
private struct AWithRequiredC: Decodable, FetchableRecord {
|
|
var a: A
|
|
var c: C
|
|
}
|
|
|
|
private struct AWithOptionalC: Decodable, FetchableRecord {
|
|
var a: A
|
|
var optionalC: C?
|
|
static let c = A.c.forKey(CodingKeys.optionalC)
|
|
}
|
|
|
|
private struct AWithRequiredBAndOptionalC: Decodable, FetchableRecord {
|
|
var a: A
|
|
var b: B
|
|
var c: C?
|
|
}
|
|
|
|
/// Test support for FetchableRecord records
|
|
class AssociationHasOneThroughDecodableRecordTests: GRDBTestCase {
|
|
|
|
override func setup(_ dbWriter: some DatabaseWriter) throws {
|
|
try dbWriter.write { db in
|
|
try db.create(table: "c") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.column("name", .text)
|
|
}
|
|
try db.create(table: "b") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.belongsTo("c")
|
|
t.column("name", .text)
|
|
}
|
|
try db.create(table: "a") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.belongsTo("b")
|
|
t.column("name", .text)
|
|
}
|
|
|
|
try C(id: 1, name: "c1").insert(db)
|
|
try B(id: 1, cId: 1, name: "b1").insert(db)
|
|
try B(id: 2, cId: nil, name: "b2").insert(db)
|
|
try A(id: 1, bId: 1, name: "a1").insert(db)
|
|
try A(id: 2, bId: 2, name: "a2").insert(db)
|
|
try A(id: 3, bId: nil, name: "a3").insert(db)
|
|
}
|
|
}
|
|
|
|
func testIncludingRequired() throws {
|
|
let dbQueue = try makeDatabaseQueue()
|
|
let request = A
|
|
.including(required: A.c)
|
|
.order(sql: "a.id")
|
|
.asRequest(of: AWithRequiredC.self)
|
|
let records = try dbQueue.inDatabase(request.fetchAll)
|
|
|
|
XCTAssertEqual(records.count, 1)
|
|
|
|
XCTAssertEqual(records[0].a.id, 1)
|
|
XCTAssertEqual(records[0].a.bId, 1)
|
|
XCTAssertEqual(records[0].a.name, "a1")
|
|
XCTAssertEqual(records[0].c.id, 1)
|
|
XCTAssertEqual(records[0].c.name, "c1")
|
|
}
|
|
|
|
func testIncludingOptional() throws {
|
|
let dbQueue = try makeDatabaseQueue()
|
|
let request = A
|
|
.including(optional: AWithOptionalC.c)
|
|
.order(sql: "a.id")
|
|
.asRequest(of: AWithOptionalC.self)
|
|
let records = try dbQueue.inDatabase(request.fetchAll)
|
|
|
|
XCTAssertEqual(records.count, 3)
|
|
|
|
XCTAssertEqual(records[0].a.id, 1)
|
|
XCTAssertEqual(records[0].a.bId, 1)
|
|
XCTAssertEqual(records[0].a.name, "a1")
|
|
XCTAssertEqual(records[0].optionalC!.id, 1)
|
|
XCTAssertEqual(records[0].optionalC!.name, "c1")
|
|
|
|
XCTAssertEqual(records[1].a.id, 2)
|
|
XCTAssertEqual(records[1].a.bId, 2)
|
|
XCTAssertEqual(records[1].a.name, "a2")
|
|
XCTAssertNil(records[1].optionalC)
|
|
|
|
XCTAssertEqual(records[2].a.id, 3)
|
|
XCTAssertNil(records[2].a.bId)
|
|
XCTAssertEqual(records[2].a.name, "a3")
|
|
XCTAssertNil(records[2].optionalC)
|
|
}
|
|
|
|
func testJoiningRequired() throws {
|
|
let dbQueue = try makeDatabaseQueue()
|
|
let request = A
|
|
.joining(required: A.c)
|
|
.order(sql: "a.id")
|
|
let records = try dbQueue.inDatabase(request.fetchAll)
|
|
|
|
XCTAssertEqual(records.count, 1)
|
|
|
|
XCTAssertEqual(records[0].id, 1)
|
|
XCTAssertEqual(records[0].bId, 1)
|
|
XCTAssertEqual(records[0].name, "a1")
|
|
}
|
|
|
|
func testJoiningOptional() throws {
|
|
let dbQueue = try makeDatabaseQueue()
|
|
let request = A
|
|
.joining(optional: A.c)
|
|
.order(sql: "a.id")
|
|
let records = try dbQueue.inDatabase(request.fetchAll)
|
|
|
|
XCTAssertEqual(records.count, 3)
|
|
|
|
XCTAssertEqual(records[0].id, 1)
|
|
XCTAssertEqual(records[0].bId, 1)
|
|
XCTAssertEqual(records[0].name, "a1")
|
|
|
|
XCTAssertEqual(records[1].id, 2)
|
|
XCTAssertEqual(records[1].bId, 2)
|
|
XCTAssertEqual(records[1].name, "a2")
|
|
|
|
XCTAssertEqual(records[2].id, 3)
|
|
XCTAssertNil(records[2].bId)
|
|
XCTAssertEqual(records[2].name, "a3")
|
|
}
|
|
|
|
func testIncludingOptionalIncludingRequiredPivot() throws {
|
|
let dbQueue = try makeDatabaseQueue()
|
|
let request = A
|
|
.including(optional: A.c)
|
|
.including(required: A.b)
|
|
.order(sql: "a.id")
|
|
.asRequest(of: AWithRequiredBAndOptionalC.self)
|
|
let records = try dbQueue.inDatabase(request.fetchAll)
|
|
|
|
XCTAssertEqual(records.count, 2)
|
|
|
|
XCTAssertEqual(records[0].a.id, 1)
|
|
XCTAssertEqual(records[0].a.bId, 1)
|
|
XCTAssertEqual(records[0].a.name, "a1")
|
|
XCTAssertEqual(records[0].b.id, 1)
|
|
XCTAssertEqual(records[0].b.name, "b1")
|
|
XCTAssertEqual(records[0].c!.id, 1)
|
|
XCTAssertEqual(records[0].c!.name, "c1")
|
|
|
|
XCTAssertEqual(records[1].a.id, 2)
|
|
XCTAssertEqual(records[1].a.bId, 2)
|
|
XCTAssertEqual(records[1].a.name, "a2")
|
|
XCTAssertEqual(records[1].b.id, 2)
|
|
XCTAssertEqual(records[1].b.name, "b2")
|
|
XCTAssertNil(records[1].c)
|
|
}
|
|
}
|