Mega Code Archive

 
Categories / Delphi / Examples
 

Interbase Sweep on the Fly in a thread

Title: Interbase Sweep on the Fly in a thread Question: In the Interbase Admin components there is a IBValidationService but is hard to use as it is. Sweeping is just one of the functions of the validation service. This component makes doing sweeps of databases alot easier, and also works in a thread. Ideal for use in server applications. Answer: (* Interbase Sweep Thread Author Kim Sandell Email: kim.sandell@celarius.com Description A Thread that performs an Sweep of an interbase database on the fly. The thread can automatically free itself after the sweep is done. Note: This can be a lengthy process so make sure you do not interrupt the program in the middle of the sweep. The sweeping process can not be interrupted !!! It makes sense to let it run in the background and free itself if you have a server program ! Parameters ---------- DatabaseName Full hostname:path to database DatabaseUsername The name of the user with rights to sweep the db DatabasePassword The password of the user FreeOnTerminate Set this to false if you want to free the thread yourself. Default is TRUE Priority The priority of the thread. Default is tpLower Version 1.0 History 24.09.2002 - Initial version Known issues None so far ... Example of usage The example below assumes you have included the "IBSweepThread" unit in the uses clause, and that you have a button on a form. The Thread must be created and the properties initialized, before the thread can be Resumed. procedure TForm1.Button1Click(Sender: TObject); Var IBSweep : TIBSweepThread; begin Try IBSweep := TIBSweepThread.Create( True ); IBSweep.DatabaseName := '127.0.0.1:C:\Databases\MyIBDB.GDB'; IBSweep.DatabaseUsername := 'SYSDBA'; IBSweep.DatabasePassword := 'masterkey'; IBSweep.FreeOnTerminate := False; // We want to see the results! IBSweep.Resume; { Wait for it } While Not IBSweep.Terminated do Begin SleepEx(1,True); Application.ProcessMessages; End; { Just make sure the thread is dead } IBSweep.WaitForAndSleep; { Check for success } If IBSweep.ResultState = state_Done then Begin MessageDlg( 'Sweep OK - Time taken: '+ IntToStr(IBSweep.ProcessTime)+' ms', mtInformation,[mbOK],0); ShowMessage( IBSweep.SweepResult.Text ); End Else MessageDlg('Sweep FAILED',mtError,[mbOK],0); Finally IBSweep.Free; End; end; *) unit IBSweepThread; interface uses Windows, Messages, SysUtils, Classes, IBServices; Const state_Idle = $0; state_Initializing = $1; state_Sweeping = $2; state_Done = $3; state_Error = $-1; type TIBSweepThread = class(TThread) private { Private declarations } protected { Protected declarations } Procedure DoSweep; public { Public declarations } DatabaseName : String; // Fully qualifyed name to db DatabaseUsername : String; // Username DatabasePassword : String; // Password Processing : Boolean; // True while processing ResultState : Integer; // See state_xxxx constants ProcessTime : Cardinal; // Milliseconds of the sweep Property Terminated; // Make the Terminated published Constructor Create( CreateSuspended: Boolean ); Virtual; Procedure Execute; Override; Procedure WaitForAndSleep; published { Published declarations } end; implementation { TIBSweepThread } /////////////////////////////////////////////////////////////////////////////// // // Threads Constructor. Allocated objects, and initializes some // variables to the default states. // // Also sets the Priority and FreeOnTreminate conditions. // /////////////////////////////////////////////////////////////////////////////// constructor TIBSweepThread.Create(CreateSuspended: Boolean); begin { Override user parameter } Inherited Create( True ); { Default parameters } FreeOnTerminate := False; Priority := tpLower; { Set variables } Processing := False; ResultState := state_Idle; end; /////////////////////////////////////////////////////////////////////////////// // // Threads execute loop. Jumps to the DoWork() procedure every 250 ms // /////////////////////////////////////////////////////////////////////////////// procedure TIBSweepThread.Execute; begin Try { Perform the Sweep } DoSweep; Except On E:Exception do ; // TODO: Execption logging End; { Signal terminated } Terminate; end; /////////////////////////////////////////////////////////////////////////////// // // Waits for the Thread to finish. Same as WaitFor, but does not take // 100% CPU time while waiting ... // /////////////////////////////////////////////////////////////////////////////// procedure TIBSweepThread.WaitForAndSleep; Var H : THandle; D : DWord; begin { Get Handle } H := Handle; { Wait for it to terminate } Repeat D := WaitForSingleObject(H, 1); { System Slizes } SleepEx(1,True); Until (Terminated) OR ((DWAIT_TIMEOUT) AND (DWAIT_OBJECT_0)); end; /////////////////////////////////////////////////////////////////////////////// // // Makes a sweep of the database specifyed in the properties. // /////////////////////////////////////////////////////////////////////////////// procedure TIBSweepThread.DoSweep; Var IBSweep : TIBValidationService; SrvAddr : String; DBName : String; begin Try { Set Start Time } ProcessTime := GetTickCount; { Extract SrvAddr and DBName from DatabaseName } SrvAddr := DatabaseName; { Correct if Local machine } If Pos(':',SrvAddr)0 then Begin Delete( SrvAddr, Pos(':',SrvAddr), Length(SrvAddr) ); DBName := DatabaseName; Delete( DBName, 1, Pos(':',DBName) ); End Else Begin { Must be localhost since Server Address is missing } SrvAddr := '127.0.0.1'; DBName := DatabaseName; End; { Set Flags } Processing := True; ResultState := state_Initializing; Try { Create IBValidationService } IBSweep := TIBValidationService.Create( NIL ); IBSweep.Protocol := TCP; IBSweep.LoginPrompt := False; IBSweep.Params.Values['user_name'] := DatabaseUsername; IBSweep.Params.Values['password'] := DatabasePassword; IBSweep.ServerName := SrvAddr; IBSweep.DatabaseName := DBName; IBSweep.Active := True; IBSweep.Options := [SweepDB]; Try { Start the service } IBSweep.ServiceStart; { Set state } ResultState := state_Sweeping; { Get the Report Lines - No lines in Sweeping but needs to be done } While NOT IBSweep.Eof do BEGIN IBSweep.GetNextLine; { Wait a bit } Sleep(1); END; Finally { Deactive Service } IBSweep.Active := False; End; { Set State to OK } ResultState := state_Done; Except On E:Exception do Begin { Set State to OK } ResultState := state_Error; End; End Finally { Calculate Process Time } ProcessTime := GetTickCount-ProcessTime; { Free objects } If Assigned(IBSweep) then Begin If IBSweep.Active then IBSweep.Active := False; IBSweep.Free; IBSweep := NIL; End; { Set flag } Processing := False; End; end; end.