Skip to main content

On This Page

Trysil: A Lightweight Attribute-Driven ORM for Delphi Development

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Meet Trysil: a lightweight ORM for Delphi

Trysil is an open-source ORM designed to eliminate manual SQL boilerplate and dataset management in Delphi applications. It leverages RTTI and attributes to map plain Delphi classes to SQLite, PostgreSQL, SQL Server, and Firebird databases.

Why This Matters

Manual database interaction in Delphi traditionally requires writing SQL by hand, managing parameters, and looping through datasets to map fields to object properties, which is notoriously error-prone. Trysil addresses this by using an attribute-driven model that allows developers to define data structures once and automate the persistence layer, significantly reducing maintenance overhead and the risk of synchronization bugs between the application and database schema.

Key Insights

  • Trysil uses RTTI-based mapping via [TTable] and [TColumn] attributes, allowing developers to use strict private fields without inheriting from a base class.
  • Optimistic locking is enforced natively through the [TVersionColumn] attribute, which prevents lost updates by including the version ID in the WHERE clause of UPDATE statements.
  • Validation logic is integrated directly into the entity definition using specialized attributes such as [TRequired], [TMaxLength], and [TEmail].
  • The TTContext class serves as the single entry point for all ORM operations, abstracting the complexity of FireDAC connection pools and transaction management.
  • The compiler directive {$WARN UNKNOWN_CUSTOM_ATTRIBUTE ERROR} is used to convert typos in attribute names into compile-time errors, ensuring type safety in metadata.

Working Examples

Defining a Trysil entity with primary keys, required fields, and optimistic locking.

[TTable('Contacts')]
[TSequence('ContactsID')]
TTContact = class
strict private
  [TPrimaryKey] [TColumn('ID')] FID: TTPrimaryKey;
  [TRequired] [TMaxLength(50)] [TColumn('Firstname')] FFirstname: String;
  [TColumn('VersionID')] [TVersionColumn] FVersionID: TTVersion;
public
  property ID: TTPrimaryKey read FID;
  property Firstname: String read FFirstname write FFirstname;
  property VersionID: TTVersion read FVersionID;
end;

Performing Insert and Update operations using the TTContext.

LContact := LContext.CreateEntity<TTContact>();
LContact.Firstname := 'Ada';
LContext.Insert<TTContact>(LContact);

LContact.Email := '[email protected]';
LContext.Update<TTContact>(LContact);

Practical Applications

  • Use case: Desktop applications using SQLite for local storage can implement full CRUD logic with zero manual SQL strings. Pitfall: Neglecting to use CreateEntity for new objects leads to untracked states and failed insertions.
  • Use case: Multi-user database systems requiring concurrency control use the [TVersionColumn] to handle simultaneous updates. Pitfall: Forgetting to set the Search Path to the compiled output directory after manual installation prevents the project from finding Trysil units.

References:

Continue reading

Next article

Meta Superintelligence Lab Unveils Muse Spark: Natively Multimodal Model with Thought Compression

Related Content