AE ORM is a static, generative ORM framework. It uses no iterfaces, no RTTI, no compiler magic, no assembly; only the good old and battle-tested Pascal code. Hard to read through, easy to understand. This is a very first attempt at a poor-mans-ORM. It might not generate objects correctly or straight up produce uncompilable code. It worked on my machine, though.
It comes with a class to generate the Pascal code for your objects and a connection pool to make sure those objects will be able to talk to your RDBMS.
The ORM system is using Zeos database access components, the Generator (it's settings to be precise) is using AEFramework.
DB discovery usage:
Var
conn: TZConnection;
discovery: TAEORMDBDiscovery;
settings: TAEORMEntityGeneratorSettings;
Begin
[...]
settings := TAEORMEntityGeneratorSettings.Create;
Try
discovery := TAEORMDBDiscovery.Create;
Try
discovery.SQLConnection := conn;
discovery.Settings := settings;
// Automatically discover all tables, fields and relations in the database:
discovery.DiscoverAll;
// Discover tables, fields or relations only:
// discovery.DiscoverTables; discovery.DiscoverFields; discovery.DiscoverRelations;
Finally
FreeAndNil(discovery);
End;
[...]
Finally
FreeAndNil(settings);
End;
Generator usage:
Var
gen: TAEORMEntityGenerator;
settings: TAEORMEntityGeneratorSettings;
Begin
[...]
settings := TAEORMEntityGeneratorSettings.Create;
Try
// Load by settings.AsString or use TAEORMDBDiscovery to have some values
// You also can manually define the structure with
// settings.Table['MyTable'].Field['MyField'].PropertyType := oftInteger;
gen := TAEORMEntityGenerator.Create;
Try
TFile.WriteAllText('.\AE.ORM.CustomEntities.pas', gen.Generate('AE.ORM.CustomEntities'));
Finally
FreeAndNil(gen);
End;
Finally
FreeAndNil(settings);
End;
Ad-hoc entity collection:
Var
table: TMyTable1;
collection: TAEORMEntityCollection<TMyTable1>;
Begin
collection := TAEORMEntityCollection<TMyTable1>.Create(connpool);
Try
collection.Load('1=1');
For table In collection Do
// Do something...
Finally
FreeAndNil(collection);
End;
End;
Single entity:
Var
table: TMyTable1;
Begin
table := TMyTable1.Create;
Try
table.LoadByID(999); // Might need multiple parameters with different types depending on the primary ID
table.MyField := 'Hello, world!';
table.Save;
Finally
FreeAndNil(table);
End;
End;
Contains TAEORMDBConnectionPool, which just collects and hands out TZConnection objects to anyone who asks for one. These connections are always active and can be used with no delay after acquiring one.
Contains EAEORMException, EAEORMDBConnectionPoolException and EAEORMEntityException.
Normally you won't need to touch anything in here. These files are the skeletons of the ORM objects the generator will generate.
This file implements TAEORMEntityCollection<T: TAEORMEntity> and it's TAEORMEntityCollectionEnumerator enumerator class. An entity collection is a collection of entities (who would have thought, right?) which can be ad-hoc or a one-to-more relation.
TAEORMCommonEntity is the base which is used by entity and entity collection objects alike.
TAEORMFieldValueList is a helper object, created only to extend a TDictionary<String, TZVariant> with encoding a simple type to a TZVariant. It is being used by generated entities to collect primary key and modified field names and their values.
TAEORMEntityHelper does basically the opposite of TAEORMFieldValueList. It reads out a specific value from a resultset to a simple type. Used by generated entities.
TAEORMEntity is the skeleton of a single ORM object, a record in the database.
This folder contains the classes needed to generate the ORM objects based on your input or discovery.
TAEORMEntityGenerator is responsible for crawling through a database, discovering and importing tables, their fields and relations to the TAEORMEntityGeneratorSettings structure. If the settings are filled manually or loaded via the .AsString property it's not always needed.
TAEORMEntityBase, TAEORMEntityGeneratorField, TAEORMEntityGeneratorRelation and TAEORMEntityGeneratorTable are all used by the settings of the generator class. They contain the information from which the source file will be generated, take care of JSON (de)serialization and contain some helper methods to make lookup or data insertation easier.
TAEORMEntityGenerator is the brains of the operation. It's role is to create the Pascal source for the tables, fields and relations currently in the provided TAEORMEntityGeneratorSettings structure.
TAEORMEntityGeneratorSettings is the full datastore for the generator object. State can be imported or exported via JSON.