Replies: 2 comments 1 reply
-
|
This is my current solution but it doesn't feel great. private func installCascadeTriggers<Parent: Table, Child: Table>(
on _: Parent.Type,
touch parentColumn: String,
for _: Child.Type,
via foreignKey: String,
on db: Database
) throws {
let updateSQL = """
UPDATE "\(Parent.tableName)" SET "\(parentColumn)" = datetime('subsec')
WHERE "id" = NEW."\(foreignKey)"
"""
let deleteSQL = """
UPDATE "\(Parent.tableName)" SET "\(parentColumn)" = datetime('subsec')
WHERE "id" = OLD."\(foreignKey)"
"""
try Child.createTemporaryTrigger(after: .insert { _ in #sql("\(raw: updateSQL)") }).execute(db)
try Child.createTemporaryTrigger(after: .update { _, _ in #sql("\(raw: updateSQL)") }).execute(db)
try Child.createTemporaryTrigger(after: .delete { _ in #sql("\(raw: deleteSQL)") }).execute(db)
}
// Usage:
try installCascadeTriggers(on: Note.self, touch: "updatedAt", for: Comment.self, via: "noteID", on: db)
try installCascadeTriggers(on: Note.self, touch: "updatedAt", for: Attachment.self, via: "noteID", on: db)
try installCascadeTriggers(on: Note.self, touch: "updatedAt", for: Tag.self, via: "noteID", on: db) |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
@Rspoon3 Thanks for sharing the problem and your solution to it! One thing you could do to make things a lil safer is to use the extension PrimaryKeyedTable {
static func installCascadeTriggers<Child: Table>(
touch parentColumn: TableColumn<Self, Date>,
for _: Child.Type,
via foreignKey: TableColumn<Child, PrimaryKey>,
on db: Database
) throws {
// ...
}
// Usage:
try Note.installCascadeTriggers(touch: \.updatedAt, for: Comment.self, via: \.noteID, on: db)We generally like to keep core library surface area lean, but this tool could be incubated as a third party library if you are so inclined! We could link to it from the README. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
It would be nice if the library had a first-class way to express parent
updatedAtcascading from child tables. Something like:The
on:parameter takes a set of events, so callers can choose which child operations cascade. For example,on: [.insert, .delete]would skip update cascading if only structural changes matter.Or perhaps leveraging the existing foreign key metadata that the
SyncEnginealready inspects:This pattern (touch parent timestamp when child records change) is common enough that a built-in API could save significant boilerplate.
Beta Was this translation helpful? Give feedback.
All reactions