Attributes¶
Complete reference of all Trysil attributes.
Entity Mapping¶
Unit: Trysil.Attributes
| Attribute | Target | Description |
|---|---|---|
TTable(name) |
Class | Maps class to database table |
TSequence(name) |
Class | Sequence for ID generation |
TPrimaryKey |
Field | Marks primary key field |
TColumn(name) |
Field | Maps field to database column |
TDetailColumn(fk, name) |
Field | Maps a detail/lookup column |
TVersionColumn |
Field | Enables optimistic locking |
TRelation(table, fk, cascade) |
Class | Declares child relationship |
TWhereClause(sql) |
Class | Adds fixed WHERE clause to all queries |
TWhereClauseParameter(name, value) |
Class | Parameter for TWhereClause |
TJoin(kind, table, ...) |
Class | Declares a JOIN for multi-table SELECT |
TColumn(alias, name) |
Field | Maps field to a joined table column (2-param overload) |
TCreatedAt |
Field | Timestamp set on insert (TTNullable<TDateTime>) |
TCreatedBy |
Field | User name set on insert (String) |
TUpdatedAt |
Field | Timestamp set on update (TTNullable<TDateTime>) |
TUpdatedBy |
Field | User name set on update (String) |
TDeletedAt |
Field | Timestamp set on delete — enables soft delete (TTNullable<TDateTime>) |
TDeletedBy |
Field | User name set on delete (String) |
TTable¶
Maps the entity class to a database table. Required on every entity.
TSequence¶
Names the database sequence used for ID generation. Behavior varies by database:
- SQL Server:
NEXT VALUE FOR [dbo].[PersonsID] - PostgreSQL:
nextval('PersonsID') - Firebird:
NEXT VALUE FOR PersonsID - SQLite:
AUTOINCREMENT(sequence name used as reference)
TPrimaryKey¶
Marks the primary key field. Must be TTPrimaryKey (Int32). One per entity.
TColumn¶
Maps a field to a database column by name. The field must be strict private.
A two-parameter overload maps a field to a column from a joined table:
The first parameter is the alias of the joined table (must match the alias from [TJoin]), the second is the column name. See JOIN Queries.
TDetailColumn¶
Maps a read-only column from a related table. First parameter is the foreign key column, second is the detail column name.
TVersionColumn¶
Enables optimistic locking. The version is incremented on each update. If another transaction has modified the record (version mismatch), ETConcurrentUpdateException is raised.
TRelation¶
Parameters:
- Child table name — the table that references this entity
- Foreign key column — the column in the child table
- Cascade delete —
True: auto-delete children;False: block delete if children exist (raisesETDataIntegrityException)
Multiple TRelation attributes can be applied to the same class.
TWhereClause / TWhereClauseParameter¶
[TTable('Users')]
[TWhereClause('Active = :Active AND Role = :Role')]
[TWhereClauseParameter('Active', True)]
[TWhereClauseParameter('Role', 'admin')]
TActiveAdmin = class
Adds a fixed WHERE clause to every query on this entity. Parameters are compile-time constants only. For dynamic filtering, use TTFilterBuilder<T>.
TWhereClauseParameter constructors accept: String, Integer, Int64, Double, Boolean, TDateTime.
TJoin¶
Declares a JOIN for multi-table SELECT queries. Three overloads:
Simple JOIN -- join using FROM table columns:
Parameters: JoinKind, TableName, SourceColumnName, TargetColumnName.
Self-JOIN with alias -- required when joining the same table multiple times:
Parameters: JoinKind, TableName, Alias, SourceColumnName, TargetColumnName.
Chained JOIN -- join using a column from a previous join:
Parameters: JoinKind, TableName, Alias, SourceTableOrAlias, SourceColumnName, TargetColumnName.
TJoinKind is a scoped enum: Inner, Left, Right.
Join entities are read-only: Insert, Update, and Delete raise ETException. The identity map is bypassed for join entities. See JOIN Queries for full documentation.
Change Tracking Attributes¶
[TCreatedAt]
[TColumn('CreatedAt')]
FCreatedAt: TTNullable<TDateTime>;
[TCreatedBy]
[TColumn('CreatedBy')]
FCreatedBy: String;
[TUpdatedAt]
[TColumn('UpdatedAt')]
FUpdatedAt: TTNullable<TDateTime>;
[TUpdatedBy]
[TColumn('UpdatedBy')]
FUpdatedBy: String;
[TDeletedAt]
[TColumn('DeletedAt')]
FDeletedAt: TTNullable<TDateTime>;
[TDeletedBy]
[TColumn('DeletedBy')]
FDeletedBy: String;
The resolver automatically populates these fields:
TCreatedAt/TCreatedBy— set duringInsertwithNowand the value fromTTContext.OnGetCurrentUser.TUpdatedAt/TUpdatedBy— set duringUpdate.TDeletedAt/TDeletedBy— set duringDelete. WhenTDeletedAtis present, delete becomes a soft delete (UPDATE instead of DELETE). All SELECT queries automatically addDeletedAt IS NULLto exclude soft-deleted records.
Type constraints:
*Atfields must beTTNullable<TDateTime>— validated at mapping time.*Byfields must beString— validated at mapping time.- Duplicate attributes of the same kind on the same entity raise
ETException.
See Entity Mapping — Change Tracking for a full example.
Validation¶
Unit: Trysil.Validation.Attributes
| Attribute | Description | Signature |
|---|---|---|
TRequired |
Not empty, null, or zero | Create or Create(errorMsg) |
TMaxLength(n) |
Maximum string length | Create(length) or Create(length, errorMsg) |
TMinLength(n) |
Minimum string length | Create(length) or Create(length, errorMsg) |
TMaxValue(n) |
Maximum numeric value | Create(Integer\|Double) or with errorMsg |
TMinValue(n) |
Minimum numeric value | Create(Integer\|Double) or with errorMsg |
TGreater(n) |
Greater than n | Create(Integer\|Double) or with errorMsg |
TLess(n) |
Less than n | Create(Integer\|Double) or with errorMsg |
TRange(min, max) |
Value in range | Create(min, max) or with errorMsg |
TRegex(pattern) |
Matches regex pattern | Create(regex) or Create(regex, errorMsg) |
TEmail |
Valid email format | Create or Create(errorMsg) |
TDisplayName(name) |
Human-readable field name for errors | Create(displayName) |
TValidator |
Marks custom validator method | Marker attribute |
Examples¶
[TRequired]
[TMaxLength(50)]
[TColumn('Firstname')]
FFirstname: String;
[TMinValue(0)]
[TMaxValue(100)]
[TColumn('Score')]
FScore: Integer;
[TEmail('Please enter a valid email')]
[TColumn('Email')]
FEmail: String;
[TRange(1, 999)]
[TDisplayName('Order Number')]
[TColumn('OrderNo')]
FOrderNo: Integer;
[TRegex('^\+?[0-9\s\-]+$', 'Invalid phone number')]
[TColumn('Phone')]
FPhone: String;
All validation attributes optionally accept a custom error message as the last parameter. If omitted, a default message is generated using the TDisplayName (if present) or the column name.
Events¶
Unit: Trysil.Events.Attributes
Class-Level Event Attributes¶
Register an event class for an entity:
| Attribute | Description |
|---|---|
TInsertEvent(eventClass) |
Event class for insert operations |
TUpdateEvent(eventClass) |
Event class for update operations |
TDeleteEvent(eventClass) |
Event class for delete operations |
[TInsertEvent(TPersonInsertEvent)]
[TUpdateEvent(TPersonUpdateEvent)]
[TDeleteEvent(TPersonDeleteEvent)]
TPerson = class
Method-Level Event Attributes¶
Declare event methods directly on the entity:
| Attribute | Description |
|---|---|
TBeforeInsert |
Method called before insert |
TAfterInsert |
Method called after insert |
TBeforeUpdate |
Method called before update |
TAfterUpdate |
Method called after update |
TBeforeDelete |
Method called before delete |
TAfterDelete |
Method called after delete |
TPerson = class
strict private
[TBeforeInsert]
procedure OnBeforeInsert;
[TAfterUpdate]
procedure OnAfterUpdate;
end;
See Events for detailed usage.
JSON¶
Unit: Trysil.JSon.Attributes
| Attribute | Description |
|---|---|
TJSonIgnore |
Exclude field from JSON serialization/deserialization |
See JSON Module for serialization documentation.
HTTP¶
Unit: Trysil.Http.Attributes
Routing¶
| Attribute | Description |
|---|---|
TUri(path) |
Controller base URI |
TGet / TGet(path) |
GET endpoint |
TPost / TPost(path) |
POST endpoint |
TPut / TPut(path) |
PUT endpoint |
TDelete / TDelete(path) |
DELETE endpoint |
URL parameters use ? as placeholder:
[TUri('/api/persons')]
TPersonController = class(TTHttpController<TAPIContext>)
public
[TGet] // GET /api/persons
procedure GetAll;
[TGet('/?')] // GET /api/persons/123
procedure GetById(const AID: TTPrimaryKey);
[TPost] // POST /api/persons
procedure Insert;
[TPut] // PUT /api/persons
procedure Update;
[TDelete('/?/?')] // DELETE /api/persons/123/1
procedure Delete(const AID: TTPrimaryKey; const AVersionID: TTVersion);
end;
Authentication & Authorization¶
| Attribute | Description |
|---|---|
TAuthorizationType(type) |
Authentication requirement for controller |
TArea(name) |
Required authorization area for method |
// No authentication required
[TAuthorizationType(TTHttpAuthorizationType.None)]
TLogonController = class(TTHttpController<TAPIContext>)
// Require 'admin' area
[TGet]
[TArea('admin')]
procedure GetSettings;
TTHttpAuthorizationType values:
None— no authentication requiredAuthentication— authentication required (default)
See HTTP Module for full documentation.