Page 1 of 1
Get standard Library name
Posted: 29.12.2022, 12:56
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
Re: Get standard Library name
Posted: 30.12.2022, 12:38
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
Re: Get standard Library name
Posted: 02.01.2023, 10:43
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
Re: Get standard Library name
Posted: 02.01.2023, 12:19
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
Re: Get standard Library name
Posted: 02.01.2023, 22:20
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.
Re: Get standard Library name
Posted: 04.01.2023, 09:12
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;
Re: Get standard Library name
Posted: 05.01.2023, 04:44
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.
Re: Get standard Library name
Posted: 09.01.2023, 09:12
by Fr0sT
Maybe GetLoadedLibrary?
Re: Get standard Library name
Posted: 10.01.2023, 10:29
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 :)