Additional
Overview
Features
Try
Discuss
News
Docu
FAQ
Testimonials
Requests
Partners
Firebird Associate
 
Data Access Engine PDF Print E-mail
Mar 13, 2010

AnyDAC for Delphi datasets TADQuery, TADMemTable, TADStoredProc, TADTable are built on the top of powerful ADO.NET-like data access engine for Delphi Win32. The lightweighted, effective and flexible engine API enables to use it directly in the applications and serves as a powerfull ground to the datasets API.

 

The engine consist of the dataset components and the non-component layers, represented by the flexible object oriented APIs. Many applications will benefit from the direct usage of these APIs.

DataSets

With the introduction of Delphi 1, the API of the Borland Database Engine (BDE) for data access components became the de facto standard for every data access library, and most data access libraries not only also copied its architecture, but also its limitations.

 

AnyDAC avoids this mistake, by introducing new very powerful methods, properties and features, while at the same time preserving the compatibility with standard TDataSet behavior. This power comes from the fact, that AnyDAC datasets are built on the top of the DatS and Phys layers.

 

All AnyDAC datasets, including the memory tables and queries, support the following features:

 

  • One of the fastest datasets around. 200-500% faster than TClientDataSet.
  • Compatibility with BDE TQuery, TStoredProc, TTable and TClientDataSet.
  • Expression filtering, using an Oracle-like expression syntax. With the ability to filter on calculated and aggregate fields.
  • Indexing and sorting including filtered indexes, online or offline indexes, expression indexes and more.
  • Search, Locate and Lookup with or without indexes, from the beginning of the dataset or from the current position, using classic field comparison or expression predicate evaluation.
  • Full range of data types supported, including high precision number, time stamps and intervals, blobs, XML, and nested datasets.
  • Data may be copied, merged, assigned or cloned across several datasets.
  • Aggregate fields, internal calculated fields, expression based calculated fields.
  • Data versioning and updates logging.
  • Data persistence, including support for XML and binary data formats.
  • Advanced master-detail with asynchronous detail refreshing and cascading updates.
  • Auto-incrementing fields with delayed updates support.

 

and much more …

 

For example, to filter a dataset by the substring value of a field, a programmer can use the OnFilterRecord event handler. AnyDAC support is similar to the Oracle expression syntax, allowing to you to write:

 

ADQuery1.Filter := 'upper(name) like ''DI%''';

 

As another example, one of the most annoying limitations of standard TDataSets is the restriction of the the Locate and Lookup methods to search only by field values. AnyDAC's LocateEx and LookupEx methods allow searching for records using more complex expressions:

 

if ADQuery1.LocateEx('upper(name) like ''DI%''', [lxoFromCurrent]) then //... 

Data Storage Engine

The following diagram shows a simplified object model of AnyDAC's in-memory Data Storage Engine (also called the DatS Layer):

 

AnyDAC DatS Layer

 

Main features include:

 

  • Powerful Object Model.
  • Powerful API enabling to build a storage from application code, populate and query it.
  • Multiple tables in single storage unit.
  • Nested and foreign key relationships between tables.
  • Constraints on tables, including foreign keys with cascading actions.
  • Support for multiple views on a single table.
  • Multiple options to filter and sort rows in a view.

 

To give you a feeling of what is actually DatS, we have provide the code sample:

uses 
  uADStanIntf, uADDatSManager;
...
var
  oCustTab: TADDatSTable;
  iId: Integer;
  oFoundRows: TADDatSView;
begin
  // 1) Create table
  oCustTab := TADDatSTable.Create('Customers');
  try
    oCustTab.Columns.Add('id', dtInt32);
    oCustTab.Columns.Add('name', dtAnsiString);
 
    // 2) Add ten rows and accept changes -> rsUnchanged
    for iId := 1 to 10 do
      oCustTab.Rows.Add([iId, Format('customer%d', [iId])]);
    oCustTab.AcceptChanges();
    // Add another ten rows               -> rsInserted
    for iId := 11 to 20 do
      oCustTab.Rows.Add([iId, Format('customer%d', [iId])]);
 
    // 3) Use the Select method to find all rows matching the filter.
    oFoundRows := oCustTab.Select('id > 5', 'name', [rsInserted]);
    try
      PrintRows(oFoundRows, Console.Lines, 'filtered rows');
    finally
      oFoundRows.Free;
    end;
 
    // 4) Use the Select method to find all rows in table.
    oFoundRows := oCustTab.DefaultView;
    try
      PrintRows(oFoundRows, Console.Lines, 'all rows');
    finally
      oFoundRows.Free;
    end;
 
  finally
    oCustTab.Free;
  end;

Data Access Engine

The following diagram shows a simplified look at AnyDAC's physical Data Access Engine (Phys Layer):

 

AnyDAC Phys Layer

 

Main features include:

 

  • Simple and effective object model.
  • COM interfaces instead of objects. No need for explicit freeing of objects.
  • No high-level components overhead.
  • Full integration with the in-memory storage engine.
  • Rich set of application callbacks to extend and adjust engine behavior.
  • DBMS specific personalized interfaces.

 

To give you a feeling of what is actually Phys, we have provide the code sample:

uses
  uADStanIntf, uADDatSManager,
  uADPhysIntf, uADPhysManager, uADPhysOracle;
...
var
  oConn: IADPhysConnection;
  oCmd:  IADPhysCommand;
  oTab:  TADDatSTable;
  I, J:  Integer;
begin
  // 1. open AnyDAC's ADPhysManager
  ADPhysManager.ConnectionDefs.Storage.FileName:= '$(ADHOME)\DB\ADConnectionDefs.ini';
  ADPhysManager.Open;
 
  // 2. open connection to Oracle database using AnyDAC connection string
  ADPhysManager.CreateConnection(
    'DriverID=Ora;Database=ORA_920_APP;User_Name=ADDemo;Password=a', 
    oConn);
  oConn.Open;
 
  // 3. create command and prepare SELECT statement
  oConn.CreateCommand(oCmd);
  oCmd.Prepare('select * from Emp');
 
  // 4. fetch rows from DB to DatS table
  oTab := TADDatSTable.Create;
  oCmd.Fetch(oTab);
 
  // 5. print rows
  mmLog.Clear;
  for I := 0 to oTab.Rows.Count1 do 
  begin
    s := ‘’;
    for J := 0 to oTab.Columns.Count1 do
      s := s + oTab.Rows[I].GetData(J) + ‘  ‘;
    mmLog.Add(s);
  end;
 
  // 6. free resources
  oTab.Free; 
end;