Skip to content

Handle FK definitions w/o key references #1210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions SQLite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@
DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; };
EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
Expand Down Expand Up @@ -340,6 +343,7 @@
DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = "<group>"; };
DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = "<group>"; };
DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = "<group>"; };
DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = "<group>"; };
EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = "<group>"; };
EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -483,6 +487,7 @@
19A17B56FBA20E7245BC8AC0 /* Schema */ = {
isa = PBXGroup;
children = (
DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */,
19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */,
19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */,
19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */,
Expand Down Expand Up @@ -998,6 +1003,7 @@
19A17FACE8E4D54A50BA934E /* FTS5Tests.swift in Sources */,
19A177909023B7B940C5805E /* FTSIntegrationTests.swift in Sources */,
19A17E1DD976D5CE80018749 /* FTS4Tests.swift in Sources */,
DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */,
19A17411403D60640467209E /* ExpressionTests.swift in Sources */,
19A17CA4D7B63D845428A9C5 /* StatementTests.swift in Sources */,
19A17885B646CB0201BE4BD5 /* QueryTests.swift in Sources */,
Expand Down Expand Up @@ -1119,6 +1125,7 @@
19A178DA2BB5970778CCAF13 /* FTS5Tests.swift in Sources */,
19A1755C49154C87304C9146 /* FTSIntegrationTests.swift in Sources */,
19A17444861E1443143DEB44 /* FTS4Tests.swift in Sources */,
DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */,
19A17DD33C2E43DD6EE05A60 /* ExpressionTests.swift in Sources */,
19A17D6EC40BC35A5DC81BA8 /* StatementTests.swift in Sources */,
19A17E3F47DA087E2B76D087 /* QueryTests.swift in Sources */,
Expand Down Expand Up @@ -1199,6 +1206,7 @@
19A1776BD5127DFDF847FF1F /* FTS5Tests.swift in Sources */,
19A173088B85A7E18E8582A7 /* FTSIntegrationTests.swift in Sources */,
19A178767223229E61C5066F /* FTS4Tests.swift in Sources */,
DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */,
19A1781CBA8968ABD3E00877 /* ExpressionTests.swift in Sources */,
19A17923494236793893BF72 /* StatementTests.swift in Sources */,
19A17A52BF29D27C9AA229E7 /* QueryTests.swift in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions Sources/SQLite/Schema/SchemaDefinitions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public struct ColumnDefinition: Equatable {
public struct ForeignKey: Equatable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to sidetrack this. But maybe while you are at it...

The ForeignKey struct is public, but its fields are not. Should they be public as well (given that the fields of ColumnDefinition itself are all are public)?

Copy link
Collaborator Author

@jberkel jberkel May 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, quite a few more schema related fields are internal. I don't remember now if this was deliberate, but it looks like they should all be exposed.

let table: String
let column: String
let primaryKey: String
let primaryKey: String?
let onUpdate: String?
let onDelete: String?
}
Expand Down Expand Up @@ -365,7 +365,7 @@ extension ColumnDefinition.ForeignKey {
([
"REFERENCES",
table.quote(),
"(\(primaryKey.quote()))",
primaryKey.map { "(\($0.quote()))" },
onUpdate.map { "ON UPDATE \($0)" },
onDelete.map { "ON DELETE \($0)" }
] as [String?]).compactMap { $0 }
Expand Down
2 changes: 1 addition & 1 deletion Sources/SQLite/Schema/SchemaReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private enum ForeignKeyListTable {
static let seqColumn = Expression<Int64>("seq")
static let tableColumn = Expression<String>("table")
static let fromColumn = Expression<String>("from")
static let toColumn = Expression<String>("to")
static let toColumn = Expression<String?>("to") // when null, use primary key
static let onUpdateColumn = Expression<String>("on_update")
static let onDeleteColumn = Expression<String>("on_delete")
static let matchColumn = Expression<String>("match")
Expand Down
38 changes: 38 additions & 0 deletions Tests/SQLiteTests/Schema/SchemaReaderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,44 @@ class SchemaReaderTests: SQLiteTestCase {
])
}

func test_foreignKeys_references_column() throws {
let sql = """
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER REFERENCES artist(artistid)
);
"""
try db.execute(sql)
let trackColumns = try db.schema.foreignKeys(table: "track")
XCTAssertEqual(trackColumns.map { $0.toSQL() }.joined(separator: "\n"), """
REFERENCES "artist" ("artistid")
""")
}

func test_foreignKeys_references_null_column() throws {
let sql = """
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER REFERENCES artist
);
"""
try db.execute(sql)
let trackColumns = try db.schema.foreignKeys(table: "track")
XCTAssertEqual(trackColumns.map { $0.toSQL() }.joined(separator: "\n"), """
REFERENCES "artist"
""")
}

func test_tableDefinitions() throws {
let tables = try schemaReader.tableDefinitions()
XCTAssertEqual(tables.count, 1)
Expand Down