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).