Get standard Library name

The offical for ZeosLib 7.3 Report problems, ask for help, post proposals for the new version of Zeoslib 7.3/v8
Quick Info:
-We made two new drivers: odbc(raw and unicode version) and oledb
-GUID domain/field-defined support for FB
-extended error infos of Firebird
-performance ups are still in queue
In future some more feature will arrive, so stay tuned and don't hassitate to help
Post Reply
CharlyTango
Fresh Boarder
Fresh Boarder
Posts: 6
Joined: 20.10.2017, 14:41

Get standard Library name

Post by CharlyTango »

Hi,

in the example project ZControlsExample there is a possibility to fill a combobox with all supported protocols.

Code: Select all

procedure TMainForm.FormShow(Sender: TObject);
var
  I, J: Integer;
  Drivers: IZCollection;
  Protocols: TStringDynArray;
begin
  ZProtocol.Clear;
  Drivers := DriverManager.GetDrivers;

  for I := 0 to Drivers.Count - 1 do
  begin
    Protocols := (Drivers.Items[I] as IZDriver).GetSupportedProtocols;
    for J := 0 to High(Protocols) do begin
      ZProtocol.Items.Add(Protocols[J]);
     end;
  end;
  ZProtocol.Sorted := True;
end; 
And selecting the desired protocol was the only thing which was needed to connect to the database.
ZEOS obviously selected the right library name and also the correct bitness (32/64bit).

Could someone give me a hint how (and where in ZEOS) that is done or at least tell me how to get the standard name of a library determined by the selected protocol (under different operating systems).
ZEOS should at least tell me the library names by protocol.

Please put me on track ;-)
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Get standard Library name

Post by marsupilami »

Hello CharlyTango,

each driver has a list of library names which Zeos tries to load on request. These libraries are listed in the plain driver part of the driver. Taking MySQL as an example:
In ZPlainMySqlDriver.pas there is the following part:

Code: Select all

{$IFDEF MSWINDOWS}
  WINDOWS_DLL_LOCATION = 'libmysql.dll';
  WINDOWS_DLL41_LOCATION = 'libmysql41.dll';
  WINDOWS_DLL41_LOCATION_EMBEDDED = 'libmysqld41.dll';
  WINDOWS_DLL50_LOCATION = 'libmysql50.dll';
  WINDOWS_DLL50_LOCATION_EMBEDDED = 'libmysqld50.dll';
  WINDOWS_DLL51_LOCATION = 'libmysql51.dll';
  WINDOWS_DLL51_LOCATION_EMBEDDED = 'libmysqld51.dll';
  WINDOWS_DLL55_LOCATION = 'libmysql55.dll';
  WINDOWS_DLL55_LOCATION_EMBEDDED = 'libmysqld55.dll';
  WINDOWS_DLL56_LOCATION = 'libmysql56.dll';
  WINDOWS_DLL56_LOCATION_EMBEDDED = 'libmysqld56.dll';
  WINDOWS_DLL57_LOCATION = 'libmysql57.dll';
  WINDOWS_DLL57_LOCATION_EMBEDDED = 'libmysqld57.dll';
{$ELSE}
  LINUX_DLL_LOCATION = 'libmysqlclient'+SharedSuffix;
  LINUX_DLL41_LOCATION = 'libmysqlclient'+SharedSuffix+'.14';
  LINUX_DLL41_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.14';
  LINUX_DLL50_LOCATION = 'libmysqlclient'+SharedSuffix+'.15';
  LINUX_DLL50_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.15';
  LINUX_DLL51_LOCATION = 'libmysqlclient'+SharedSuffix+'.16';
  LINUX_DLL51_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.16';
  LINUX_DLL55_LOCATION = 'libmysqlclient'+SharedSuffix+'.18';
  LINUX_DLL55_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.18';
  LINUX_DLL56_LOCATION = 'libmysqlclient'+SharedSuffix+'.19';
  LINUX_DLL56_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.19';
  LINUX_DLL57_LOCATION = 'libmysqlclient'+SharedSuffix+'.20';
  LINUX_DLL57_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.20';
  LINUX_DLL58_LOCATION = 'libmysqlclient'+SharedSuffix+'.21';
  LINUX_DLL58_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.21';
{$ENDIF}
This part defines the library names to try when connecting to MySQL database. These constants get used upon construction of the relevant plain driver:

Code: Select all

constructor TZMySQLPlainDriver.Create;
begin
  inherited create;
  FLoader := TZNativeLibraryLoader.Create([]);
  FLoader.AddLocation(MARIADB_LOCATION);
  FLoader.AddLocation(DLL_LOCATION_EMBEDDED);
{$IFDEF MSWINDOWS}
  FLoader.AddLocation(WINDOWS_DLL_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL41_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL41_LOCATION_EMBEDDED);
  FLoader.AddLocation(WINDOWS_DLL50_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL50_LOCATION_EMBEDDED);
  FLoader.AddLocation(WINDOWS_DLL51_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL51_LOCATION_EMBEDDED);
  FLoader.AddLocation(WINDOWS_DLL55_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL55_LOCATION_EMBEDDED);
  FLoader.AddLocation(WINDOWS_DLL56_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL56_LOCATION_EMBEDDED);
  FLoader.AddLocation(WINDOWS_DLL57_LOCATION);
  FLoader.AddLocation(WINDOWS_DLL57_LOCATION_EMBEDDED);
{$ELSE}
  FLoader.AddLocation(LINUX_DLL_LOCATION);
  FLoader.AddLocation(LINUX_DLL41_LOCATION);
  FLoader.AddLocation(LINUX_DLL41_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL50_LOCATION);
  FLoader.AddLocation(LINUX_DLL50_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL51_LOCATION);
  FLoader.AddLocation(LINUX_DLL51_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL55_LOCATION);
  FLoader.AddLocation(LINUX_DLL55_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL56_LOCATION);
  FLoader.AddLocation(LINUX_DLL56_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL57_LOCATION);
  FLoader.AddLocation(LINUX_DLL57_LOCATION_EMBEDDED);
  FLoader.AddLocation(LINUX_DLL58_LOCATION);
  FLoader.AddLocation(LINUX_DLL58_LOCATION_EMBEDDED);
{$ENDIF}
  LoadCodePages;
end;
So while Zeos cannot tell you which libraries it uses, you can take a look at the library names it will try to use.

Best regards,

Jan
CharlyTango
Fresh Boarder
Fresh Boarder
Posts: 6
Joined: 20.10.2017, 14:41

Re: Get standard Library name

Post by CharlyTango »

Hi Jan,

thank you for your explanation.

I think it's great that ZEOS has such sophisticated functions to guess "missing" inputs.

However, I would like to know where and how to place the access libraries under Windows so that they are easily found by zeos.

It would also be nice to be able to determine which library is currently being used to see if the correct one is in use. Of course this would be more a function for an administrator or the programmer to see if everything is running correctly.

Regards,
Karl
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Get standard Library name

Post by marsupilami »

Hello Karl,
CharlyTango wrote: 02.01.2023, 10:43 However, I would like to know where and how to place the access libraries under Windows so that they are easily found by zeos.
There is no general rule for this. For most databases I suggest to place the libraries alongside the application and use the TZConnection property LibraryLocation. This will keep zeos from guessing and make it try one library only. Usually I distribute the client libraries along with my programs and have a subfolder for them. Something like:
MyProgram\
|-firebird-3.0\
| |-fbclient.dll
| |-...other files
|-MyProgram.exe
|-...other files
In the code of my program I usually do something like:

Code: Select all

procedure TMyDatamodule.OnCreate(Sender: TObject);
begin
  // some initialization code before these lines
  ZeosConnection.LibraryLocation := ExtractFilePath(ParamStr(0)) + 'firebird-3.0\fbclient.dll';
  // more code here
end;
Another idea is to load a library location from an ini file or from the registry.
CharlyTango wrote: 02.01.2023, 10:43 It would also be nice to be able to determine which library is currently being used to see if the correct one is in use.
If you go the above way, you know which library is in use because if you provide a library to use, Zeos will not try to load other libraries.

Best regards,

Jan
User avatar
aehimself
Zeos Dev Team
Zeos Dev Team
Posts: 765
Joined: 18.11.2018, 17:37
Location: Hungary

Re: Get standard Library name

Post by aehimself »

CharlyTango wrote: 02.01.2023, 10:43It would also be nice to be able to determine which library is currently being used to see if the correct one is in use.
It's actually possible, I even posted it on this forum a while ago. Can not find it atm, so here you go:

Code: Select all

If Assigned(ZConnection1.DbcConnection) And
    Assigned(ZConnection1.DbcConnection.GetIZPlainDriver) And
    Assigned(ZConnection1.DbcConnection.GetIZPlainDriver.GetInstance.Loader) Then
  WriteLn(GetModuleName(ZConnection1.DbcConnection.GetIZPlainDriver.GetInstance.Loader.Handle));
Edit:

This post.
Delphi 12.1, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmariadb.dll 3.3.8
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.13
- MSSQL 2012, 2019; sybdb.dll FreeTDS_2435
- SQLite 3.45.2
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1918
Joined: 17.01.2011, 14:17

Re: Get standard Library name

Post by marsupilami »

What do you think about adding that to the TZConnectionobject? Something like

Code: Select all

function TZAbstractConnection.GetLibraryInUse: String;
begin
  Result := '';
  if Active and 
    Assigned(DbcConnection) And
    Assigned(DbcConnection.GetIZPlainDriver) And
    Assigned(DbcConnection.GetIZPlainDriver.GetInstance.Loader) and
    (DbcConnection.GetIZPlainDriver.GetInstance.Loader.Handle <> 0)
  then
    Result := GetModuleName(ZConnection1.DbcConnection.GetIZPlainDriver.GetInstance.Loader.Handle);
end;
MJFShark
Expert Boarder
Expert Boarder
Posts: 211
Joined: 04.06.2020, 13:59

Re: Get standard Library name

Post by MJFShark »

I vote yes! I use a very similar version and it has always worked well. Mine also checks

Code: Select all

if Assigned(ZConn.DbcConnection.GetIZPlainDriver.GetInstance) then
But maybe that's not needed.
Fr0sT
Zeos Dev Team
Zeos Dev Team
Posts: 280
Joined: 08.05.2014, 12:08

Re: Get standard Library name

Post by Fr0sT »

Maybe GetLoadedLibrary?
User avatar
aehimself
Zeos Dev Team
Zeos Dev Team
Posts: 765
Joined: 18.11.2018, 17:37
Location: Hungary

Re: Get standard Library name

Post by aehimself »

MJFShark wrote: 05.01.2023, 04:44But maybe that's not needed.
Afaik it's unnecessary, as GetInstance returns a new instance. As long as there's a plain driver, you'll always get an instance.
I did not check the code right now, though so I might be wrong.

If anyone is about to add this please make sure that it will continue to work if we finally get rid of Zeos's notorious driver library caching :)
Delphi 12.1, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmariadb.dll 3.3.8
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.13
- MSSQL 2012, 2019; sybdb.dll FreeTDS_2435
- SQLite 3.45.2
Post Reply