Druhý (a možná poslední) díl poznámek o FireDAC, tak jak na to přicházím při přechodu z ADO.
CommandTimeout a ConnectionTimeout
ConnectionTimeout se specifikuje jako parametr pro Connection, tj.
oCon.Params.Values['LoginTimeout'] := IntToStr(iConnectionTimeout);
CommandTimeout se nastavuje jako parametr
ResourceOptions.CmdExecTimeout := iValue * 1000; // pro ekv. hodnotu z ADO * 1000
Ale pozor: normálně je nastaveno neomezeně, ale v případné nastavení hodnoty je řízeno spouštěním vlákna, což v případě nastavení malé dávky dat je celkem
hukot, kdy vlákna vznikají jak o duši.
Moje nastavení datasetu
with FormatOptions do
begin
OwnMapRules := True;
with MapRules.Add do
begin
SourceDataType := dtDateTimeStamp;
TargetDataType := dtDateTime;
end;
with MapRules.Add do
begin
SourceDataType := dtTime;
TargetDataType := dtDateTime;
end;
FormatOptions.StrsTrim2Len := True; // orizni string dle Size
FormatOptions.StrsTrim := False; // neodstranuj nadbytecne mezery
FormatOptions.StrsEmpty2Null := False;
UpdateOptions.RefreshMode:= rmManual; // zakaz automaticke refresh po POST
FetchOptions.RowsetSize := 10000; // bez docitani co nejvetsi! pro rychlost
end;
Toto mám definováno pro connection, jednotlivé datasety a spol. toto dědí. Na začátku nastavení mapování všech datumových typů na DateTime, RefreshMode mám manual protože nechci po Post reload dat a poslední položka je experimentálně zjištěno co nejrychlejší načítání dat v případě bez nastaveného dočítání.
Pro řazení jako v ADO se dá specifikovat
FormatOptions.SortOptions := [soNullFirst, soDescNullLast];
což určuje jak se bude chovat k řazení NULL.
Datum a ms
FireDAC vrací datum včetně ms, pokud se Vám to nelíbí (BDE ani ADO to nedělá)
function dtServer: TDateTime;
var
y, mo, d, h, m, s, ms: Word;
begin
Result := ExecuteScalar('SELECT GetDate()');
DecodeDate(Result, y, mo, d);
DecodeTime(Result, h, m, s, ms);
Result := EncodeDate(y, mo, d) + EncodeTime(h, m, s, 0);
end;
Refresh
Aktuálně používám možnost, kdy mám v jednom datasetu balík dat pro zobrazení a ten aktualizuji z jiného datasetu. Podmínkou je mít definované klíče a pak stačí
použít
ds.CopyDataSet(dsRefresh, [coRestart, coRefresh, coAppend])
což způsobí, že v cílovém DS jsou nahrazeny hodnoty pro nalezené záznamy. Pokud není nalezen záznam tak je přidán.
Podobně se dají kopírovat řádky:
ds.CopyDataSet(dsSource, [coStructure]); //jen struktura
a pak
ds.CopyDataSet(dsSource, [coRestart, coRefresh, coAppend]);
nebo něco jako
dsSource.First;
while not dsSource.Eof do
begin
if xxxx then
begin
ds.Append;
ds.CopyRecord(dsSource);
ds.Post;
end;
dsSource.Next;
end;
S řádky se dá různě šachovat a to nejen v případě TADMemTable, což je implementace velmi rychlé memory tabulky.