* Remove unused code paths.

* Raise flag when a bug occurs.
This commit is contained in:
rosenfield.albert
2008-07-08 14:56:09 +00:00
parent d4e9386682
commit 8ca2138a48
4 changed files with 21 additions and 204 deletions

View File

@ -4073,7 +4073,7 @@ begin
end; end;
FProgressForm := TFrmQueryProgress.Create(Self); FProgressForm := TFrmQueryProgress.Create(Self);
debug('RunThreadedQuery(): Launching asynchronous query.'); debug('RunThreadedQuery(): Launching asynchronous query.');
res := ExecPostAsync(FConn,nil,FProgressForm.Handle,ds); res := ExecPostAsync(FConn,FProgressForm.Handle,ds);
WaitForQueryCompletion(FProgressForm, res, false); WaitForQueryCompletion(FProgressForm, res, false);
if res.Result in [MQR_CONNECT_FAIL,MQR_QUERY_FAIL] then if res.Result in [MQR_CONNECT_FAIL,MQR_QUERY_FAIL] then
begin begin
@ -4121,7 +4121,7 @@ begin
* Set FQueryRunning to false * Set FQueryRunning to false
} }
debug('RunThreadedQuery(): Launching asynchronous query.'); debug('RunThreadedQuery(): Launching asynchronous query.');
Result := ExecMysqlStatementAsync (AQuery,FConn,nil,FProgressForm.Handle,RunAsyncPost); Result := ExecMysqlStatementAsync (AQuery,FConn,FProgressForm.Handle,RunAsyncPost);
{ Repeatedly check if the query has finished by inspecting FQueryRunning { Repeatedly check if the query has finished by inspecting FQueryRunning
Allow repainting of user interface Allow repainting of user interface

View File

@ -6,15 +6,6 @@ uses Windows, Messages, Classes, Db, ZConnection, ZDataSet, MysqlQueryThread,
HeidiComp; HeidiComp;
const const
// Query execution mode
MQM_SYNC = 0;
MQM_ASYNC = 1;
// Query status notification mode
MQN_EVENTPROC = 0; // via event procedure with Synchronize
MQN_WINMESSAGE = 1; // via window message WM_MYSQL_THREAD_NOTIFY
// Thread notification events // Thread notification events
MQE_INITED = 0; // initialized MQE_INITED = 0; // initialized
MQE_STARTED = 1; // query started MQE_STARTED = 1; // query started
@ -42,14 +33,10 @@ type
FMysqlConnectionIsOwned : Boolean; FMysqlConnectionIsOwned : Boolean;
FMysqlDataset : TDataset; FMysqlDataset : TDataset;
FThreadID : Integer; FThreadID : Integer;
FSyncMode : Integer;
FQueryThread : TMysqlQueryThread; FQueryThread : TMysqlQueryThread;
FEventName : String; FEventName : String;
FEventHandle : THandle; FEventHandle : THandle;
FSql : WideString; FSql : WideString;
FOnNotify : TMysqlQueryNotificationEvent;
function GetNotificationMode: Integer;
function GetConnectionID: Integer;
function GetComment: String; function GetComment: String;
function GetResult: Integer; function GetResult: Integer;
function GetHasresultSet: Boolean; function GetHasresultSet: Boolean;
@ -58,14 +45,13 @@ type
public public
constructor Create (AOwner : TComponent; AConn : POpenConnProf); overload; constructor Create (AOwner : TComponent; AConn : POpenConnProf); overload;
destructor Destroy (); override; destructor Destroy (); override;
procedure Query(ASql: WideString; AMode: Integer; ANotifyWndHandle : THandle; Callback: TAsyncPostRunner; ds: TDeferDataSet); procedure Query(ASql: WideString; ANotifyWndHandle : THandle; Callback: TAsyncPostRunner; ds: TDeferDataSet);
procedure SetMysqlDataset(ADataset : TDataset); procedure SetMysqlDataset(ADataset : TDataset);
procedure PostNotification (AQueryResult : TThreadResult; AEvent : Integer); procedure PostNotification (AQueryResult : TThreadResult; AEvent : Integer);
procedure SetThreadResult(AResult : TThreadResult); procedure SetThreadResult(AResult : TThreadResult);
property Result : Integer read GetResult; // Query result code property Result : Integer read GetResult; // Query result code
property Comment : String read GetComment; // Textual information about the query result, includes error description property Comment : String read GetComment; // Textual information about the query result, includes error description
property ConnectionID : Integer read GetConnectionID; // Mysql connection ID
property MysqlConnection : TZConnection read FMysqlConnection; property MysqlConnection : TZConnection read FMysqlConnection;
property MysqlDataset : TDataset read FMysqlDataset; // Resultset property MysqlDataset : TDataset read FMysqlDataset; // Resultset
property HasResultset : Boolean read GetHasresultSet; // Indicator of resultset availability property HasResultset : Boolean read GetHasresultSet; // Indicator of resultset availability
@ -73,13 +59,10 @@ type
property Sql : WideString read FSql; // Query string property Sql : WideString read FSql; // Query string
property EventName : String read FEventName; // Operating system event name used for blocking mode property EventName : String read FEventName; // Operating system event name used for blocking mode
property EventHandle : THandle read FEventHandle; property EventHandle : THandle read FEventHandle;
property NotificationMode : Integer read GetNotificationMode;
property OnNotify : TMysqlQueryNotificationEvent read FOnNotify write FOnNotify; // Event procedure used in MQN_EVENTPROC notification mode
end; end;
function ExecMysqlStatementAsync(ASql : WideString; AConn : TOpenConnProf; ANotifyProc : TMysqlQueryNotificationEvent; AWndHandle : THandle; Callback: TAsyncPostRunner) : TMysqlQuery; function ExecMysqlStatementAsync(ASql : WideString; AConn : TOpenConnProf; AWndHandle : THandle; Callback: TAsyncPostRunner) : TMysqlQuery;
function ExecMysqlStatementBlocking(ASql : WideString; AConn : TOpenConnProf; AWndHandle : THandle) : TMysqlQuery; function ExecPostAsync(AConn : TOpenConnProf; AWndHandle : THandle; ds: TDeferDataSet): TMysqlQuery;
function ExecPostAsync(AConn : TOpenConnProf; ANotifyProc : TMysqlQueryNotificationEvent; AWndHandle : THandle; ds: TDeferDataSet): TMysqlQuery;
implementation implementation
@ -94,50 +77,26 @@ uses
Wrapper function to simplify running a query in asynchronous mode Wrapper function to simplify running a query in asynchronous mode
This function will end right after the thread is created. This function will end right after the thread is created.
If ANotifyProc<>nil then status notifications will be send using this eventproc;
* use the ASender param to inspect the result
Otherwise status notifications are sent by the WM_MYSQL_THREAD_NOTIFY message; Otherwise status notifications are sent by the WM_MYSQL_THREAD_NOTIFY message;
* use the WParam member of the AMessage parameter (a TMysqlQuery object) * use the WParam member of the AMessage parameter (a TMysqlQuery object)
@param string SQL-statement @param string SQL-statement
@param TConnParams Connection credentials structure @param TConnParams Connection credentials structure
@param TMysqlQueryNotificationEvent Notify procedure
@param THandle Window handle to post thread status messages to @param THandle Window handle to post thread status messages to
} }
function ExecMysqlStatementAsync(ASql : WideString; AConn : TOpenConnProf; ANotifyProc : TMysqlQueryNotificationEvent; AWndHandle : THandle; Callback: TAsyncPostRunner) : TMysqlQuery; function ExecMysqlStatementAsync(ASql : WideString; AConn : TOpenConnProf; AWndHandle : THandle; Callback: TAsyncPostRunner) : TMysqlQuery;
begin begin
Result := TMysqlQuery.Create(nil,@AConn); Result := TMysqlQuery.Create(nil,@AConn);
Result.OnNotify := ANotifyProc; Result.Query(ASql,AWndHandle,Callback,nil);
Result.Query(ASql,MQM_ASYNC,AWndHandle,Callback,nil);
end; end;
function ExecPostAsync(AConn : TOpenConnProf; ANotifyProc : TMysqlQueryNotificationEvent; AWndHandle : THandle; ds: TDeferDataSet): TMysqlQuery; function ExecPostAsync(AConn : TOpenConnProf; AWndHandle : THandle; ds: TDeferDataSet): TMysqlQuery;
begin begin
Result := TMysqlQuery.Create(nil,@AConn); Result := TMysqlQuery.Create(nil,@AConn);
Result.OnNotify := ANotifyProc; Result.Query('',AWndHandle,nil,ds);
Result.Query('',MQM_ASYNC,AWndHandle,nil,ds);
end; end;
{***
Wrapper function to simplify running a query in blocking mode
Status notifications are sent by the WM_MYSQL_THREAD_NOTIFY message;
Use the WParam member of the AMessage parameter (a TMysqlQuery object)
@param string The single SQL-statement to be executed
@param TConnParams Connection credentials structure
@param THandle Window handle to post thread status messages to
@return TMysqlQuery Query object returned to resolve status info and the data
}
function ExecMysqlStatementBlocking(ASql : WideString; AConn : TOpenConnProf; AWndHandle : THandle) : TMysqlQuery;
begin
Result := TMysqlQuery.Create(nil,@AConn);
Result.Query(ASql,MQM_SYNC,AWndHandle,nil,nil);
end;
{ TMysqlQuery } { TMysqlQuery }
@ -194,24 +153,11 @@ begin
Result := FQueryResult.Comment; Result := FQueryResult.Comment;
end; end;
function TMysqlQuery.GetConnectionID: Integer;
begin
Result := FQueryResult.ConnectionID;
end;
function TMysqlQuery.GetHasresultSet: Boolean; function TMysqlQuery.GetHasresultSet: Boolean;
begin begin
Result := FMysqlDataset <> nil; Result := FMysqlDataset <> nil;
end; end;
function TMysqlQuery.GetNotificationMode: Integer;
begin
if Assigned(FOnNotify) then
Result := MQN_EVENTPROC
else
Result := MQN_WINMESSAGE;
end;
function TMysqlQuery.GetResult: Integer; function TMysqlQuery.GetResult: Integer;
begin begin
Result := FQueryResult.Result; Result := FQueryResult.Result;
@ -220,62 +166,26 @@ end;
procedure TMysqlQuery.PostNotification(AQueryResult: TThreadResult; AEvent : Integer); procedure TMysqlQuery.PostNotification(AQueryResult: TThreadResult; AEvent : Integer);
begin begin
SetThreadResult(AQueryResult); SetThreadResult(AQueryResult);
debug(Format('qry: Not calling notify function, event type %d occurred.', [AEvent]));
if
(FSyncMode = MQM_ASYNC) and
(AEvent in [MQE_INITED,MQE_STARTED,MQE_FINISHED,MQE_FREED]) and
Assigned(FOnNotify) then begin
debug(Format('qry: Calling notify function, event type %d occurred.', [AEvent]));
FOnNotify(Self, AEvent);
end else begin
debug(Format('qry: Not calling notify function, event type %d occurred.', [AEvent]));
end;
end; end;
procedure TMysqlQuery.Query(ASql: WideString; AMode: Integer; ANotifyWndHandle : THandle; Callback: TAsyncPostRunner; ds: TDeferDataSet); procedure TMysqlQuery.Query(ASql: WideString; ANotifyWndHandle : THandle; Callback: TAsyncPostRunner; ds: TDeferDataSet);
begin begin
// create thread object // create thread object
FQueryThread := TMysqlQueryThread.Create(Self,FConn,ASql,AMode,Callback,ds); FQueryThread := TMysqlQueryThread.Create(Self,FConn,ASql,Callback,ds);
FQueryThread.NotifyWndHandle := ANotifyWndHandle; FQueryThread.NotifyWndHandle := ANotifyWndHandle;
FThreadID := FQueryThread.ThreadID; FThreadID := FQueryThread.ThreadID;
FEventName := APPNAME+'_'+IntToStr(FThreadID); FEventName := APPNAME+'_'+IntToStr(FThreadID);
FSyncMode := AMode;
FSql := ASql; FSql := ASql;
FEventHandle := CreateEvent ({*EVENT_MODIFY_STATE + SYNCHRONIZE*}nil, False, False, PChar(FEventName)); FEventHandle := CreateEvent ({*EVENT_MODIFY_STATE + SYNCHRONIZE*}nil, False, False, PChar(FEventName));
case AMode of // exec query
MQM_SYNC: debug(Format('qry: Starting query thread %d', [FQueryThread.ThreadID]));
begin FQueryThread.Resume();
// exec query
debug(Format('qry: Starting query thread %d', [FQueryThread.ThreadID]));
FQueryThread.Resume();
debug(Format('qry: Waiting for query thread %d', [FQueryThread.ThreadID]));
WaitForSingleObject (EventHandle, INFINITE);
debug(Format('qry: Done waiting for query thread %d', [FQueryThread.ThreadID]));
CloseHandle (EventHandle);
// read status
// free thread
end;
MQM_ASYNC:
begin
// exec query
debug(Format('qry: Starting query thread %d', [FQueryThread.ThreadID]));
FQueryThread.Resume();
end;
end;
end; end;
{***
@param
@param
@result
}
procedure TMysqlQuery.SetMysqlDataset(ADataset: TDataset); procedure TMysqlQuery.SetMysqlDataset(ADataset: TDataset);
begin begin
FMysqlDataset := ADataset; FMysqlDataset := ADataset;
@ -286,8 +196,7 @@ begin
try try
FQueryResult := AResult; FQueryResult := AResult;
except except
// Todo: Find cause of sporadical AV here. Avoid annoyance in the meantime by raise Exception.Create('Assertion failed: Internal error in SetThreadResult().');
// suppressing AVs here which doesn't seem to have any (visible) problematic consequences.
end; end;
end; end;

View File

@ -49,19 +49,12 @@ type
TThreadResult = record TThreadResult = record
ThreadID : Integer; ThreadID : Integer;
ConnectionID : Cardinal;
Action : Integer; Action : Integer;
Sql : WideString; Sql : WideString;
Result : Integer; Result : Integer;
Comment : String; Comment : String;
end; end;
{*TMysqlConnectThread = class(TThread)
private
protected
public
end;*}
TMysqlQueryThread = class(TThread) TMysqlQueryThread = class(TThread)
private private
FMysqlConn : TZConnection; FMysqlConn : TZConnection;
@ -72,26 +65,20 @@ type
FPostDataSet: TDeferDataSet; FPostDataSet: TDeferDataSet;
FResult : Integer; FResult : Integer;
FComment : String; FComment : String;
FSyncMode : Integer;
FNotifyWndHandle : THandle; FNotifyWndHandle : THandle;
procedure ReportInit;
procedure ReportStart;
procedure ReportFinished;
procedure ReportFreed;
function GetExceptionData(AException : Exception) : TExceptionData; function GetExceptionData(AException : Exception) : TExceptionData;
protected protected
procedure Execute; override; procedure Execute; override;
procedure SetState (AResult : Integer; AComment : String); procedure SetState (AResult : Integer; AComment : String);
procedure SetNotifyWndHandle (Value : THandle); procedure SetNotifyWndHandle (Value : THandle);
procedure NotifyStatus (AEvent : Integer); procedure NotifyStatus (AEvent : Integer);
procedure NotifyStatusViaEventProc (AEvent : Integer);
procedure NotifyStatusViaWinMessage (AEvent : Integer); procedure NotifyStatusViaWinMessage (AEvent : Integer);
function AssembleResult () : TThreadResult; function AssembleResult () : TThreadResult;
function RunDataQuery (ASql : WideString; var ADataset : TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner) : Boolean; function RunDataQuery (ASql : WideString; var ADataset : TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner) : Boolean;
function RunUpdateQuery (ASql : WideString; var ADataset : TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner) : Boolean; function RunUpdateQuery (ASql : WideString; var ADataset : TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner) : Boolean;
function QuerySingleCellAsInteger (ASql : WideString) : Integer; function QuerySingleCellAsInteger (ASql : WideString) : Integer;
public public
constructor Create (AOwner : TObject; AConn : TOpenConnProf; ASql : WideString; ASyncMode : Integer; Callback: TAsyncPostRunner; APostDataSet: TDeferDataSet); constructor Create (AOwner : TObject; AConn : TOpenConnProf; ASql : WideString; Callback: TAsyncPostRunner; APostDataSet: TDeferDataSet);
destructor Destroy; override; destructor Destroy; override;
property NotifyWndHandle : THandle read FNotifyWndHandle write SetNotifyWndHandle; property NotifyWndHandle : THandle read FNotifyWndHandle write SetNotifyWndHandle;
end; end;
@ -110,17 +97,13 @@ begin
ZeroMemory (@Result,SizeOf(Result)); ZeroMemory (@Result,SizeOf(Result));
Result.ThreadID := ThreadID; Result.ThreadID := ThreadID;
try
Result.ConnectionID := FMysqlConn.GetThreadId;
except
end;
Result.Action := 1; Result.Action := 1;
Result.Sql := FSql; Result.Sql := FSql;
Result.Result := FResult; Result.Result := FResult;
Result.Comment := FComment; Result.Comment := FComment;
end; end;
constructor TMysqlQueryThread.Create (AOwner : TObject; AConn : TOpenConnProf; ASql : WideString; ASyncMode : Integer; Callback: TAsyncPostRunner; APostDataSet: TDeferDataSet); constructor TMysqlQueryThread.Create (AOwner : TObject; AConn : TOpenConnProf; ASql : WideString; Callback: TAsyncPostRunner; APostDataSet: TDeferDataSet);
var var
mc : TZConnection; mc : TZConnection;
begin begin
@ -128,7 +111,6 @@ begin
FOwner := AOwner; FOwner := AOwner;
FConn := AConn; FConn := AConn;
FSyncMode := ASyncMode;
FCallback := Callback; FCallback := Callback;
FPostDataSet := APostDataSet; FPostDataSet := APostDataSet;
mc := TMysqlQuery(FOwner).MysqlConnection; mc := TMysqlQuery(FOwner).MysqlConnection;
@ -144,7 +126,6 @@ begin
mc.Port := AConn.MysqlParams.Port; mc.Port := AConn.MysqlParams.Port;
FreeOnTerminate := True; FreeOnTerminate := True;
end; end;
destructor TMysqlQueryThread.Destroy; destructor TMysqlQueryThread.Destroy;
@ -153,15 +134,11 @@ begin
end; end;
procedure TMysqlQueryThread.NotifyStatus(AEvent: Integer); procedure TMysqlQueryThread.NotifyStatus(AEvent: Integer);
var var
h : THandle; h : THandle;
qr : TThreadResult; qr : TThreadResult;
begin begin
if AEvent = MQE_FINISHED then begin if AEvent = MQE_FINISHED then begin
debug(Format('qry: Setting result', [AEvent])); debug(Format('qry: Setting result', [AEvent]));
qr := AssembleResult(); qr := AssembleResult();
@ -169,34 +146,14 @@ begin
// trigger query finished event // trigger query finished event
h := OpenEvent (EVENT_MODIFY_STATE,False,PChar(TMysqlQuery(FOwner).EventName)); h := OpenEvent (EVENT_MODIFY_STATE,False,PChar(TMysqlQuery(FOwner).EventName));
debug('qry: Signalling completion via event.'); debug('qry: Signalling completion via event.');
if not SetEvent (h) then debug(Format('qry: Assertion failed: Error %d signaling event', [GetLastError])); if not SetEvent (h) then raise Exception.Create(Format('Assertion failed: Error %d signaling event', [GetLastError]));
CloseHandle(h); CloseHandle(h);
end; end;
NotifyStatusViaWinMessage(AEvent);
case TMysqlQuery(FOwner).NotificationMode of
MQN_EVENTPROC: NotifyStatusViaEventProc(AEvent);
MQN_WINMESSAGE: NotifyStatusViaWinMessage(AEvent);
end;
end;
procedure TMysqlQueryThread.NotifyStatusViaEventProc(AEvent: Integer);
begin
if FSyncMode=MQM_ASYNC then
begin
case AEvent of
MQE_INITED: Synchronize(ReportInit);
MQE_STARTED: Synchronize(ReportStart);
MQE_FINISHED: Synchronize(ReportFinished);
MQE_FREED: Synchronize(ReportFreed);
end;
end;
end; end;
procedure TMysqlQueryThread.NotifyStatusViaWinMessage(AEvent: Integer); procedure TMysqlQueryThread.NotifyStatusViaWinMessage(AEvent: Integer);
begin begin
debug('qry: Signalling completion via message.');
debug(Format('qry: Posting status %d via WM_MYSQL_THREAD_NOTIFY message', [AEvent])); debug(Format('qry: Posting status %d via WM_MYSQL_THREAD_NOTIFY message', [AEvent]));
PostMessage(FNotifyWndHandle,WM_MYSQL_THREAD_NOTIFY,Integer(FOwner),AEvent); PostMessage(FNotifyWndHandle,WM_MYSQL_THREAD_NOTIFY,Integer(FOwner),AEvent);
end; end;
@ -234,11 +191,6 @@ begin
end else begin end else begin
try try
r := RunDataQuery (FSql,TDataSet(q),ex,FCallback); r := RunDataQuery (FSql,TDataSet(q),ex,FCallback);
//if r then begin
//if q.State=dsBrowse then begin
// WTF?
//end;
//end;
TMysqlQuery(FOwner).SetMysqlDataset(q); TMysqlQuery(FOwner).SetMysqlDataset(q);
if r then SetState (MQR_SUCCESS,'SUCCESS') if r then SetState (MQR_SUCCESS,'SUCCESS')
@ -280,46 +232,6 @@ begin
end; end;
end; end;
procedure TMysqlQueryThread.ReportStart();
var
qr : TThreadResult;
begin
qr := AssembleResult();
if FOwner <> nil then
TMysqlQuery (FOwner).PostNotification(qr,MQE_STARTED);
end;
procedure TMysqlQueryThread.ReportFinished();
var
qr : TThreadResult;
begin
qr := AssembleResult();
if FOwner <> nil then
TMysqlQuery (FOwner).PostNotification(qr,MQE_FINISHED);
end;
procedure TMysqlQueryThread.ReportInit();
var
qr : TThreadResult;
begin
qr := AssembleResult();
if FOwner <> nil then
TMysqlQuery (FOwner).PostNotification(qr,MQE_INITED);
end;
procedure TMysqlQueryThread.ReportFreed;
var
qr : TThreadResult;
begin
qr := AssembleResult();
if FOwner <> nil then
TMysqlQuery (FOwner).PostNotification(qr,MQE_FREED);
end;
function TMysqlQueryThread.RunDataQuery(ASql: WideString; function TMysqlQueryThread.RunDataQuery(ASql: WideString;
var ADataset: TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner): Boolean; var ADataset: TDataset; out AExceptionData : TExceptionData; callback: TAsyncPostRunner): Boolean;
var var
@ -364,7 +276,6 @@ begin
except except
On E: Exception do On E: Exception do
AExceptionData := GetExceptionData(E); AExceptionData := GetExceptionData(E);
//MessageDlg( 'SQL Error: '+ CRLF + E.Message, mtError, [mbOK], 0 );
end; end;
FreeAndNil (q); FreeAndNil (q);
@ -377,6 +288,7 @@ end;
procedure TMysqlQueryThread.SetState(AResult: Integer; AComment: String); procedure TMysqlQueryThread.SetState(AResult: Integer; AComment: String);
begin begin
debug(Format('qry: Setting status %d with comment %s', [AResult, AComment]));
FResult := AResult; FResult := AResult;
FComment := AComment; FComment := AComment;
end; end;

View File

@ -58,15 +58,11 @@ begin
begin begin
debug('qry: Setting running flag to ''true''.'); debug('qry: Setting running flag to ''true''.');
end; end;
MQE_STARTED:
begin
end;
MQE_FINISHED: MQE_FINISHED:
begin begin
debug('qry: Setting running flag to ''false'' and closing dialog.'); debug('qry: Setting running flag to ''false'' and closing dialog.');
Close(); Close();
end; end;
MQE_FREED:;
end; end;
end; end;