You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,15 @@
2
2
3
3
Notable changes to Trysil, in reverse chronological order.
4
4
5
+
## Change Tracking & Soft Delete
6
+
7
+
-**Change tracking attributes**: `[TCreatedAt]`, `[TCreatedBy]`, `[TUpdatedAt]`, `[TUpdatedBy]`, `[TDeletedAt]`, `[TDeletedBy]` — automatic timestamps and user tracking on insert, update, and delete
8
+
-**Soft delete**: entities with `[TDeletedAt]` use UPDATE instead of DELETE; all SELECT queries automatically exclude soft-deleted records (`DeletedAt IS NULL`)
9
+
-**`IncludeDeleted`**: option on `TTFilter` and `TTFilterBuilder<T>` to include soft-deleted records in queries
10
+
-**`OnGetCurrentUser`**: callback property on `TTContext` to provide the current user name for `*By` fields
11
+
-**`TTChangeTrackingMap`**: mapping infrastructure for change tracking columns
12
+
-**`TTSoftDeleteSyntax`**: SQL syntax class for soft delete UPDATE statements
13
+
5
14
## Recent
6
15
7
16
-**Docs**: MkDocs Material documentation site, cookbook, demo READMEs
The resolver automatically populates these fields:
146
+
147
+
-**`TCreatedAt` / `TCreatedBy`** — set during `Insert` with `Now` and the value from `TTContext.OnGetCurrentUser`.
148
+
-**`TUpdatedAt` / `TUpdatedBy`** — set during `Update`.
149
+
-**`TDeletedAt` / `TDeletedBy`** — set during `Delete`. When `TDeletedAt` is present, delete becomes a **soft delete** (UPDATE instead of DELETE). All SELECT queries automatically add `DeletedAt IS NULL` to exclude soft-deleted records.
150
+
151
+
Type constraints:
152
+
153
+
-`*At` fields must be `TTNullable<TDateTime>` — validated at mapping time.
154
+
-`*By` fields must be `String` — validated at mapping time.
155
+
- Duplicate attributes of the same kind on the same entity raise `ETException`.
156
+
157
+
See [Entity Mapping — Change Tracking](../guide/entities.md#change-tracking) for a full example.
If the entity has a `[TDeletedAt]` column, `Delete` performs a **soft delete** (UPDATE) instead of a SQL DELETE. See [Entity Mapping — Soft Delete](entities.md#soft-delete) for details.
145
+
144
146
### DeleteAll
145
147
146
148
```pascal
@@ -258,6 +260,21 @@ Validation also runs automatically before every `Insert` and `Update` operation
258
260
|`InTransaction`|`Boolean`| Whether the write connection has an active transaction |
259
261
|`SupportTransaction`|`Boolean`| Whether the write connection supports transactions |
260
262
|`UseIdentityMap`|`Boolean`| Whether the identity map is enabled for this context |
263
+
|`OnGetCurrentUser`|`TFunc<String>`| Callback that returns the current user name for change tracking `*By` fields |
264
+
265
+
### OnGetCurrentUser
266
+
267
+
Assign this property to provide the current user name for change tracking attributes (`[TCreatedBy]`, `[TUpdatedBy]`, `[TDeletedBy]`):
268
+
269
+
```pascal
270
+
LContext.OnGetCurrentUser :=
271
+
function: String
272
+
begin
273
+
Result := GetCurrentUserName;
274
+
end;
275
+
```
276
+
277
+
If not assigned, an empty string is written to `*By` fields. See [Entity Mapping — Change Tracking](entities.md#change-tracking) for details.
- For dynamic, runtime-constructed filters, use [TTFilterBuilder\<T\>](filtering.md) instead.
104
104
105
+
## Change Tracking
106
+
107
+
Trysil can automatically set timestamp and user-name fields when entities are inserted, updated, or soft-deleted. Decorate columns with the change tracking attributes:
- The resolver automatically populates `*At` fields with `Now` and `*By` fields with the value returned by `TTContext.OnGetCurrentUser` (empty string if not assigned).
166
+
-`[TCreatedAt]` / `[TCreatedBy]` are set during `Insert`.
167
+
-`[TUpdatedAt]` / `[TUpdatedBy]` are set during `Update`.
168
+
-`[TDeletedAt]` / `[TDeletedBy]` are set during `Delete`.
169
+
170
+
### Soft Delete
171
+
172
+
When an entity has a `[TDeletedAt]` column, calling `Delete<T>` does **not** execute a SQL `DELETE`. Instead, it executes an `UPDATE` that sets the `DeletedAt` (and optionally `DeletedBy`) column and increments `[TVersionColumn]` if present. Relation checks (`TRelation`) are skipped for soft deletes.
173
+
174
+
All SELECT queries automatically add `DeletedAt IS NULL` to the WHERE clause, so soft-deleted records are excluded by default. To include them, use `TTFilter.IncludeDeleted` or `TTFilterBuilder<T>.IncludeDeleted` — see [Filtering](filtering.md#including-soft-deleted-records).
175
+
176
+
### Providing the Current User
177
+
178
+
Set `OnGetCurrentUser` on the context to supply the user name for `*By` fields:
179
+
180
+
```pascal
181
+
LContext := TTContext.Create(LConnection);
182
+
LContext.OnGetCurrentUser :=
183
+
function: String
184
+
begin
185
+
Result := GetCurrentUserName; // your application logic
186
+
end;
187
+
```
188
+
189
+
If `OnGetCurrentUser` is not assigned, an empty string is written to `*By` fields.
190
+
105
191
## RTTI Warning
106
192
107
193
Always add this compiler directive at the top of units that define entities with Trysil attributes:
Copy file name to clipboardExpand all lines: Docs/guide/filtering.md
+26Lines changed: 26 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -122,6 +122,32 @@ LBuilder
122
122
123
123
Only one `OrderBy` call is active at a time. Calling `OrderByAsc` or `OrderByDesc` replaces any previous ordering.
124
124
125
+
## Including Soft-Deleted Records
126
+
127
+
When an entity has a `[TDeletedAt]` column, all queries automatically exclude soft-deleted records by adding `DeletedAt IS NULL` to the WHERE clause. To include them:
128
+
129
+
### Via TTFilterBuilder
130
+
131
+
```pascal
132
+
var LFilter := LContext.CreateFilterBuilder<TArticle>()
0 commit comments