FireDAC - z praxe 3

vložil Radek Červinka 20. května 2013 00:43

V dalším díle nepravidelného občasníku o FireDac si povíme něco o konverzi z BDE a ADO a něco o nižší vrstvě která se může někdy hodit.

Než se z AnyDAC stal FireDAC byl součástí balíku konverzní nástroj ADDFMChanger, což je command line tool sloužící ke změně komponent na formulářích (viz. to DFM v názvu). Bohužel tento nástroj není přímo součástí instalace FireDAC prý z důvodu licenčních podmínek, ale je ho možné stáhnout z webu AnyDACu www.da-soft.com/download/anydac/anydac-addons/download.html. Nástroj je primárně určen ke konverzi ADO a BDE na FireDAC, ale jelikož jsou pravidla v textových souborech, je teoreticky možné upravit tyto pravidla a konvertovat jiné komponenty (bez záruky).

FireDAC (a AnyDAC) je primárně postaven na svých rozhraních a rozhraní pro TDataset je až nad těmito implementacemi. Dvě hlavní z těchto struktur jsou Data Storage Engine - DatS a physical Data Access Engine - Phys. Pokud tedy nechcete do svého programu linkovat podporu pro TDataSet a spol. je toto možná cesta.

Následující kód (z demo příkladu) ukazuje použití Phys:

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.Count – 1 do 
  begin
    s := ‘’;
    for J := 0 to oTab.Columns.Count – 1 do
      s := s + oTab.Rows[I].GetData(J) + ‘  ‘;
    mmLog.Add(s);
  end;
 
  // 6. free resources
  oTab.Free; 
end;

DatS zaručuje uložení dat z Phys v paměti (aspoň to tak chápu) - dá se s tím celkem kouzlit i z pohledu TDataSet. V našem programu (MS SQL DB) přes to např. dělám Refresh jednoho řádku, případně Delete bez smazání z DB.

Pokud se chcete z datasetu dostat na DatS tak stačí:

  oRow := GetRow; // aktuální řádek
  oRow.Delete();
  Table.Rows.Remove(oDestRow);
// případně přes SourceView
//ideálně přes BeginBatch, EndBatch což zařídí synchronizaci s datasetem

atd.

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;

Stále si hraji s optimalizacemi, je to jako kdybych dostal lego. Člověk z toho bez námahy složí auto podle obrázku, ale taky může popustit uzdu fantazii.

Minule jsem myslím upozorňoval na možnosti optimalizace přes velikost řádku a trochu jsem to přehnal s RowSetSize - moc velká hodnota moc žere paměť, nic se nesmí přehánět.

  FetchOptions.RowsetSize := 500;

Ale pokud jste opravdu hardcore a máte přehled o velikosti textových položek, lze optimalizovat i čtení stringů (nebo blobů).

  FormatOptions.InlineDataSize := 255; 

Tj. řetezce do velikosti 255 byte jsou součástí bufru řádku, větší jsou alokovány na haldě. Def. velikost je myslím 8000. První možnost je výrazně rychlejší, ale bufer je vždy o uvedené velikosti. Druhá možnost je efektivnější z hlediska ukládání, ale výrazně pomalejší.

Dále se dá např. nastavit možnosti cache (tj. zda se mají udržovat v cache bloby atd).

Pořád to vypadá že mi FireDac má co nabídnout.

BTW: aktuální verze je FireDAC XE4 Update 1 (FireDAC 8.0.3.3291).

Tagy:

Komentáře

20.5.2013 20:50:09 #

Daniel Andraščík

Parada. Uz sme sa tu niekde bavili ze pouzivam ZeosLib, pretoze tiez v zaklade nepouziva TDataSet. Tato informacia ze i FireDac sa da pouzit bez TDatasetu mozno vsetko zmeni :)

Daniel Andraščík

21.5.2013 19:01:41 #

MartyK

Radku, zdravím.
Tvoje nadšení z FireDacu je hezké, ale zdá se mi, že mezi verzí 7.0.1.3119 a 8.0.1.3279 se jim vloudila chyba. Alespoň při mých pokusech se mi to tak jeví.
Sice jsem to zkoušel v Builderu, ale  TADFormatOptions.StrsEmpty2Null ať nastavíš false nebo true, chová se pořád stejně (jako by bylo true, tzn. místo '' vrazí do tabulky NULL). V History.txt verze 8.0.1.3279 se píše, že byla změněna defaultní hodnota z true na false, ale asi se při tom stala někde chybka :-((. Verze 7.0.1.3119 totiž pracuje správně podle popisu. (Testy probíhaly na MS SQL Server Express 2008 R2). Nebo je to jinak?

MartyK

22.5.2013 13:06:19 #

radekc

Tak tu chybu reportuj na QC. Tady to má cenu jen jako informace pro ostatní.

radekc

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců