Search code examples
delphifiredac

Delphi FireDAC query execution tracing not working with connection object created by component


I created a vcl component which uses firedac to access a PostgreSQL database. This works fine, except for query tracing, which I cannot get to work.

In component constructor, I create connection object, set params etc. In the uses clause, I added FireDAC.Phys.PG and FireDAC.Moni.Base, FireDAC.Moni.FlatFile.

Following the embarcadero docs, the TFDMoniFlatFileClientLink is created before the TFDConnection, and tracing is set to true for both the FDTracer and the FDConnection.ConnectionIntf.

unit My.Database;

interface

uses
  System.SysUtils, System.Classes, FireDAC.Comp.UI, FireDAC.Comp.Client, FireDAC.Phys.PG,
  FireDAC.Moni.Base, FireDAC.Moni.FlatFile;

type
  TMyDatabase = class(TComponent)
  private
    { Private declarations }
    FDTracer: TFDMoniFlatFileClientLink;
    FDConnection: TFDConnection;
    FConnectionString: string;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function IsConnected: Boolean;
    property ConnectionString: stringread FConnectionString write FConnectionString;
    function OpenConnection: Boolean;
    function GetAsDataset(ASQL: string): TFDQuery;
  end;

implementation

uses
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.Stan.Def, FireDAC.Stan.Async,
  FireDAC.VCLUI.Login, FireDAC.VCLUI.Wait;

constructor TMyDatabase.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FDTracer := TFDMoniFlatFileClientLink.Create(Self);
  FDConnection := TFDConnection.Create(Self);

  FDTracer.tracing := True;  

  with FDConnection do
  begin
    DriverName := 'PG';
    LoginPrompt := False;

    //params for PostgreSQL
    with Params do
    begin
      Add('Port=5432');
      Add('LoginTimeout=2');
      Add('Pooled=False');
      Add('OidAsBlob=No');
      Add('UnknownFormat=BYTEA');
      Add('ExtendedMetadata=True');
    end;
  end;

  FDConnection.ConnectionIntf.Tracing := True;
end;

function TMyDatabase.IsConnected: Boolean;
begin
  Result := FDConnection.Connected;
end;

function TMyDatabase.OpenConnection: Boolean;
begin
  with FDConnection do
  try
    ConnectionString := FConnectionString;

    if not Connected then
    begin
      Open;
    end;
  finally
    Result := Connected;
  end;
end;

function TMyDatabase.GetAsDataset(ASQL: string): TFDQuery;
begin
  Result := TFDQuery.Create(Self);

  with Result do
  begin
    Connection := FDConnection;
  end;

  Result.Open(ASQL);
end;

When I connect to a database and execute a query via GetAsDataSet, the trace file only logs the starting/stopping of the FireDac connection, but not the execution of the query. If I put the TFDConnection and TFDMoniFlatFileClientLink components on a form or datamodule, query execution is traced as expected.

Anyone who knows how to trace the execution of a query with a connection object that is created dynamically from a component?

Best regards, Ronald


Solution

  • I tried to reproduce your problem in a simple FireDAC testbed of mine, by adding a TFDMoniFlatFileClientLink to it and got a similar result, i.e. the trace file contained entries saying that it had been started and stopped, but nothing in between.

    Looking at http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FireDAC.MoniLayerClients_Sample I seemed to be missing a small but vital step, namely to set the MonitorBy parameter of my FDConnection to 'FlatFile', to match the TFDMoniFlatFileClientLink

    So, just before opening the connection in my code, I added the first line below

      FDConnection1.Params.MonitorBy := mbFlatFile;
      FDConnection1.Connected := True;
    

    and the trace then ran fine.

    Partial trace extract

      --- new start of FireDAC Trace ---
      4361928750001 19:48:07.092 -=#!!! FireDAC Tracer started !!!#=-
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           TFDPhysMSSQLConnecti  . CreateConnection [ConnectionDef=""]
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           TFDPhysMSSQLConnecti  . CreateTransaction [ConnectionDef=""]
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1        >> Open [ConnectionDef=""]
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                >> Definition [Name=""]
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . Server=MAT430\ss2014
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . User_Name=sa
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . Password=*****
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . Database=MAtest
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . OSAuthent=No
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . DriverID=MSSQL
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                     . MonitorBy=FlatFile
      4361928750001 19:48:07.094 TFDConnectionDef                 $0100C390                << Definition [Name=""]
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1            >> FireDAC info
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1                 . Tool=RAD Studio 10.2
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1                 . FireDAC=16.0.0 (Build 88974)
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1                 . Platform=Windows 32 bit
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1                 . Defines=FireDAC_NOLOCALE_META;FireDAC_MONITOR
      4361928750001 19:48:07.094 TFDPhysMSSQLConnection           FDConnection1            << FireDAC info
      4361931710001 19:48:07.390 TFDPhysMSSQLConnection           FDConnection1             . SQLDriverConnect [szConnStr="DRIVER=SQL Server Native Client 11.0;UID=sa;PWD=*******;Server=MAT430\ss2014;Database=MAtest;Trusted_Connection=No;MARS_Connection=yes"]
      4361931710001 19:48:07.392 TFDPhysMSSQLDriver               MSSQL                     . ENTER SQLDriverConnectW
          HDBC                0x01044B18
          HWND                0x00000000
          WCHAR *             0x61942440 [      -3] "******\ 0"
          SWORD                       -3
          WCHAR *             0x61942440
          SWORD                       -3
          SWORD *             0x00000000
          UWORD                        0 <SQL_DRIVER_NOPROMPT>
    
      4361935310001 19:48:07.756 TFDPhysMSSQLDriver               MSSQL                     . EXIT  SQLDriverConnectW  with return code 1 (SQL_SUCCESS_WITH_INFO)
          HDBC                0x01044B18
          HWND                0x00000000
          WCHAR *             0x61942440 [      -3] "******\ 0"
          SWORD                       -3
          WCHAR *             0x61942440 <Invalid buffer length!> [-3]
          SWORD                       -3
          SWORD *             0x00000000
          UWORD                        0 <SQL_DRIVER_NOPROMPT>
    
          DIAG [01000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Changed database context to 'MAtest'. (5701)
    
          DIAG [01000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Changed language setting to us_english. (5703)
    
      4361935310001 19:48:07.758 TFDPhysMSSQLDriver               MSSQL                     . ENTER SQLGetDiagRecW
          SQLSMALLINT                  2 <SQL_HANDLE_DBC>
          SQLHANDLE           0x01044B18
          SQLSMALLINT                  1
          SQLWCHAR *          0x00FCB5CC
          SQLINTEGER *        0x0019F840
          SQLWCHAR *          0x0019D83A
          SQLSMALLINT               4096
          SQLSMALLINT *       0x0019F846
    

    followed by the remainder of the kitchen sink.