Search code examples
delphidriverfirebirdfiredacdelphi-10.2-tokyo

Setting up a second TFDPhysFBDriverLink - possible and necessary?


My application has a design time TFDConnection and TFDPhysFBDriverLink as source connection. This may or may not be opened in Firebird embedded mode (if so, FDPhysFBDriverLink.VendorLib := 'fbembed.dll' is set (32 bits)).

I create a run-time target TFDConnection which must use embedded Firebird because we do not know if Firebird is installed on the PC (our setup supplies fbembed.dll).

How do I set this up? At runtime I can create another TFDPhysFBDriverLink and set its VendorLib, but how does FireDAC know what its associated connection is? Or can I use only one FDPhysFBDriverLink in the application?

This is old code I'm converting, using DirectSQL, and this also used to set some magic SDFib.SqlApiDLL := FBEMBED property, which supposedly worked for the target database only.


Solution

  • Worst case in your situation is that Firebird is installed, so one connection connects to that installed server instance whilst another to the embedded one. For that is enough to have one physical driver object, but there's no problem having more.

    So, drop one TFDPhysFBDriverLink on a form or datamodule and setup its DriverID property to a unique name (that is not used as base driver ID for any driver), and mark it as Embedded (that has no practical meaning in case when you specify VendorLib at this time, but you can use it to identify the driver; FireDAC uses this property only for decision which default library should be loaded).

    Then for one connection use DriverID that you defined and for the other one use fallback to default Firebird driver settings by using its BaseDriverID (I've omitted settings unecessary for this task):

    FDPhysFBDriverLink1.DriverID := 'FBEmbedded'; { ← ID not used by any BaseDriverID }
    FDPhysFBDriverLink1.Embedded := True; { ← not mandatory when VendorLib is specified }
    FDPhysFBDriverLink1.VendorLib := 'C:\fbembed.dll'; { ← client library file name }
    
    FDConnection1.Params.DriverID := 'FB'; { ← driver's BaseDriverID }
    FDConnection1.Open; { ← this will connect to the installed server }
    
    FDConnection2.Params.DriverID := 'FBEmbedded'; { ← driver's DriverID }
    FDConnection2.Open; { ← this will connect to the embedded server }
    

    But I would prefer having two separate driver objects, one for installed server (with default settings, like base driver has) and one for embedded server. For example:

    FDPhysFBDriverLink1.DriverID := 'FBEmbedded'; { ← ID not used by any BaseDriverID }
    FDPhysFBDriverLink1.Embedded := True; { ← not mandatory when VendorLib is specified }
    FDPhysFBDriverLink1.VendorLib := 'C:\fbembed.dll'; { ← client library file name }
    
    FDPhysFBDriverLink2.DriverID := 'FBInstalled'; { ← ID not used by any BaseDriverID }
    
    FDConnection1.Params.DriverID := 'FBEmbedded'; { ← driver 1 DriverID }
    FDConnection1.Open; { ← this will connect to the embedded server }
    
    FDConnection2.Params.DriverID := 'FBInstalled'; { ← driver 2 DriverID }
    FDConnection2.Open; { ← this will connect to the installed server }