Skip to content

Commit abb5084

Browse files
authored
Refactor temporary trigger touch APIs to be more flexible. (#202)
* Temporary trigger improvements The "touch" helpers have been moved from statics on the table type to statics on the operation type so that additional customization (like `on` and `when`) can be surfaced. * wip * wip * wip
1 parent 9bbfc44 commit abb5084

File tree

4 files changed

+284
-192
lines changed

4 files changed

+284
-192
lines changed

Sources/StructuredQueriesSQLiteCore/Documentation.docc/Articles/Triggers.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ refreshed with the current time immediately.
4545

4646
This pattern of updating a timestamp when a row changes is so common that the library comes with
4747
a specialized tool just for that kind of trigger,
48-
``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterUpdateTouch:fileID:line:column:)``:
48+
``TemporaryTrigger/Operation/update(touch:when:)``:
4949

5050
@Row {
5151
@Column {
5252
```swift
5353
Reminder.createTemporaryTrigger(
54-
afterUpdateTouch: {
54+
after: .update: {
5555
$0.updatedAt = datetime('subsec')
5656
}
5757
)
@@ -72,14 +72,14 @@ a specialized tool just for that kind of trigger,
7272

7373
And further, the pattern of specifically updating a _timestamp_ column is so common that the library
7474
comes with another specialized too just for that kind of trigger,
75-
``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterUpdateTouch:fileID:line:column:)``:
75+
``TemporaryTrigger/Operation/update(touch:when:)``:
7676

7777

7878
@Row {
7979
@Column {
8080
```swift
8181
Reminder.createTemporaryTrigger(
82-
afterUpdateTouch: \.updatedAt
82+
after: .update(touch: \.updatedAt)
8383
)
8484
```
8585
}
@@ -195,11 +195,11 @@ reminder is inserted into the database with the following trigger:
195195
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:before:fileID:line:column:)``
196196
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:insteadOf:fileID:line:column:)``
197197

198-
### Touching records
199-
200-
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterInsertTouch:fileID:line:column:)``
201-
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterUpdateTouch:fileID:line:column:)``
202-
203198
### Triggers
204199

205200
- ``TemporaryTrigger``
201+
202+
### Deprecations
203+
204+
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterInsertTouch:fileID:line:column:)``
205+
- ``StructuredQueriesCore/Table/createTemporaryTrigger(_:ifNotExists:afterUpdateTouch:fileID:line:column:)``

Sources/StructuredQueriesSQLiteCore/Internal/Deprecations.swift

Lines changed: 129 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,123 @@
11
import Foundation
22
import StructuredQueriesCore
33

4+
// NB: Deprecated after 0.22.2:
5+
6+
extension Table {
7+
@available(
8+
*,
9+
deprecated,
10+
message: "Prefer 'createTemporaryTrigger(after: .update(touch:))', instead"
11+
)
12+
public static func createTemporaryTrigger(
13+
_ name: String? = nil,
14+
ifNotExists: Bool = false,
15+
afterUpdateTouch updates: (inout Updates<Self>) -> Void,
16+
fileID: StaticString = #fileID,
17+
line: UInt = #line,
18+
column: UInt = #column
19+
) -> TemporaryTrigger<Self> {
20+
Self.createTemporaryTrigger(
21+
name,
22+
ifNotExists: ifNotExists,
23+
after: .update { _, new in
24+
Self
25+
.where { $0.rowid.eq(new.rowid) }
26+
.update { updates(&$0) }
27+
},
28+
fileID: fileID,
29+
line: line,
30+
column: column
31+
)
32+
}
33+
34+
@available(
35+
*,
36+
deprecated,
37+
message: "Prefer 'createTemporaryTrigger(after: .update(touch:))', instead"
38+
)
39+
public static func createTemporaryTrigger<D: _OptionalPromotable<Date?>>(
40+
_ name: String? = nil,
41+
ifNotExists: Bool = false,
42+
afterUpdateTouch dateColumn: KeyPath<TableColumns, TableColumn<Self, D>>,
43+
date dateFunction: any QueryExpression<D> = SQLQueryExpression<D>("datetime('subsec')"),
44+
fileID: StaticString = #fileID,
45+
line: UInt = #line,
46+
column: UInt = #column
47+
) -> TemporaryTrigger<Self> {
48+
Self.createTemporaryTrigger(
49+
name,
50+
ifNotExists: ifNotExists,
51+
afterUpdateTouch: {
52+
$0[dynamicMember: dateColumn] = dateFunction
53+
},
54+
fileID: fileID,
55+
line: line,
56+
column: column
57+
)
58+
}
59+
60+
@available(
61+
*,
62+
deprecated,
63+
message: "Prefer 'createTemporaryTrigger(after: .insert(touch:))', instead"
64+
)
65+
public static func createTemporaryTrigger(
66+
_ name: String? = nil,
67+
ifNotExists: Bool = false,
68+
afterInsertTouch updates: (inout Updates<Self>) -> Void,
69+
fileID: StaticString = #fileID,
70+
line: UInt = #line,
71+
column: UInt = #column
72+
) -> TemporaryTrigger<Self> {
73+
Self.createTemporaryTrigger(
74+
name,
75+
ifNotExists: ifNotExists,
76+
after: .insert { new in
77+
Self
78+
.where { $0.rowid.eq(new.rowid) }
79+
.update { updates(&$0) }
80+
},
81+
fileID: fileID,
82+
line: line,
83+
column: column
84+
)
85+
}
86+
87+
@available(
88+
*,
89+
deprecated,
90+
message: "Prefer 'createTemporaryTrigger(after: .insert(touch:))', instead"
91+
)
92+
public static func createTemporaryTrigger<D: _OptionalPromotable<Date?>>(
93+
_ name: String? = nil,
94+
ifNotExists: Bool = false,
95+
afterInsertTouch dateColumn: KeyPath<TableColumns, TableColumn<Self, D>>,
96+
date dateFunction: any QueryExpression<D> = SQLQueryExpression<D>("datetime('subsec')"),
97+
fileID: StaticString = #fileID,
98+
line: UInt = #line,
99+
column: UInt = #column
100+
) -> TemporaryTrigger<Self> {
101+
Self.createTemporaryTrigger(
102+
name,
103+
ifNotExists: ifNotExists,
104+
afterInsertTouch: {
105+
$0[dynamicMember: dateColumn] = dateFunction
106+
},
107+
fileID: fileID,
108+
line: line,
109+
column: column
110+
)
111+
}
112+
}
113+
4114
// NB: Deprecated after 0.5.1:
5115

6116
extension Table {
7117
@available(
8-
*, deprecated, message: "Use a trailing closure, instead: 'Table.insert { row }'"
118+
*,
119+
deprecated,
120+
message: "Use a trailing closure, instead: 'Table.insert { row }'"
9121
)
10122
public static func insert(
11123
or conflictResolution: ConflictResolution,
@@ -16,7 +128,9 @@ extension Table {
16128
}
17129

18130
@available(
19-
*, deprecated, message: "Use a trailing closure, instead: 'Table.insert { rows }'"
131+
*,
132+
deprecated,
133+
message: "Use a trailing closure, instead: 'Table.insert { rows }'"
20134
)
21135
public static func insert(
22136
or conflictResolution: ConflictResolution,
@@ -49,7 +163,10 @@ extension Table {
49163

50164
@available(*, deprecated, renamed: "insert(or:_:select:onConflictDoUpdate:)")
51165
public static func insert<
52-
V1, each V2, From, Joins
166+
V1,
167+
each V2,
168+
From,
169+
Joins
53170
>(
54171
or conflictResolution: ConflictResolution,
55172
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
@@ -62,7 +179,9 @@ extension Table {
62179

63180
extension PrimaryKeyedTable {
64181
@available(
65-
*, deprecated, message: "Use a trailing closure, instead: 'Table.insert { draft }'"
182+
*,
183+
deprecated,
184+
message: "Use a trailing closure, instead: 'Table.insert { draft }'"
66185
)
67186
public static func insert(
68187
or conflictResolution: ConflictResolution,
@@ -73,7 +192,9 @@ extension PrimaryKeyedTable {
73192
}
74193

75194
@available(
76-
*, deprecated, message: "Use a trailing closure, instead: 'Table.insert { drafts }'"
195+
*,
196+
deprecated,
197+
message: "Use a trailing closure, instead: 'Table.insert { drafts }'"
77198
)
78199
public static func insert(
79200
or conflictResolution: ConflictResolution,
@@ -84,7 +205,9 @@ extension PrimaryKeyedTable {
84205
}
85206

86207
@available(
87-
*, deprecated, message: "Use a trailing closure, instead: 'Table.upsert { draft }'"
208+
*,
209+
deprecated,
210+
message: "Use a trailing closure, instead: 'Table.upsert { draft }'"
88211
)
89212
public static func upsert(
90213
or conflictResolution: ConflictResolution,

0 commit comments

Comments
 (0)