4

I work with Firebird and Delphi, I want to implement access via internet with wirecompression; But I am unable to activate it.

I have followed the steps inside this document for the new parameter(one of the few I was able to find) How to enable WireCompression on Firebird 3.0 using FireDAC

In the tests I use Windows server 2012 R2 Firebird : Firebird-3.0.4.33054_0_Win32(32 bits) Also copied to executable folder. fbclient.dll zlib1.dll (idem server and client) created firebird.conf with wirecompression=true. and I am giving wirecompression=true inside the Firedac of the application.

Why am I unable to activate the P15:CZ compression ?

Sending connection info for the example:
================================
Connection definition parameters
================================
DriverID=FB
Database=miservidor001:C:\sysdat\C100\gestdat03.fdb
User_Name=SYSDBA
PassWord=*****
WireCompression=true
================================
FireDAC info
================================
Tool = RAD Studio 10.2
FireDAC = 16.0.0 (Build 88974)
Platform = Windows 32 bit
Defines = FireDAC_NOLOCALE_META;FireDAC_MONITOR
================================
Client info
================================
Loading driver FB ...
Brand = Firebird
Client version = 300049900
Client DLL name = C:\APPS\WC01\fbclient.dll
================================
Session info
================================
Current catalog = 
Current schema = 
Server version = WI-V3.0.4.33054 Firebird 3.0
WI-V3.0.4.33054 Firebird 3.0/tcp (WIN-2012LAGO003)/P15:C
WI-V3.0.4.33054 Firebird 3.0/tcp (nucleo)/P15:C'
Arioch 'The
  • 15,799
  • 35
  • 62
gasaluy
  • 41
  • 2
  • Exactly how do you pass `WireCompression=true` to the client? A comment on https://stackoverflow.com/a/40886443/466862 says _"Adding wirecompression=true to the connection params do nothing, only adding it to firebird.conf take effect"_ (the firebird.conf read by the fbclient.dll that is!) – Mark Rotteveel Dec 27 '18 at 09:05
  • What do you mean by "created firebird.conf with wirecompression=true" ? You should not be *creating* Firebird configuration! You should be locating the only existing configuration file and EDITING it (and restarting Firebird after that). If you CREATED it on the server then it most probably lies in some stray place where Firebird Server would never ever look. – Arioch 'The Dec 27 '18 at 10:36
  • use SysInternals Process Monitor to ensure what file accesses your application makes: does it load the fbclient.dll, zlib1.dll and firebird.conf that you want it to load, or some other files, or not all of them ? – Arioch 'The Dec 27 '18 at 10:43
  • The `WireCompression=true` in the firebird.conf file is a client-only setting. If you change it in the `firebird.conf` of the server, it only affects the `on external datasource` connections made by the server (where the server acts as a client). Changing this setting on the server does not influence clients connecting to the server in any way (except when they read the same config file). – Mark Rotteveel Dec 27 '18 at 10:49

2 Answers2

5

NOTE: I don't know Delphi nor FireDAC, this answer is based on the general behavior of Firebird and my experience with maintaining its JDBC driver (Jaybird). So it is possible that there is a better answer specifically for FireDAC/Delphi.

Enabling or disabling wire compression is entirely determined by the client, not by the server. This means that configuration of the server is not necessary nor has it any effect, except in cases where the server itself acts as a client, for example with execute statement ... on external datasource.

To be able to use wire compression, you need three things:

  1. fbclient.dll
  2. zlib1.dll (in the same location as fbclient.dll, or on the search path)
  3. A configuration to enable wire compression for the client

Point 3 is likely your problem: I'm not sure if FireDAC has a connection property WireCompression that actually enables wire compression.

I know of two ways to enable wire compression for the client:

  1. Create a firebird.conf in the same directory as the fbclient.dll used by your application. In this configuration file, put the requested configuration options (one per line):

    WireCompression = true
    # maybe other config lines (eg AuthClient, WireCrypt, etc)
    
  2. Instead of creating a firebird.conf file, pass the configuration (with linebreaks separating config options) in the isc_dpb_config (int 87) database parameter item.

    The value is the same as the content of the firebird.conf file in the previous option. This may run into size issues if the client is using the old database parameter buffer format (where strings are max 255 bytes) and you want to pass (a lot) more config options.

Option 1 is probably the simplest and will work for all frameworks. Option 2 depends on whether or not the framework or driver exposes the database parameter buffer or if it has a connection property that maps to isc_dpb_config.

For example in Java using Jaybird, you can enable compression (only when using native connections) using:

Properties props = new Properties();
props.setProperty("user", "sysdba");
props.setProperty("password", "masterkey");
props.setProperty("config", "WireCompression=true");

try (var connection = DriverManager.getConnection(
        "jdbc:firebirdsql:native:localhost:D:/data/db/fb3/fb3testdatabase.fdb", props)) {

    FirebirdConnection fbCon = connection.unwrap(FirebirdConnection.class);
    FbDatabase fbDatabase = fbCon.getFbDatabase();
    System.out.println(fbDatabase.getServerVersion());

} catch (SQLException e) {
    e.printStackTrace();
}

This prints out WI-V3.0.4.33054 Firebird 3.0,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ (note this is <server version>,<server protocol info>,<client protocol info>). The Z in P15:CZ means that the connection is zlib compressed (the C that the connection is encrypted).

Here, the config property is an alias for isc_dpb_config.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
4

Mark's answer is the best (and probably the only) source of information about this problem in the entire internet. Good luck finding anything on Delphi, FireDAC or Firebird documentation about what he said.

Based on his answer, here is what you need to use Firebird wire compression with FireDAC:

  • You need Delphi Rio 10.3.1 (Update 1) or later. Only in this version the config low level parameter (see below) was added to FireDAC.

  • You must pass WireCompression=true to the low level config connection parameter. This is NOT TFDConnection.Params (high level).

    • To accomplish this you need to set the IBAdvanced property of TFDPhysFBConnectionDefParams to config=WireCompression=true (yeah! Go figure it!)

    • Code:

      FDConnection1.DriverName := '​FB';
      with FDConnection1.Params as TFDPhysFBConnectionDefParams do   
      begin
        Server := '...';
        Database := '...';
        UserName := '...';
        Password := '...';
        IBAdvanced := 'config=WireCompression=true';
      end;
      FDConnection1.Connected := True;
      
    • Using a connection definition file:

      [FB_Demo]
      DriverID=FB
      Server=...
      Database=...
      User_Name=...
      Password=...
      IBAdvanced=config=WireCompression=true
      
  • You need zlib1.dll in the same path of your fbclient.dll. The catch here is that Firebird distribution DOES NOT have the 32-bit version of zlib1.dll in its C:\Program Files\Firebird\Firebird_3_0\WOW64 folder. So:

    • If your application is 64-bit you are probably fine. Just use both fbclient.dll and zlib1.dll from your C:\Program Files\Firebird\Firebird_3_0 folder.

    • If your application is 32-bit you have to download the 32-bit version of zlib1.dll from the 32-bit Firebird distribution. Use it together with the fbclient.dll you find in your C:\Program Files\Firebird\Firebird_3_0\WOW64 (which contains 32-bit libraries).

In Firebird 3.0.4 or later you can use the WIRE_COMPRESSED context variable to check if the connection was established as you expected:

SELECT
  RDB$GET_CONTEXT('SYSTEM', 'WIRE_COMPRESSED') wire_compressed
FROM
  rdb$database

This will return TRUE if the current connection is compressed.

Shaun Roselt
  • 1,650
  • 5
  • 18
  • 44
F.D.Castel
  • 2,284
  • 1
  • 16
  • 15