|
|
Adattábla eseményeit naplózó komponens készítése
|
|
Példaprogram letöltése
12081 bájt
|
Ebben a cikkben egy olyan komponenst mutatunk be, amely képes egy TDataSet osztályból származó komponens (TTable, TQuery, stb.) szinte összes eseményét naplózni, vagyis egy tetszőlegesen megadható log fájlba menteni. Ez nagyszerűen használható az adatbázis műveletek nyomon követésére, vagy hiba esetén a hiba okának felderítésére. Nekünk nincs más dolgunk, mint feltenni a komponenst a Form-ra, beállítani az adatbázist, bejelölni a naplózni kívánt eseményeket, és megadni a log fájl nevét. Ezután a többit csak rá kell bíznunk a komponensre.
A mellékelt példaprogram megnyitása előtt a DBLog.pas-ban lévő komponenst telepítenie kell a Delphi alá.
A LogFileName property-ben kell megadni a log fájl nevét. A LogEvents property-ben állíthatjuk be a naplózni kívánt eseményeket. Ezek a következők lehetnek:
- BeforeCancel
- BeforeClose
- BeforeDelete
- BeforeEdit
- BeforeInsert
- BeforeOpen
- AfterPost
- BeforePost
- OnCalcFields
- OnDeleteError
- OnEditError
- OnNewRecord
- OnPostError
A komponens működési elve az, hogy a Dataset property-ben megadott adatbázis eseményeihez hozzárendel egy-egy belső eljárást. Ezekben az eljárásokban a szükséges információkat kiírjuk a LogFileName property-ben megadott fájlba.
A log fájl megnyitását vagy létrehozását a StartLog eljárás végzi. Ebben először megnézzük, hogy van-e már log fájl megnyitva, és ha igen, akkor lezárjuk azt a CloseLog metódus meghívásával. Ha az Enabled property True, akkor megnézzük, hogy a megadott fájl már létezik-e. Ha létezik, akkor megnyitjuk, ellenkező esetben létrehozzuk. A log fájlt egyébként a TFileStream osztályon keresztül kezeljük. Miután megnyitottuk a fájlt, a végére pozícionálunk, majd kiírjuk a fejlécet. A log fájlba a WriteLog eljárással tudunk szöveget kiírni.
procedure TDBLog.StartLog;
var fmode:word;
begin
if NOT (csDesigning in ComponentState) then
begin
if Assigned(FLogFile) then CloseLog;
if FEnabled then begin
try
fmode:=fmCreate;
if FileExists(FLogFileName) then fmode:=fmOpenReadWrite;
FLogFile:=TFileStream.Create(FLogFileName, fmode);
FLogFile.Seek(0, soFromEnd);
WriteLog('******************************************');
WriteLog('* Log started: '+DateTimeToStr(Now));
WriteLog('*'+CRLF);
except
Application.MessageBox(PChar(
'A "'+FLogFileName+'" fájlt nem sikerült megnyitni!'),
'Hiba!',
MB_OK+MB_ICONSTOP);
FEnabled:=False;
end;
end;
end;
end;
A CloseLog belső eljárással zárhatjuk le a log fájlt.
procedure TDBLog.CloseLog;
begin
if Assigned(FLogFile) then begin
WriteLog('');
WriteLog('*');
WriteLog('* Log finished: '+DateTimeToStr(Now));
WriteLog('******************************************');
WriteLog(CRLF);
FLogFile.Free;
FLogFIle:=NIL;
end;
end;
A WriteLog eljárással írhatunk a log fájlba. Ha a fájl meg van nyitva, és az Enabled property értéke true, akkor a paraméterként megkapott sztringet kiírja a log fájlba.
procedure TDBLog.WriteLog;
var buff:array[0..511] of char;
begin
if Assigned(FLogFile) and (FEnabled) then begin
msg:=msg+CRLF;
StrPCopy(buff, msg);
FLogFile.Write(buff, Length(msg));
end;
end;
Néhány eseménynél azt is jó lenne látni, hogy az aktuális rekord milyen adatokat tartalmaz. Éppen ezért létrehoztunk egy belső eljárást, ami a rekord tartalmát kiírja a log fájlba.
procedure TDBLog.WriteCurrentRecord;
var i, ml:integer;
v, fn, ms:string;
begin
Készítünk egy szóközökből álló sztringet, ami 1 karakterrel hosszabb lesz, mint a leghosszabb mezőnév. Erre azért van szükség, hogy a mezők értékeit egymás alá tudjuk igazítani.
ml:=0;
for i:=0 to Dataset.FieldCount-1 do begin
fn:=Dataset.Fields[i].FieldName;
if Length(fn)>ml then ml:=Length(fn);
end;
ms:=StringOfChar(' ', ml+1);
Végighaladunk a Dataset mezőin, és kiírjuk a nevüket, valamint az aktuális értéküket a log fájlba.
for i:=0 to Dataset.FieldCount-1 do begin
fn:=Dataset.Fields[i].FieldName;
if Dataset.Fields[i].IsNull then v:='<NULL>' else
if Dataset.Fields[i].IsBlob then v:='<BLOB>' else v:='"'+Dataset.Fields[i].AsString+'"';
WriteLog(' '+Copy(fn+ms, 1, Length(ms))+v);
end;
end;
Most nézzük meg egy-egy eseményt kiemelve, hogy hogyan történik a tárolásuk a log fájlba. Először az AfterPost eseményt vizsgáljuk meg, mivel itt az aktuális rekord tartalmát is kiírjuk a fájlba.
Első lépésben ellenőrizzük, hogy az esemény naplózása engedélyezve van-e. Ezt a LogEvents property-ből tudhatjuk meg. Az Enabled property értékét itt nem kell figyelnünk, mert azt a WriteLog eljárásban úgyis ellenőrizzük. Ha az eseményt naplózni kell, akkor kiírjuk az esemény azonosítóját, és az aktuális dátumot és időpontot. Az események azonosítója mindig "#" karakterrel kezdődik. Ha kiírtuk az azonosítót, akkor utána meghívjuk a WriteCurrentRecord eljárást, ami az aktuális rekordot másolja a log fájlba. Ezután még kiírunk egy "# END OF …" azonosítót, hogy tudjuk, az eseményhez tartozó adatok eddig tartottak. Ezt csak abban az esetben tesszük meg, ha az esemény azonosítóján kívül további adatokat is tárolunk. Ha a kiírással végeztünk, akkor meghívjuk az eredeti eseménykezelő eljárást, ha volt ilyen.
procedure TDBLog.DoAfterPost;
begin
if (leAfterPost in FLogEvents) then begin
WriteLog('# AFTER POST '+DateTimeToStr(Now));
WriteCurrentRecord;
WriteLog('# END OF AFTER POST '+DateTimeToStr(Now));
end;
if Assigned(FOldAfterPost) then FOldAfterPost(DataSet);
end;
Egy másik esemény típus, amikor hibaüzenetet is kapunk. Ilyen például az OnPostError esemény is. Ez annyiban különbözik az előzőtől, hogy itt az aktuális rekordon kívül az E paraméter Message mezőjét is eltároljuk, mivel ez tartalmazza a hibaüzenetet.
procedure TDBLog.DoOnPostError;
begin
if (lePostError in FLogEvents) then begin
WriteLog('# POST ERROR '+DateTimeToStr(Now));
WriteLog(E.Message);
WriteCurrentRecord;
WriteLog('# END OF POST ERROR '+DateTimeToStr(Now));
end;
if Assigned(FOldOnPostError) then FOldOnPostError(DataSet, E, Action);
end;
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 295. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|