home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / Runimage / Delphi50 / Demos / Db / Bkquery / resltfrm.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-08-11  |  3.8 KB  |  155 lines

  1. unit ResltFrm;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   ExtCtrls, DB, DBTables, Grids, DBGrids, StdCtrls;
  8.  
  9. type
  10.   TQueryForm = class(TForm)
  11.     QueryLabel: TLabel;
  12.     DBGrid1: TDBGrid;
  13.     DataSource: TDataSource;
  14.     Query: TQuery;
  15.     Session: TSession;
  16.     StatusLine: TLabel;
  17.     Database: TDatabase;
  18.   private
  19.     { Private declarations }
  20.   public
  21.     { Public declarations }
  22.   end;
  23.  
  24. procedure BackgroundQuery(const QueryName, Alias, User, Password,
  25.   QueryText: string);
  26.  
  27. implementation
  28.  
  29. {$R *.DFM}
  30.  
  31. { TQueryThread }
  32.  
  33. type
  34.   TQueryThread = class(TThread)
  35.   private
  36.     QueryForm: TQueryForm;
  37.     MessageText: string;
  38.     procedure ConnectQuery;
  39.     procedure DisplayMessage;
  40.   protected
  41.     procedure Execute; override;
  42.   public
  43.     constructor Create(AQueryForm: TQueryForm);
  44.   end;
  45.  
  46. constructor TQueryThread.Create(AQueryForm: TQueryForm);
  47. begin
  48.   QueryForm := AQueryForm;
  49.   FreeOnTerminate := True;
  50.   inherited Create(False);
  51. end;
  52.  
  53. var
  54.   Guard: Integer;
  55.   Numbers: Integer;
  56.  
  57. { Thread safe increment of Numbers to guarantee the result is unique }
  58.  
  59. function GetUniqueNumber: Integer;
  60. asm
  61. @@1:    MOV     EDX,1
  62.         XCHG    Guard,EDX
  63.         OR      EDX,EDX
  64.         JNZ     @@2
  65.         MOV     EAX,Numbers
  66.         INC     EAX
  67.         MOV     Numbers,EAX
  68.         MOV     Guard,EDX
  69.         RET
  70.  
  71. @@2:    PUSH    0
  72.         CALL    Sleep
  73.         JMP     @@1
  74. end;
  75.  
  76.  
  77. procedure TQueryThread.Execute;
  78. var
  79.   UniqueNumber: Integer;
  80. begin
  81.   try
  82.     with QueryForm do
  83.     begin
  84.       { Ensure the Query has a unique session and database.  A unique session
  85.         is required for each thread.  Since databases are session specific
  86.         it must be unique as well }
  87.       UniqueNumber := GetUniqueNumber;
  88.       Session.SessionName := Format('%s%x', [Session.Name, UniqueNumber]);
  89.       Database.SessionName := Session.SessionName;
  90.  
  91.       Database.DatabaseName := Format('%s%x', [Database.Name, UniqueNumber]);
  92.       Query.SessionName := Database.SessionName;
  93.       Query.DatabaseName := Database.DatabaseName;
  94.  
  95.       { Open the query }
  96.       Query.Open;
  97.  
  98.       { Connect the query to the grid.  This must be done in a synchronzied
  99.         method since assigning the query to the DataSource will modify the
  100.         contents of the grid and the grid can only be modified from the main
  101.         VCL thread }
  102.       Synchronize(ConnectQuery);
  103.  
  104.       { Update the status line.  Since the label is a VCL control this must
  105.         also be done in the main VCL thread }
  106.       MessageText := 'Query openned';
  107.       Synchronize(DisplayMessage);
  108.     end;
  109.   except
  110.     on E: Exception do
  111.     begin
  112.       { Display any error we receive on the status line }
  113.       MessageText := Format('%s: %s.', [E.ClassName, E.Message]);
  114.       Synchronize(DisplayMessage);
  115.     end;
  116.   end;
  117. end;
  118.  
  119. procedure TQueryThread.ConnectQuery;
  120. begin
  121.   with QueryForm do DataSource.Dataset := Query;
  122. end;
  123.  
  124. procedure TQueryThread.DisplayMessage;
  125. begin
  126.   with QueryForm do StatusLine.Caption := MessageText;
  127. end;
  128.  
  129. { BackgroundQuery }
  130.  
  131. procedure BackgroundQuery(const QueryName, Alias, User, Password,
  132.   QueryText: string);
  133. var
  134.   QueryForm: TQueryForm;
  135. begin
  136.   QueryForm := TQueryForm.Create(Application);
  137.   with QueryForm, Database do
  138.   begin
  139.     Caption := QueryName;
  140.     QueryLabel.Caption := QueryText;
  141.     Show;
  142.     AliasName := Alias;
  143.     Params.Values['USER'] := User;
  144.     Params.Values['PASSWORD'] := Password;
  145.     Query.Sql.Text := QueryText;
  146.   end;
  147.  
  148.   { Create the background thread to execute the query. Since the thread
  149.     will free itself on termination we do not neet to maintain a reference
  150.     to it.  Creating it is enough }
  151.   TQueryThread.Create(QueryForm);
  152. end;
  153.  
  154. end.
  155.