5.3. How to execute a query in another thread?
All metadata providers inherit the following methods to support asyncronous query execution:
// returns true if this metadata provider is capable to create copies of Connection objects function SupportAsyncExecSql:boolean; virtual; // methods to create and free a copy of Connection object: function CreateConnectionCopy(AOwner: TComponent): TCustomConnection; virtual; procedure FreeConnection(AConnection: TCustomConnection); virtual; // event is fired after creation of each copy of Connection object property OnCustomizeConnectionCopy: TacConnectionEvent; // asyncronous query execution methods: function SupportAsyncExecSql: boolean; virtual; function CreateSqlAsync(ATag:TObject):IacAsyncSql; // creates and executes a query asyncronously and returns unidirectional readonly dataset function ExecSQLDatasetURAsync(const ASQL:WideString; AParams:TParams=nil):IacAsyncSql; virtual;
The simplest way to create a copy of connection and asyncronously execute a query (unidirectional, readonly) against it, is to call the ExecSQLDatasetURAsync method. If you want to execute a query in another way, you should call the CreateSqlAsync method and tune the properties of the IacAsyncSql interface returned by this method.
A copy of connection that's created inside the ExecSQLDatasetURAsync and CreateSqlAsync methods has the same values of all published properties as the original connection object, but sometimes it's needed to perform additional tuning of connection for it's proper functioning. For example, this might be needed to specify database password that was not initially defined in connection properties. To fix this, you can define a handler for the OnCustomizeConnectionCopy event and tune the connection properties the way you need.
The IacAsyncSql interface provides the following properties and methods:
property Sql: WideString; property Params: TParams; property ReturnResults: boolean; property Unidirectional: boolean; property ReadOnly: boolean; property MetadataProvider: TacBaseMetadataProvider; property Connection: TCustomConnection; property Dataset: TDataset; procedure Run; property State: TacTaskState; // TacTaskState=(actCreated, actRunning, actCompleted, actCanceled, actFaulted); property CanCancel: boolean; function Cancel:boolean; // cancels the query property Exception: Exception; // read it if the query state is actFaulted function Wait(ATimeout:Cardinal=INFINITE):boolean; // The OnStarting and OnStopped events property OnStarting: TNotifyEvent; property OnCompleted: TNotifyEvent; property OnFaulted: TNotifyEvent; property OnCanceled: TNotifyEvent; property OnStopped: TNotifyEvent;