Recent

Author Topic: TSQLDBlibraryloader fails @designtime  (Read 4333 times)

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
TSQLDBlibraryloader fails @designtime
« on: November 04, 2017, 02:58:22 pm »
I Put TSQLConnector and TSQLDBLibraryloader on form. Set property libraryname to the path of the clientlibrary. Then I set property enabled to true.
If I run the application, fpc comes with the error :
Quote
'..raised exception class EDatabaseError with the message:
SQLDBLibrayloader1: This operation is not allowed while the database is loaded.
Why is this happen? property TSQLConnector.connected is still set to false.

I know it can be fixed at runtime, but my demo requires this option @designtime. 
 
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

LacaK

  • Hero Member
  • *****
  • Posts: 691
Re: TSQLDBlibraryloader fails @designtime
« Reply #1 on: November 06, 2017, 07:39:49 am »
TSQLDBLibraryLoader message is not related to TSQLConnector.
Probably you have in your code: SQLDBLibrayloader1.Enbled := True; ? or any other use of SQLDBLibrayloader1 ?

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: TSQLDBlibraryloader fails @designtime
« Reply #2 on: November 06, 2017, 08:45:21 am »
Yes I did.
So what's the relation to TSQLConnector? I know it tells to the TSQLConnector where to find the required library. What's the purpose of the property enabled?
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: TSQLDBlibraryloader fails @designtime
« Reply #3 on: November 06, 2017, 09:38:15 am »
I looked into the source by property enabled:
Code: Pascal  [Select][+][-]
  1. procedure TSQLDBLibraryLoader.SetEnabled(AValue: Boolean);
  2. begin
  3.   if FEnabled=AValue then Exit;
  4.   if (csLoading in ComponentState) then
  5.     FEnabled:=AValue
  6.   else
  7.     If AValue then
  8.       LoadLibrary
  9.     else
  10.       UnloadLibrary;
  11. end;                    
  12.  
Does the clientlibrary has to be loaded before starting the connection to the database. What is TSQLconnector doing when the library already loaded?

I couldn't find any code to see what happens if TSQLConnector.connected is set to true.

There's also a problem with the IDE if the application is haved with TSQLDBloadlibrary.enabled := true.
When the project will loaded into the IDE, the IDE goes in a loop or it will fails when loading the TSQLDBloadlibrary.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: TSQLDBlibraryloader fails @designtime
« Reply #4 on: November 06, 2017, 09:50:11 am »
I couldn't find any code to see what happens if TSQLConnector.connected is set to true.
TSQLConnector inherits from TSQLConnection which in its turn inherits from TDatabase.

TSQLConnection (re)publishes the property Connected so we go up one ancestor to see what that does.

Code: [Select]
TDataBase: property Connected: Boolean read FConnected write SetConnected;

So we need to look at TDataBase.SetConnected() but alas, that one is implemented in (yet another one) its ancestor class TCustomConnection. so we take a look there:

Code: [Select]
procedure TCustomConnection.SetConnected(Value: boolean);

begin
  If Value<>Connected then
    begin
    If Value then
      begin
      if csReading in ComponentState then
        begin
        FStreamedConnected := true;
        exit;
        end
      else
        begin
        if Assigned(BeforeConnect) then
          BeforeConnect(self);
        DoLoginPrompt;
        DoConnect;
        if Assigned(AfterConnect) then
          AfterConnect(self);
        end;
      end
    else
      begin
      if Assigned(BeforeDisconnect) then
        BeforeDisconnect(self);
      DoDisconnect;
      if Assigned(AfterDisconnect) then
        AfterDisconnect(self);
      end;
    end;
end;

We take a look at DoConnect, which is virtual. We see that its child TDataBase does override DoConnect and reads:
Code: [Select]
procedure TDatabase.DoConnect;
begin
  DoInternalConnect;
  FConnected := True;
end;

So, there it calls DoInternalConnect. DoInternalConnect is overridden in the child classes. For TSQLConnector that reads:

Quote
procedure TSQLConnector.DoInternalConnect;

Var
  D : TConnectionDef;

begin
  inherited DoInternalConnect;
  CheckProxy;
  FProxy.CharSet:=Self.CharSet;
  FProxy.DatabaseName:=Self.DatabaseName;
  FProxy.HostName:=Self.HostName;
  FProxy.LogEvents:=Self.LogEvents;
  FProxy.Password:=Self.Password;
  FProxy.Role:=Self.Role;
  FProxy.UserName:=Self.UserName;
  FProxy.FTransaction:=Self.Transaction;
  FProxy.LogEvents:=Self.LogEvents;
  FProxy.OnLog:=Self.OnLog;
  FProxy.Options:=Self.Options;
  D:=GetConnectionDef(ConnectorType);
  D.ApplyParams(Params,FProxy);
  FProxy.Connected:=True;
end;

Note that Inherited DoInternalConnect is executed, so look at its parent's class implementation of DoInternalConnect as well.

That is, if i understood your question correctly.

edit: added some additional in-between steps
« Last Edit: November 06, 2017, 10:16:54 am by molly »

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: TSQLDBlibraryloader fails @designtime
« Reply #5 on: November 06, 2017, 12:21:49 pm »
Part of it Molly.

I tried to understand which relation TSQLDBLibraryloader has to TSQLConnector (TSQLConnection). If the libraryloader is loading the clientlibrary, what is TSQLConnector (TSQLConnection) doing with the loaded library. If this component is not available, TSQLConnector (TSQLConnection) handles the loading of the client library by itself (AFAIK). Why is loading my project failing when I use TSQLDBLibraryloader.enabled := true.
It's nice to know where you can find the procedures of the handled code, but is not my purpose.
Delphi and Lazarus/FPC are built to build a application in the IDE without a single code put by user.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: TSQLDBlibraryloader fails @designtime
« Reply #6 on: November 06, 2017, 01:08:59 pm »
Part of it Molly.
Was already afraid you was going to say that :-D

Databases are not my greatest virtue, and usually i set properties manually at runtime instead of design-time (so double my handicap  :D)

Quote
I tried to understand which relation TSQLDBLibraryloader has to TSQLConnector (TSQLConnection).
afaik, none whatsoever other then overriding some default behaviour (in particular the path and name of the library).

Quote
If the libraryloader is loading the clientlibrary, what is TSQLConnector (TSQLConnection) doing with the loaded library.
afaik the libraryloader is responsible for 'correcting' default behaviour that TSDQLConnection expresses. TSQLConnection and friends uses a default location (path) and name for the clientlibrary (.dll/.so) and this might not correspond to your (end-user)situation. Ergo Library loader let's you customize some (default) settings.

Quote
If this component is not available, TSQLConnector (TSQLConnection) handles the loading of the client library by itself (AFAIK).
afaik as well, yes.

Quote
Why is loading my project failing when I use TSQLDBLibraryloader.enabled := true.
No idea atm. The message you showed seem to indicate that the database/connection has already been opened ("database already loaded").

Quote
It's nice to know where you can find the procedures of the handled code, but is not my purpose.
Indeed it is not, but sometimes knowing the flow of the program is able to help you understand certain issues/topics. I assumed that is why you asked the question i quoted and replied to.

Quote
Delphi and Lazarus/FPC are built to build a application in the IDE without a single code put by user.
:)

Although you as a developer do not have to code anything when visually creating a design, behind the scenes a lot of code is executed (either at design-time or at execution time) because of the (visual) changes that you've made.

All the properties you've changed are stored inside the .lfm file and when you load your program (either at execution or designtime) these changes are streamed inside your program and therefor a lot of those changed properties invoke code (that you probably never knew existed before).

That is why (under certain circumstances) it is advisable to build lazarus/components in debug-mode so that you are able to debug the components source-code at runtime and be able to see what the debugger has to tell.

Note that afaik using libraryloader requires you to set properties in a particular order, otherwise things might go amiss (see also here). Did you follow the rules from that small example ? Also note that there are some libraryloader examples available in fpc source-tree.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: TSQLDBlibraryloader fails @designtime
« Reply #7 on: November 06, 2017, 02:59:36 pm »
I'm aware of the wiki part. But AFAIK it's a kind of workaround and not the solution to the GUI part.
I have to change my script, because it fails @desingtime.
Quote
Although you as a developer do not have to code anything when visually creating a design, behind the scenes a lot of code is executed (either at design-time or at execution time) because of the (visual) changes that you've made.
If a compagny gives you a vision to built something without any word of code typed, it should work. A newbie/beginner doesn't know anything about the exceptions.

But know this topic is almost offtopic. I shall be carefull for my answers :D

I hope that Lacak can explain why TSQLDBLibrary.enabled is not working as it should.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: TSQLDBlibraryloader fails @designtime
« Reply #8 on: November 06, 2017, 05:45:57 pm »
I'm aware of the wiki part. But AFAIK it's a kind of workaround and not the solution to the GUI part.
Currently a bit besides the question. To make sure (as you mentioned it in your first post as well): are you able to 'get rid of' the exception when you use runtime code ?

Quote
I have to change my script, because it fails @desingtime.
Yes, i am aware. Please don't worry about that  :)

Quote
A newbie/beginner doesn't know anything about the exceptions.
That is a bit of a contradictio in terminis. The exceptions are (also) there to help newbies understand errors in a better way, be able to locate them inside the source so that they can be addressed. I admit, some exceptions make more sense than others.

Also in this case, the error is clear. The problem lies in figuring out the 'why' part. I feel that some short example in order to reproduce the issue would be more helpful.

Quote
I hope that Lacak can explain why TSQLDBLibrary.enabled is not working as it should.
I'm currently blank as i seem unable to reproduce. So, any help from a more savvy user would be appreciated.

LacaK

  • Hero Member
  • *****
  • Posts: 691
Re: TSQLDBlibraryloader fails @designtime
« Reply #9 on: November 07, 2017, 08:28:37 pm »
I hope that Lacak can explain why TSQLDBLibrary.enabled is not working as it should.
:D
I will try.
First how TSQLDBLibraryLoader works was already answered I think. Simply say TSQLDBLibraryLoader loads appropriate library before any TSQLConnection tries open connection. When you look into code you will see that TSQLConnection will load library ONLY if none is already loaded. So if "somebody" loads library in advance TSQLConnection does nothing else uses already loaded library.

And why it does not work for you when you set Enabled at design time? Simply say you found a bug IMO ;-)
It is related to order how published properties are stored/read from LFM.
When you look into LFM you will see Enabled at first place then followed by ConnectionType and  LibraryName.
When component is loaded properties are set in order how they are stored in LFM.
And what is happening in TSQLDBLibraryLoader.SetCType and TSQLDBLibraryLoader.SetLibraryName ... CheckDisabled is called ...

I will contact author of component to confirm my suspection and will let you know ...
EDIT: Fixed already in revision: 37570
« Last Edit: November 07, 2017, 10:20:04 pm by LacaK »

 

TinyPortal © 2005-2018