Jump to content

PiedSoftware

Members
  • Content Count

    65
  • Joined

  • Last visited

Posts posted by PiedSoftware


  1. Rollo62: Yes, there is a way to see it like that. I can't think of another more theoretically pure place to put it, unless the datasources were all under some manager at the application level. But the fact is that both are declared in Data.DB, and TDataset already has a member variable of type FDataSources: TList<TDataSource> and property DataSource: TDataSource, used for setting indexes or something.

    • Like 1

  2. 15 hours ago, Patrick PREMARTIN said:

    Perhaps you can try to access it from a helper on TDataSet...

    I don't know if it has the right meaning though.

    And since in Delphi there can only be one helper, I would avoid that approach in case someone else had a better use for it.


  3. Here is the code when reduced in size because it works:

     

    type TLocalDataSource = class(TDataSource); // Exposes protected property DataLinks
    
    function GetDataAwareList(ds: TDataSource): TArray<TControl>;
    var lds: TLocalDataSource absolute ds;
        link: TDataLink;
        fldLink: TFieldDataLink absolute link;
    begin
      result := [];
      for link in lds.DataLinks do begin       // See, I told you
        if (link is TFieldDataLink) and (fldLink.Control is TControl) then begin
          result := result + [TControl(fldLink.Control)];
        end;
      end;
    end{ GetDataAwareList};

     


  4. Hi

     

    It seems like a natural thing to want: is there a way to get all the datasouces that have dataset = ADataset? Other than looping through the components property of the owner of course. 

     

    I was looking at the code of TDataset. It even has a private member variable FDatasources: TList<TDatasource>, but it is not exposed. So close!

    TIA

    Mark

    • Like 1

  5. Thanks for the thought, Uwe. I should have said I'm using Delphi 10.4. I tried this function:
     

    uses Vcl.DBCtrls, System.Generics.Collections, System.Classes;
    
    type TLocalDataSource = class(TDataSource);
    
    function GetDataAwareList(ds: TDataSource): TArray<TControl>;
    var lds: TLocalDataSource absolute ds;
        links: TList<TDataLink>;
        link: TDataLink;
        fldLink: TFieldDataLink;
        cmp: TComponent;
    begin
      result := [];
      links := lds.DataLinks;
      for link in links do begin
        if link is TFieldDataLink then begin
          fldLink := link as TFieldDataLink;
          cmp := fldLink.Control;
          if cmp is TControl then begin
            result := result + [TControl(cmp)];
          end;
        end;
      end;
    end{ GetDataAwareList};

    It keeps seizing in the middle there, no particular line, sometimes reading fldlink.Control, sometimes when adding it to the array. I've been hacking at that for a while, stretching it out with more local variables to make it finer grained, but it has never worked for me. 

    I'll just have to go ahead with code that is aware of what controls it needs to manage.

     

     

    EDIT: It seems that it does actually work. It was the debugger that was freezing. When I don't single step through it, it works fine.


  6. I just used claude for a while. I asked it to write a function to return the number of bytes in a string. It generated code that looked right, but I didn't check the unicode specs to confirm. But it had an error. It use a for i := loop but in the loop had inc(i) which of course does not compile. But I just told it that that wouldn't work and it replaced it with a while loop. Also it responded well to my style specifications, like having all the reserved words in lower case.

    I haven't tried others. Maybe DeepLink will be worth a look.

    I hope that helps.


  7. I keep getting messages from OneDrive that it is close to full (4.5GB of 5GB), with of course an offer for me to purchase more.  I went looking at at the folder and found that most of it (4.53 GB) is in C:\Users\Mark\OneDrive\Documents\Embarcadero\Studio

    Is there some process for making Delphi use some other folder for that and getting away from OneDrive? I'm concerned about the risk of corrupting my Delphi installation.

     

    Regards

    Mark


  8. On 9/25/2024 at 6:38 PM, David Heffernan said:

     

    Delphi doesn't know that you want [] to be an array rather than a set. Because the language has been designed iteratively and there is ambiguity. Delphi literals are a bit of a mess.

     

    In any case are you sure that you want to use = with a reference type? That's reference identity and not value identity.

      

    You will need to test for Length(a)=0 or not Assigned(a) or a = nil

    Thanks for thinking about it Dave. But ...
    It already knows the type of a to be an array, so a set interpretation is ruled out.
    And for arrays, nil and [] mean the same thing. That is why the assignment operator works. So, I think it is reasonable to expect the compile to test for equality with the same syntax.


  9. I like the way Delphi is getting better at arrays, but there is still a gap in the compiler that let me down. 

    I tried this code in 12.2 to highlight the issue.
     

    
    const nostrings: tarray<string> = [];
    
    procedure TForm1.FormShow(Sender: TObject);
    begin
      var a: tarray<string>;
      a := [];
      if a = nostrings then
        say('nostrings');
      if a = [] then
        say('it''s blank');
    end;
    
    procedure TForm1.say(const s: string);
    begin
      ListBox1.Items.Add(s);
    end;

    This refuses to compile at the line

     if a = [] then

    with the error "Incompatible types". But it has no problem with the assignment, so it looks like the programmers have just put this in the "do eventually" basket.

    Does anyone have any insights into this?

    --- Mark 

    • Sad 1

  10. On 7/11/2024 at 9:50 PM, David Heffernan said:

    Classic delphi type ambiguity consequence

    Yes, it would be much better if sets has a different punctuation from arrays. Sets came first though, and they got [ and ] on a first come first choose basis. If Delphi could yield { and } from comments and give it to arrays or sets, life would be better.


  11. type
      TCodeStructure = record
        StartTkn: string;
        EndTkn: string;
        SubTkns: array of string;
      end;
    
    type TIfTkns = (itElse, itElsif);
    
    const elseTkn  = '#else';
          elsifTkn = '#elseif';
          IfTkns: array[TIfTkns] of string = (elseTkn, elsifTkn);
    
      IfStruct: TCodeStructure =
        (StartTkn: '#if';
         EndTkn:   '#endif';
         SubTkns: [IfTkns[itElse], IfTkns[itElsif]]); 

    I wrote this code and got the error "E2026 Constant expression expected" on the last line.


    I also tried 

    SubTkns: IfTkns);

     

    When I changed it to 

    SubTkns: [elseTkn, elsifTkn]);

    it compiled happily.
    and that gave me E2010 Incompatible types: 'Dynamic array' and 'Array'.

    To me it seems that Delphi should allow the first thing I tried - referencing a const array via constant indices to specify a constant. There is no reason to disallow that sort of thing. Ideally even the second attempt should be reasonable.

    I have Delphi 10.4.


  12. 5 hours ago, Anders Melander said:

    Okay but it's installed in the IDE by default and it affects the design-time performance of forms and datamodules.

    Give a try; It's one of the first things I do when I install Delphi.

    I went to Component | Install Packages and unchecked "Embarcadero LiveBindings Components" and saved, but when I closed and reopened Delphi, it was back on again. D'oh! 

    I'm concerned the maybe a library is using it. How can I work that out? Should I remove it?


  13. 10 hours ago, corneliusdavid said:

    If it runs fine in debug mode but then you compile in release mode (which I think is what you mean), is there a conditional in your code that sets up the database connection differently for debug mode, like maybe you're using a local database for testing but the release mode one is connecting remotely for the customer?

    Thank. What I am comparing are the 2 functions from the Delphi Run menu: Run (f9) and Run without debugging (shift-ctrl-f9)


  14. 2 hours ago, corneliusdavid said:

    What version of Delphi? At runtime or design-time in the IDE?

     

    What database? What type of activity--I assume at least connecting?  Is it using the same connection in debug and release modes? Are the release and debug configs generating executable in different directories? Perhaps it loading a configuration from an .INI file which is in one location but not the other?

     

    After the form is loaded, does everything run fine (assuming this is at runtime)?

     

    There are so many things this could be--we need a little more information.

    Delphi 10.4

    MySQL, but I don't think that is the issue. I probably shouldn't have mentioned it. It was my first thought, I put timings in the code. The time is just the form getting created, with no database activity.
    It looks fine when it has loaded

     

    Yes, I know it's pretty diffuse. I haven't started pulling my hair out yet.


  15. Hi

     

    I have been trying to work out what is going on with one of my forms. Just opening it, which has only a small amount of DB activity, was taking nearly a minute in the debugger, once it was about 35s. But when I run it without the debugger it is less than 3 seconds. There is no obvious bottlenecks in Task Manager. I have 8 GB of RAM.

    Does this sound familiar to anyone? Does anyone have a possible solution?

    Regards
    Mark

×