add
This commit is contained in:
-736
@@ -1,736 +0,0 @@
|
||||
import XCTest
|
||||
@testable import GRDB
|
||||
|
||||
class AssociationPrefetchingRelationTests: GRDBTestCase {
|
||||
func testAssociationKeyInflections() {
|
||||
do {
|
||||
let key = SQLAssociationKey.inflected("player")
|
||||
XCTAssertEqual(key.baseName, "player")
|
||||
XCTAssertEqual(key.singularizedName, "player")
|
||||
XCTAssertEqual(key.pluralizedName, "players")
|
||||
XCTAssertEqual(key.name(singular: true), "player")
|
||||
XCTAssertEqual(key.name(singular: false), "players")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixedSingular("player")
|
||||
XCTAssertEqual(key.baseName, "player")
|
||||
XCTAssertEqual(key.singularizedName, "player")
|
||||
XCTAssertEqual(key.pluralizedName, "players")
|
||||
XCTAssertEqual(key.name(singular: true), "player")
|
||||
XCTAssertEqual(key.name(singular: false), "players")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixedSingular("players")
|
||||
XCTAssertEqual(key.baseName, "players")
|
||||
XCTAssertEqual(key.singularizedName, "players")
|
||||
XCTAssertEqual(key.pluralizedName, "players")
|
||||
XCTAssertEqual(key.name(singular: true), "players")
|
||||
XCTAssertEqual(key.name(singular: false), "players")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixedPlural("player")
|
||||
XCTAssertEqual(key.baseName, "player")
|
||||
XCTAssertEqual(key.singularizedName, "player")
|
||||
XCTAssertEqual(key.pluralizedName, "player")
|
||||
XCTAssertEqual(key.name(singular: true), "player")
|
||||
XCTAssertEqual(key.name(singular: false), "player")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixedPlural("players")
|
||||
XCTAssertEqual(key.baseName, "players")
|
||||
XCTAssertEqual(key.singularizedName, "player")
|
||||
XCTAssertEqual(key.pluralizedName, "players")
|
||||
XCTAssertEqual(key.name(singular: true), "player")
|
||||
XCTAssertEqual(key.name(singular: false), "players")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixed("player")
|
||||
XCTAssertEqual(key.baseName, "player")
|
||||
XCTAssertEqual(key.singularizedName, "player")
|
||||
XCTAssertEqual(key.pluralizedName, "player")
|
||||
XCTAssertEqual(key.name(singular: true), "player")
|
||||
XCTAssertEqual(key.name(singular: false), "player")
|
||||
}
|
||||
do {
|
||||
let key = SQLAssociationKey.fixed("players")
|
||||
XCTAssertEqual(key.baseName, "players")
|
||||
XCTAssertEqual(key.singularizedName, "players")
|
||||
XCTAssertEqual(key.pluralizedName, "players")
|
||||
XCTAssertEqual(key.name(singular: true), "players")
|
||||
XCTAssertEqual(key.name(singular: false), "players")
|
||||
}
|
||||
}
|
||||
|
||||
func testOneStep() {
|
||||
let cardinalities: [SQLAssociationCardinality] = [
|
||||
.toOne,
|
||||
.toMany,
|
||||
]
|
||||
|
||||
let keys: [SQLAssociationKey] = [
|
||||
.inflected("player"),
|
||||
.fixedSingular("player"),
|
||||
.fixedSingular("players"),
|
||||
.fixedPlural("player"),
|
||||
.fixedPlural("players"),
|
||||
.fixed("player"),
|
||||
]
|
||||
|
||||
for cardinality in cardinalities {
|
||||
for key in keys {
|
||||
|
||||
let relation = SQLRelation.all(fromTable: "ignored")
|
||||
|
||||
let association = _SQLAssociation(
|
||||
key: key,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality)
|
||||
|
||||
for relation in [
|
||||
relation._joining(optional: association),
|
||||
relation._including(optional: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._including(all: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .all)
|
||||
}
|
||||
}
|
||||
|
||||
for relation in [
|
||||
relation._joining(required: association),
|
||||
relation._including(required: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._including(all: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .all)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
let relation = relation._including(all: association)
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._joining(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneOptional)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._joining(required: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneRequired)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._including(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneOptional)
|
||||
}
|
||||
if key.name(singular: true) != key.name(singular: false) {
|
||||
let relation = relation._including(required: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(all: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .all)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testTwoSteps() {
|
||||
let cardinalities: [SQLAssociationCardinality] = [
|
||||
.toOne,
|
||||
.toMany,
|
||||
]
|
||||
|
||||
let keys1: [SQLAssociationKey] = [
|
||||
.inflected("player"),
|
||||
.fixedSingular("player"),
|
||||
.fixedSingular("players"),
|
||||
.fixedPlural("player"),
|
||||
.fixedPlural("players"),
|
||||
.fixed("player"),
|
||||
]
|
||||
|
||||
let keys2: [SQLAssociationKey] = [
|
||||
.inflected("award"),
|
||||
.fixedSingular("award"),
|
||||
.fixedSingular("awards"),
|
||||
.fixedPlural("award"),
|
||||
.fixedPlural("awards"),
|
||||
.fixed("award"),
|
||||
]
|
||||
|
||||
for cardinality1 in cardinalities {
|
||||
for key1 in keys1 {
|
||||
for cardinality2 in cardinalities {
|
||||
for key2 in keys2 {
|
||||
let relation = SQLRelation.all(fromTable: "ignored")
|
||||
|
||||
let association1 = _SQLAssociation(
|
||||
key: key1,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality1)
|
||||
|
||||
let association2 = _SQLAssociation(
|
||||
key: key2,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality2)
|
||||
|
||||
let association = association2.through(association1)
|
||||
|
||||
for relation in [
|
||||
relation._joining(optional: association),
|
||||
relation._including(optional: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
do {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._including(all: association1)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 0)
|
||||
}
|
||||
}
|
||||
do {
|
||||
do {
|
||||
let relation = relation._joining(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._including(all: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children[0].key, key2.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.relation.children[0].value.kind, .all)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for relation in [
|
||||
relation._joining(required: association),
|
||||
relation._including(required: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
do {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._including(all: association1)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 0)
|
||||
}
|
||||
}
|
||||
do {
|
||||
do {
|
||||
let relation = relation._joining(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(optional: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._including(required: association)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._including(all: association)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children[0].key, key2.name(singular: false))
|
||||
XCTAssertEqual(relation.children[1].value.relation.children[0].value.kind, .all)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
let relation = relation._including(all: association)
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .all)
|
||||
}
|
||||
|
||||
// TODO: here we see the problem: it should be possible to merge association1 when it is singular.
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testThreeSteps() {
|
||||
let cardinalities: [SQLAssociationCardinality] = [
|
||||
.toOne,
|
||||
.toMany,
|
||||
]
|
||||
|
||||
let keys1: [SQLAssociationKey] = [
|
||||
.inflected("player"),
|
||||
.fixedSingular("player"),
|
||||
.fixedSingular("players"),
|
||||
.fixedPlural("player"),
|
||||
.fixedPlural("players"),
|
||||
.fixed("player"),
|
||||
]
|
||||
|
||||
let keys2: [SQLAssociationKey] = [
|
||||
.inflected("award"),
|
||||
.fixedSingular("award"),
|
||||
.fixedSingular("awards"),
|
||||
.fixedPlural("award"),
|
||||
.fixedPlural("awards"),
|
||||
.fixed("award"),
|
||||
]
|
||||
|
||||
let keys3: [SQLAssociationKey] = [
|
||||
.inflected("sponsor"),
|
||||
.fixedSingular("sponsor"),
|
||||
.fixedSingular("sponsors"),
|
||||
.fixedPlural("sponsor"),
|
||||
.fixedPlural("sponsors"),
|
||||
.fixed("sponsor"),
|
||||
]
|
||||
|
||||
for cardinality1 in cardinalities {
|
||||
for key1 in keys1 {
|
||||
for cardinality2 in cardinalities {
|
||||
for key2 in keys2 {
|
||||
for cardinality3 in cardinalities {
|
||||
for key3 in keys3 {
|
||||
let relation = SQLRelation.all(fromTable: "ignored")
|
||||
|
||||
let association1 = _SQLAssociation(
|
||||
key: key1,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality1)
|
||||
|
||||
let association2 = _SQLAssociation(
|
||||
key: key2,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality2)
|
||||
|
||||
let association3 = _SQLAssociation(
|
||||
key: key3,
|
||||
condition: .none,
|
||||
relation: .all(fromTable: "ignored"),
|
||||
cardinality: cardinality3)
|
||||
|
||||
for association in [
|
||||
association3.through(association2.through(association1)),
|
||||
association3.through(association2).through(association1),
|
||||
] {
|
||||
|
||||
for relation in [
|
||||
relation._joining(optional: association),
|
||||
relation._including(optional: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .oneOptional)
|
||||
}
|
||||
}
|
||||
|
||||
for relation in [
|
||||
relation._joining(required: association),
|
||||
relation._including(required: association),
|
||||
] {
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
do {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: true))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .oneRequired)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
let relation = relation._including(all: association)
|
||||
do {
|
||||
XCTAssertEqual(relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: cardinality2.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .all)
|
||||
}
|
||||
// TODO: here we see the problem: it should be possible to merge association1 when it is singular.
|
||||
if !cardinality1.isSingular && key1.name(singular: true) != key1.name(singular: false) {
|
||||
let relation = relation._joining(optional: association1)
|
||||
XCTAssertEqual(relation.children.count, 2)
|
||||
XCTAssertEqual(relation.children[0].key, key1.name(singular: cardinality1.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].key, key2.name(singular: cardinality2.isSingular))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.kind, .bridge)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children.count, 1)
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].key, key3.name(singular: false))
|
||||
XCTAssertEqual(relation.children[0].value.relation.children[0].value.relation.children[0].value.kind, .all)
|
||||
XCTAssertEqual(relation.children[1].key, key1.name(singular: true))
|
||||
XCTAssertEqual(relation.children[1].value.kind, .oneOptional)
|
||||
XCTAssertEqual(relation.children[1].value.relation.children.count, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for <https://github.com/groue/GRDB.swift/issues/1315>
|
||||
func testIssue1315() throws {
|
||||
struct A: TableRecord {
|
||||
static let b = belongsTo(B.self)
|
||||
}
|
||||
struct B: TableRecord {
|
||||
static let c = hasOne(C.self)
|
||||
static let e = hasOne(E.self)
|
||||
}
|
||||
struct C: TableRecord {
|
||||
static let ds = hasMany(D.self)
|
||||
}
|
||||
struct D: TableRecord { }
|
||||
struct E: TableRecord {
|
||||
static let fs = hasMany(F.self)
|
||||
}
|
||||
struct F: TableRecord { }
|
||||
|
||||
try DatabaseQueue().write { db in
|
||||
try db.execute(sql: """
|
||||
CREATE TABLE b (id INTEGER PRIMARY KEY);
|
||||
CREATE TABLE a (id INTEGER PRIMARY KEY, bId INTEGER REFERENCES b(id));
|
||||
CREATE TABLE c (id INTEGER PRIMARY KEY, bId INTEGER REFERENCES b(id));
|
||||
CREATE TABLE d (id INTEGER PRIMARY KEY, cId INTEGER REFERENCES c(id));
|
||||
CREATE TABLE e (id INTEGER PRIMARY KEY, bId INTEGER REFERENCES b(id));
|
||||
CREATE TABLE f (id INTEGER PRIMARY KEY, eId INTEGER REFERENCES e(id));
|
||||
""")
|
||||
|
||||
let region = try A
|
||||
.including(required: A.b
|
||||
.including(optional: B.c.including(all: C.ds))
|
||||
.including(optional: B.e.including(all: E.fs)))
|
||||
.databaseRegion(db)
|
||||
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "a")))
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "b")))
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "c")))
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "d")))
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "e")))
|
||||
XCTAssertTrue(region.isModified(byEventsOfKind: .insert(tableName: "f")))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user