Blog

All Blog Posts  |  Next Post  |  Previous Post

Increased RAD level for ORM development with TMS Aurelius

Thursday, September 12, 2019

The new released version 4.8 of TMS Aurelius, brings RAD with ORM to a new level!

"Photo by AbsolutVision on Unsplash"

New design-time components

There are now three new components available for design-time: TAureliusManager, TAureliusDBSchema and TAureliusModelEvents.

They are just wrappers around existing classes, but they make it even easier to getting started with Aurelius. Here is how you can start using Aurelius with SQLite for example.

Drop the components on the form

First step is simply to drop TAureliusConnection, TAureliusDBSchema and TAureliusManager components on the form. This will also automatically add extra needed units to the uses clause.

Aurelius design-time components

Configure the database connection

You can then double click AureliusConnection1 component to configure your database connection. It brings the dialog below (if you are going to use a 3rd-party component to access the database, like FireDAC for example, just drop a TFDConnection in the form before double-clicking the TAureliusConnection):

Aurelius connection configuration

You can then properly configure the connection. In the example above, we will use native SQLite and simply inform the name of the database file, in this case test.db (if using 3rd party like FireDAC, just choose the Adapter Mode and associate with the TFDConnection component).

Associate other components with the connection

Both TAureliusManager and TAureliusDBSchema components provide functionality that deals with the database. We need to specify which database we are going to use.

Both components have a Connection property that you use to associate to a TAureliusConnection component. That is as simple as that, just open the object inspector and associate the AureliusConnection1 component to boht AureliusDBSchema1 and AureliusManager1 components.

TAureliusDBSchema inspector

TAureliusManager inspector

Write your entities

This is the same as it ever was. We are working with an ORM which means we need entity classes, of course. Let's create in our project a new unit named Entities and add a very simple class entity to it.

Here is the unit full source code. Don't forget that if you have an existing database, you can always automaticaly generate the entities from the existing database structure.

unit Entities;

interface
uses Aurelius.Mapping.Attributes;

type
  [Entity, Automapping]
  TCustomer = class
  strict private
    FId: Integer;
    FName: string;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
  end;

implementation

initialization
  RegisterEntity(TCustomer);
end.

Update database structure

Our SQLite database doesn't exist and will be created automatically when we run our application. But there will be no tables in it. That is not a problem for Aurelius, which can create all the needed structure for us.

With the new TAureliusDBSchema component we dropped on the form, it gets even easier. All we have to do is call method UpdateDatabase. We can do it from the OnCreate event of the form so our database automatically gets all tables and fields it needs when the application is started:

procedure TForm4.FormCreate(Sender: TObject);
begin
  AureliusDBSchema1.UpdateDatabase;
end;

All set: Use the manager!

That is it. We have our database ready, we have the manager component in the form, we can simply start using Aurelius right away. For example, we can drop a TButton component and a TEdit component on the form and add the following code to create a new customer:

procedure TForm4.Button1Click(Sender: TObject);
var
  Customer: TCustomer;
begin
  Customer := TCustomer.Create;
  Customer.Name := Edit1.Text;
  AureliusManager1.Save(Customer);
end;

Ready-to-use features

TMS Aurelius source code is very modular and each functionality is in a different unit. That means that usually you need to keep adding the specific unit you need to the uses clause. The nice thing about using Aurelius design-time components is that they add the needed units for you.

For example, you can start writing queries right away, without the need to manually add Aurelius.Criteria.Base or Aurelius.Criteria.Linq units to the uses clause.

Actually, even from code you don't need to do that anymore. You can now just use a single Aurelius.Linq unit which holds everything you need. But that is not even needed when using TAureliusManager component. Just write the queries you want:

procedure TForm4.Button2Click(Sender: TObject);
begin
  ShowMessage(
    'First customer starting with "W" is: ' +
    AureliusManager1.Find<TCustomer>
      .Where(Linq['Name'].StartsWith('W'))
      .OrderBy('Name')
      .Take(1)
      .UniqueResult
      .Name);
end;

Using events with TAureliusModelEvents

Handling events in TMS Aurelius is now easier than ever thanks to the TAureliusModelEvents component.

For example, if you want to intercept and log all SQL statements executed, just drop the component in the form:

TAureliusModelEvents component

Then create an event handler for the OnSqlExecuting event.

TAureliusModelEvents.OnSqlExecuting

Then simply add the following event handler code, drop a TMemo in the form, and you have a logger of the executed SQL statements in a few seconds!

procedure TForm4.AureliusModelEvents1SQLExecuting(Sender: TObject;
  Args: TSQLExecutingArgs);
begin
  Memo1.Lines.Add(Args.SQL);
end;

New Where Attribute

Design-time components are not the only new feature in latest TMS Aurelius. A nice addition is the Where attribute. You can now use it to add additional filtering to your entities or many-valued associations (lists).

This is very handy to implement soft deletes for example (flag entities that have been deleted without actually deleting them).

Here is how you would use it:

  [Entity, Automapping]
  [Where('{Deleted} <> ''T''')]
  TCustomer = class
  private
    FId: integer;
    FName: string;

Whenever you try to retrieve customers, those which Deleted field in database contains T will not be retrieved. You can also use the clause in many-valued associations:

private
  [ManyValuedAssociation([], CascadeTypeAll)]
  [Where('{Status} = ''New''')]
  FNewCustomers: TList<TCustomer>;

It's interesting to note that the Where clause above of the TCustomer entity will still apply, meaning the NewCustomers list will only bring customers which Status field are equal to New and Deleted field different than T.

Expanding blobs in TMS XData

There are updates in other products of TMS Business product line as well. TMS XData got a nice addition: the $expand query option now also expands blobs inlined the returned JSON.

Usually if you request a resource from the server that contains a blob property, it will come as a proxy reference to minimize traffic. For example, a request to a customer that contains a Photo property:

http://myserver/tms/xdata/Customer/6/

Might bring something like this (extra info removed):

{
  "Id": 1,
  "Name": "Wilbur",
  "Photo@xdata.proxy": "Customer(6)/Photo"
}

But with the $expand clause you can now ask the Photo property to come inline in JSON as base64 string:

http://myserver/tms/xdata/Customer/6/?$expand=Photo

The request above will bring a response like this (base64 string value is not a real photo of course):

{
  "Id": 1,
  "Name": "Wilbur",
  "Photo": "T0RhdGE"
}

This is also valid for retriving entity lists as well.

TMS RemoteDB performance improvements

Last but not least in this great TMS Business update, TMS RemoteDB got its performence improved, especially in the situations where queries have lots of parameters, or return a significant amount of data.

Get in touch

Don't forget to subscribe to our channels to receive updated information as soon as it's released! Subscribe to our Youtube channel, and also subscribe to our newsletter to receive news via e-mail.

Have you enjoyed this update as much as I did? Leave your comment below and let us know!



Wagner Landgraf




This blog post has received 2 comments.


1. Friday, September 13, 2019 at 5:36:26 PM

Simply Brilliant!
You are doing a wonderful job guys... Thank you so much.

WIERZBICKI Stéphane


2. Friday, September 13, 2019 at 7:16:24 PM

Thank you for the kind words, Stéphane!

Wagner R. Landgraf




Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post