857 lines
43 KiB
Swift
857 lines
43 KiB
Swift
import XCTest
|
|
import GRDB
|
|
|
|
/// Test SQL generation
|
|
class AssociationHasOneSQLTests: GRDBTestCase {
|
|
|
|
func testSingleColumnNoForeignKeyNoPrimaryKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["id"] = 1
|
|
container["rowid"] = 2
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.column("id", .integer)
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parentId", .integer)
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."rowid"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."rowid"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."rowid"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."rowid"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 2")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSingleColumnNoForeignKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["id"] = 1
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.primaryKey("id", .integer)
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parentId", .integer)
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSingleColumnSingleForeignKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["id"] = 1
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.primaryKey("id", .integer)
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.belongsTo("parent")
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self),
|
|
Parent.hasOne(Table(Child.databaseTableName)),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentId")], to: [Column("id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parentId" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parentId\" = 1")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSingleColumnSeveralForeignKeys() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["id"] = 1
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.primaryKey("id", .integer)
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.belongsTo("parent1", inTable: "parents")
|
|
t.belongsTo("parent2", inTable: "parents")
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent1Id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent1Id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parent1Id\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent1Id")], to: [Column("id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent1Id")], to: [Column("id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent1Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parent1Id\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent2Id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent2Id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parent2Id\" = 1")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent2Id")], to: [Column("id")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent2Id")], to: [Column("id")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON "children"."parent2Id" = "parents"."id"
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE \"parent2Id\" = 1")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCompoundColumnNoForeignKeyNoPrimaryKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["a"] = 1
|
|
container["b"] = 2
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.column("a", .integer)
|
|
t.column("b", .integer)
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parentA", .integer)
|
|
t.column("parentB", .integer)
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCompoundColumnNoForeignKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["a"] = 1
|
|
container["b"] = 2
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.column("a", .integer)
|
|
t.column("b", .integer)
|
|
t.primaryKey(["a", "b"])
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parentA", .integer)
|
|
t.column("parentB", .integer)
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentA"), Column("parentB")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentA"), Column("parentB")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCompoundColumnSingleForeignKey() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["a"] = 1
|
|
container["b"] = 2
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.column("a", .integer)
|
|
t.column("b", .integer)
|
|
t.primaryKey(["a", "b"])
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parentA", .integer)
|
|
t.column("parentB", .integer)
|
|
t.foreignKey(["parentA", "parentB"], references: "parents")
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self),
|
|
Parent.hasOne(Table(Child.databaseTableName)),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentA"), Column("parentB")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentA"), Column("parentB")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parentA"), Column("parentB")], to: [Column("a"), Column("b")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parentA" = "parents"."a") AND ("children"."parentB" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parentA\" = 1) AND (\"parentB\" = 2)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testCompoundColumnSeveralForeignKeys() throws {
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
}
|
|
|
|
struct Parent : TableRecord, EncodableRecord {
|
|
static let databaseTableName = "parents"
|
|
func encode(to container: inout PersistenceContainer) {
|
|
container["a"] = 1
|
|
container["b"] = 2
|
|
}
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "parents") { t in
|
|
t.column("a", .integer)
|
|
t.column("b", .integer)
|
|
t.primaryKey(["a", "b"])
|
|
}
|
|
try db.create(table: "children") { t in
|
|
t.column("parent1A", .integer)
|
|
t.column("parent1B", .integer)
|
|
t.column("parent2A", .integer)
|
|
t.column("parent2B", .integer)
|
|
t.foreignKey(["parent1A", "parent1B"], references: "parents")
|
|
t.foreignKey(["parent2A", "parent2B"], references: "parents")
|
|
}
|
|
}
|
|
|
|
try dbQueue.inDatabase { db in
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent1A"), Column("parent1B")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent1A"), Column("parent1B")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parent1A\" = 1) AND (\"parent1B\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent1A"), Column("parent1B")], to: [Column("a"), Column("b")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent1A"), Column("parent1B")], to: [Column("a"), Column("b")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent1A" = "parents"."a") AND ("children"."parent1B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parent1A\" = 1) AND (\"parent1B\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent2A"), Column("parent2B")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent2A"), Column("parent2B")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parent2A\" = 1) AND (\"parent2B\" = 2)")
|
|
}
|
|
|
|
for association in [
|
|
Parent.hasOne(Child.self,
|
|
using: ForeignKey([Column("parent2A"), Column("parent2B")], to: [Column("a"), Column("b")])),
|
|
Parent.hasOne(Table(Child.databaseTableName),
|
|
using: ForeignKey([Column("parent2A"), Column("parent2B")], to: [Column("a"), Column("b")])),
|
|
] {
|
|
try assertEqualSQL(db, Parent.all().including(required: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().including(optional: association), """
|
|
SELECT "parents".*, "children".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(required: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent.all().joining(optional: association), """
|
|
SELECT "parents".* \
|
|
FROM "parents" \
|
|
LEFT JOIN "children" ON ("children"."parent2A" = "parents"."a") AND ("children"."parent2B" = "parents"."b")
|
|
""")
|
|
try assertEqualSQL(db, Parent().request(for: association), "SELECT * FROM \"children\" WHERE (\"parent2A\" = 1) AND (\"parent2B\" = 2)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func testForeignKeyDefinitionFromColumn() {
|
|
// This test pass if code compiles
|
|
struct Parent : TableRecord {
|
|
static let databaseTableName = "parents"
|
|
enum Columns {
|
|
static let id = Column("id")
|
|
}
|
|
static let child1 = hasOne(Child.self, using: Child.ForeignKeys.parent1)
|
|
static let child2 = hasOne(Child.self, using: Child.ForeignKeys.parent2)
|
|
}
|
|
|
|
struct Child : TableRecord {
|
|
static let databaseTableName = "children"
|
|
enum Columns {
|
|
static let parentId = Column("parentId")
|
|
}
|
|
enum ForeignKeys {
|
|
static let parent1 = ForeignKey([Columns.parentId])
|
|
static let parent2 = ForeignKey([Columns.parentId], to: [Parent.Columns.id])
|
|
}
|
|
}
|
|
}
|
|
}
|