Recent

Author Topic: 'treat private like protected'  (Read 2770 times)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
'treat private like protected'
« on: October 26, 2022, 01:12:41 pm »
Can we get an option for that? So we can fix bugs and extend the functionality of existing classes, without having to modify the FPC source code and make a merge request?

As an example, I want to expand the TSQLConnector to pass the TSQLite3Connection.OpenFlags. But the encapsulated TSQLConnection object (FProxy) is private, so that's a no-go.
« Last Edit: October 26, 2022, 01:17:33 pm by SymbolicFrank »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: 'treat private like protected'
« Reply #2 on: October 26, 2022, 02:01:20 pm »
Interesting. But I'm probably doing it wrong:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSpecialConnector = class(TSQLConnector)
  3.   protected
  4.     procedure DoInternalConnect; override;
  5.   end;
  6.  
  7.   TConnectionAccessor = class
  8.   public
  9.     FProxy: TSQLite3Connection;
  10.   end;
  11.  
  12. implementation
  13.  
  14. procedure TSpecialConnector.DoInternalConnect;
  15. begin
  16.   if ConnectorType = 'SQLite3' then
  17.     TConnectionAccessor(Self).FProxy.OpenFlags :=
  18.       [sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  19.   inherited DoInternalConnect;
  20. end;

This gives the compile error:

Code: [Select]
tablefunctions.pas(1473,5) Error: Class or Object types "TSpecialConnector" and "TConnectionAccessor" are not related

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: 'treat private like protected'
« Reply #3 on: October 26, 2022, 03:19:05 pm »
?
Code: Pascal  [Select][+][-]
  1. TConnectionAccessor = class(TSpecialConnector)
  2.   public
  3.     FProxy: TSQLite3Connection;
  4.   end;

EDIT: Related to your other thread:
Have you tried by checking the ConnectionDef of the FProxy?
FProxy is a TSQLConnection, but you could try casting it
AIRCODE
Code: Pascal  [Select][+][-]
  1. procedure TSpecialConnector.DoInternalConnect;
  2. begin
  3.   if ConnectorType = 'SQLite3' then
  4.     TSQLite3Connection(Self).FProxy.OpenFlags :=
  5.       [sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  6.   inherited DoInternalConnect;
  7. //blablabla....
  8.  
and i was under the impression one should call the inherited Method first in this case...
Code: Pascal  [Select][+][-]
  1. procedure TSQLConnector.DoInternalConnect;
  2.  
  3. Var
  4.   D : TConnectionDef;
  5.  
  6. begin
  7.   inherited DoInternalConnect;
  8.   CheckProxy;
  9.   FProxy.CharSet:=Self.CharSet;
  10.   FProxy.DatabaseName:=Self.DatabaseName;
« Last Edit: October 26, 2022, 03:31:04 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: 'treat private like protected'
« Reply #4 on: October 26, 2022, 03:24:24 pm »
Also keep in mind: https://wiki.freepascal.org/FPC_New_Features_3.0.0#Class_field_reordering

Quote
Since the internal memory layout of a class is opaque
In other words, whatever works now (with current FPC versions), it may stop work with any upcoming FPC version. (By either this, or by other optimizations / even by changes that aren't optimizations).

Quote
this optimization may be moved to level -O2
While FPC 3.0.0 only does this in -O4, it is already announced to come to -O2 (and we are past 3.0.0 ...)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: 'treat private like protected'
« Reply #5 on: October 26, 2022, 04:07:10 pm »
?
Code: Pascal  [Select][+][-]
  1. TConnectionAccessor = class(TSpecialConnector)
  2.   public
  3.     FProxy: TSQLite3Connection;
  4.   end;

That gives an 'invalid type cast' runtime error. I'm not sure, but I was under the impression that if you introduce a field with the same name of an inaccessible one, it creates a new field. But it's hard to find the documentation for that.

Quote
EDIT: Related to your other thread:
Have you tried by checking the ConnectionDef of the FProxy?
FProxy is a TSQLConnection, but you could try casting it
AIRCODE
Code: Pascal  [Select][+][-]
  1. procedure TSpecialConnector.DoInternalConnect;
  2. begin
  3.   if ConnectorType = 'SQLite3' then
  4.     TSQLite3Connection(Self).FProxy.OpenFlags :=
  5.       [sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  6.   inherited DoInternalConnect;
  7. //blablabla....
  8.  

Well, yes, but I cannot access FProxy, so far. The above code generates the 'not related' or 'invalid typecast' error, depending.

Quote
and i was under the impression one should call the inherited Method first in this case...
Code: Pascal  [Select][+][-]
  1. procedure TSQLConnector.DoInternalConnect;
  2.  
  3. Var
  4.   D : TConnectionDef;
  5.  
  6. begin
  7.   inherited DoInternalConnect;
  8.   CheckProxy;
  9.   FProxy.CharSet:=Self.CharSet;
  10.   FProxy.DatabaseName:=Self.DatabaseName;

Ok, I'll try that as soon as I can set those OpenFlags.

But it's possible I don't understand what I'm doing.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: 'treat private like protected'
« Reply #6 on: October 26, 2022, 04:08:44 pm »
Also keep in mind: https://wiki.freepascal.org/FPC_New_Features_3.0.0#Class_field_reordering

Quote
Since the internal memory layout of a class is opaque
In other words, whatever works now (with current FPC versions), it may stop work with any upcoming FPC version. (By either this, or by other optimizations / even by changes that aren't optimizations).

Quote
this optimization may be moved to level -O2
While FPC 3.0.0 only does this in -O4, it is already announced to come to -O2 (and we are past 3.0.0 ...)

Or, a hack like the above ones isn't going to keep on working, if I can get it functioning at all.

Back to the drawing board.

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: 'treat private like protected'
« Reply #7 on: October 26, 2022, 04:32:45 pm »
This compiles
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses Sysutils, Classes, sqldb, sqlite3conn;
  3.  
  4. Type
  5.  
  6.   { TMyConnector }
  7.   TMyConnector = Class(TSQLConnector)
  8.     Protected
  9.       FProxy:TSQLConnection;
  10.   end;
  11.  
  12.   { TMyHelper }
  13.  
  14.   TMyHelper = Class helper for TMyConnector
  15.     Public
  16.       Procedure SetOpenFlags;
  17.   end;
  18.  
  19. { TMyHelper }
  20.  
  21. Procedure DoSomethingElse;
  22. Begin
  23. End;
  24.  
  25. procedure TMyHelper.SetOpenFlags;
  26. begin
  27.   If ConnectorType='SQLite3' Then
  28.     TSQLite3Connection(FProxy).OpenFlags:=[sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  29.   If ConnectorType='MySQL' Then DoSomethingElse;
  30. end;  
  31.  
  32. begin
  33. end.
  34.  
« Last Edit: October 26, 2022, 04:36:23 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: 'treat private like protected'
« Reply #8 on: October 26, 2022, 04:44:40 pm »
It does :)

But it gives the error below:

Tomorrow I'll look further.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: 'treat private like protected'
« Reply #9 on: October 26, 2022, 05:57:58 pm »
As an example, I want to expand the TSQLConnector to pass the TSQLite3Connection.OpenFlags. But the encapsulated TSQLConnection object (FProxy) is private, so that's a no-go.
May be
Code: Pascal  [Select][+][-]
  1. uses SQLDB, SQLite3Conn;
  2.  
  3. type
  4.   TSpecialConnector = class(TSQLConnector)
  5.   protected
  6.     procedure CreateProxy; override;
  7.   end;
  8.  
  9. procedure TSpecialConnector.CreateProxy;
  10. begin
  11.   inherited;
  12.   if Proxy is TSQLite3Connection then
  13.     TSQLite3Connection(Proxy).OpenFlags := [sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  14. end;

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: 'treat private like protected'
« Reply #10 on: October 27, 2022, 08:57:34 am »
This compiles and works. No Idea about "SCHEMA HAS CHANGED"
Code: Pascal  [Select][+][-]
  1. program project1;
  2. Uses Sysutils, Classes, sqldb, sqlite3conn;
  3.  
  4. Type
  5.  
  6.   { TMyConnector }
  7.   TMyConnector = Class(TSQLConnector)
  8.     Protected
  9.       Procedure SetOpenFlags;
  10.   end;
  11. Var
  12.   cn1,cn2:TMyConnector;
  13.   ta1,ta2:TSQLTransaction;
  14.   qr1,qr2:TSQLQuery;
  15. Procedure DoSomethingElse;
  16. Begin
  17. End;
  18.  
  19. procedure TMyConnector.SetOpenFlags;
  20. begin
  21.   If ConnectorType='SQLite3' Then
  22.     TSQLite3Connection(Proxy).OpenFlags:=[sofReadWrite, sofCreate, sofFullMutex, sofSharedCache];
  23.   If ConnectorType='MySQL' Then DoSomethingElse;
  24. end;
  25.  
  26. begin
  27.   cn1:=TMyConnector.Create(Nil);
  28.   cn1.ConnectorType:='SQLite3';
  29.   cn1.DatabaseName:='test.db';
  30.   ta1:=TSQLTransaction.Create(Nil);
  31.   cn1.Transaction:=ta1;
  32.   qr1:=TSQLQuery.Create(Nil);
  33.   qr1.DataBase:=cn1;
  34.   qr1.Transaction:=ta1;
  35.   cn1.SetOpenFlags;
  36.   cn1.Open;
  37.   cn1.ExecuteDirect('CREATE TABLE IF NOT EXISTS "tbl_test" ("ID" INT, "SomeText" TEXT);');
  38.   ta1.commit;  
  39.   qr1.free;
  40.   ta1.free;
  41.   cn1.free;
  42. end.
Thanks to Serge i noticed i missed, that there is a (Public?) Property "Proxy" (Not FProxy!)
« Last Edit: October 27, 2022, 09:00:56 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: 'treat private like protected'
« Reply #11 on: October 27, 2022, 01:15:42 pm »
Can I ask a supplementary question here please. I've got a vague recollection from the comparatively early Delphi days that one could "surface" something hidden in an ancestor class simply by redefining it with lower protection: is this accurate and if so what was its applicability... protected to public?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: 'treat private like protected'
« Reply #12 on: October 27, 2022, 01:48:00 pm »
Can I ask a supplementary question here please. I've got a vague recollection from the comparatively early Delphi days that one could "surface" something hidden in an ancestor class simply by redefining it with lower protection: is this accurate and if so what was its applicability... protected to public?

This is documented behaviour for properties (but afaik not for fields)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: 'treat private like protected'
« Reply #13 on: October 27, 2022, 02:19:04 pm »
Do you have any references for that? I've been looking via Google with limited success.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: 'treat private like protected'
« Reply #14 on: October 27, 2022, 02:48:59 pm »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018