Jump to content
David Schwartz

TO ChatGPT: In Delphi, is there any kind of an adapter or class that takes a TList<T> and makes it look like a TDataSet?

Recommended Posts

I've been asking ChatGPT (free version) lots of questions about Delphi and things that a lot of devs would have trouble answering, and I'm quite amazed at the responses I've been getting. I think StackOverflow has met its match! It even does a decent job of explaining what the code is doing.

 

Here's one I thought I'd share.

--------------------------------------------------

 

In Delphi, is there any kind of an adapter or class that takes a TList<T> and makes it look like a TDataSet?

 

[I had no idea there was such a thing as TListDataSet component in Delphi!]

 

Yes, you can use a TListDataSet component in Delphi to make a TList<T> look like a TDataSet.

Here's an example:

 

uses
  System.Classes, Data.DB, Datasnap.DBClient;

type
  TMyData = class
    // Define the fields in your class
    FField1: string;
    FField2: Integer;
    FField3: TDateTime;
    // Add more fields as needed
  end;

var
  MyList: TList<TMyData>;
  MyDataSet: TClientDataSet;
  MyListDataSet: TListDataSet;
begin
  // Assume MyList is already populated with data

  MyDataSet := TClientDataSet.Create(nil);
  try
    // Define the fields in the TClientDataSet
    MyDataSet.FieldDefs.Add('Field1', ftString, 50);
    MyDataSet.FieldDefs.Add('Field2', ftInteger);
    MyDataSet.FieldDefs.Add('Field3', ftDateTime);
    // Add more fields as needed

    MyDataSet.CreateDataSet;

    // Iterate through the TList<T> and add each item to the TClientDataSet
    for MyData in MyList do
    begin
      MyDataSet.Append;
      MyDataSet.FieldByName('Field1').AsString := MyData.FField1;
      MyDataSet.FieldByName('Field2').AsInteger := MyData.FField2;
      MyDataSet.FieldByName('Field3').AsDateTime := MyData.FField3;
      // Set more fields as needed

      MyDataSet.Post;
    end;

    // Create a TListDataSet and set it's DataSet property to the TClientDataSet
    MyListDataSet := TListDataSet.Create(nil);
    MyListDataSet.DataSet := MyDataSet;

    // Now you can use the TListDataSet like a regular TDataSet
    MyListDataSet.First;
    while not MyListDataSet.Eof do
    begin
      // Do something with the data
      MyListDataSet.Next;
    end;
  finally
    MyListDataSet.Free;
    MyDataSet.Free;
  end;
end;

 

In this example, we create a TClientDataSet and define the fields in the dataset to match the fields in TMyData. We then iterate through the TList<T> and add each item to the TClientDataSet. Finally, we create a TListDataSet and set its DataSet property to the TClientDataSet, allowing us to use the TListDataSet like a regular TDataSet.

 

Note that if your TMyData class uses properties instead of fields, you'll need to use the FieldByName method to set the field values in the TClientDataSet, like this:

MyDataSet.FieldByName('Field1').AsString := MyData.Field1;
MyDataSet.FieldByName('Field2').AsInteger := MyData.Field2;
MyDataSet.FieldByName('Field3').AsDateTime := MyData.Field3;
// Set more fields as needed

How can the fields be defined by using RTTI on the type of object in the list?

 

You can use Delphi's RTTI (Run Time Type Information) to automatically define the fields in a TClientDataSet based on the fields in your class. Here's an example:

 

uses
  System.Classes, System.Rtti, Data.DB, Datasnap.DBClient;

type
  TMyData = class
  private
    FField1: string;
    FField2: Integer;
    FField3: TDateTime;
  public
    property Field1: string read FField1 write FField1;
    property Field2: Integer read FField2 write FField2;
    property Field3: TDateTime read FField3 write FField3;
  end;

var
  MyList: TList<TMyData>;
  MyDataSet: TClientDataSet;
  MyListDataSet: TListDataSet;
  MyCtx: TRttiContext;
  MyType: TRttiType;
  MyProp: TRttiProperty;
  MyFieldDef: TFieldDef;
begin
  // Assume MyList is already populated with data

  MyDataSet := TClientDataSet.Create(nil);
  try
    // Use RTTI to define the fields in the TClientDataSet
    MyCtx := TRttiContext.Create;
    try
      MyType := MyCtx.GetType(TypeInfo(TMyData));
      for MyProp in MyType.GetProperties do
      begin
        MyFieldDef := MyDataSet.FieldDefs.AddFieldDef;
        MyFieldDef.Name := MyProp.Name;
        MyFieldDef.DataType := MyProp.PropertyType.HandleToFldType;
      end;
    finally
      MyCtx.Free;
    end;

    MyDataSet.CreateDataSet;

    // Iterate through the TList<T> and add each item to the TClientDataSet
    for MyData in MyList do
    begin
      MyDataSet.Append;
      // Use RTTI to set the field values in the TClientDataSet
      MyCtx := TRttiContext.Create;
      try
        MyType := MyCtx.GetType(TypeInfo(TMyData));
        for MyProp in MyType.GetProperties do
        begin
          MyFieldDef := MyDataSet.FieldDefs.Find(MyProp.Name);
          if Assigned(MyFieldDef) then
          begin
            MyDataSet.FieldByName(MyFieldDef.Name).Value := MyProp.GetValue(MyData).AsVariant;
          end;
        end;
      finally
        MyCtx.Free;
      end;

      MyDataSet.Post;
    end;

    // Create a TListDataSet and set it's DataSet property to the TClientDataSet
    MyListDataSet := TListDataSet.Create(nil);
    MyListDataSet.DataSet := MyDataSet;

    // Now you can use the TListDataSet like a regular TDataSet
    MyListDataSet.First;
    while not MyListDataSet.Eof do
    begin
      // Do something with the data
      MyListDataSet.Next;
    end;
  finally
    MyListDataSet.Free;
    MyDataSet.Free;
  end;
end;

 

In this example, we use TRttiContext and TRttiType to iterate through the properties of TMyData and define the corresponding fields in the TClientDataSet. We then use TRttiContext and TRttiProperty to iterate through the properties of each item in the TList<T> and set the corresponding field values in the TClientDataSet.

 

Note that this example assumes that the properties in TMyData have the same names as ...

 

It choked at this point, but the answer is fairly complete.

 

Curiously, I ran it again to get it un-stuck, and this time it came up with a slightly different take on defining the fields:

 

  MyDataSet := TClientDataSet.Create(nil);
  try
    // Use RTTI to define the fields in the TClientDataSet based on the properties of TMyData
    Ctx := TRttiContext.Create;
    try
      Typ := Ctx.GetType(TMyData);
      for Prop in Typ.GetProperties do
      begin
        FieldDef := MyDataSet.FieldDefs.AddFieldDef;
        FieldDef.Name := Prop.Name;
        case Prop.PropertyType.TypeKind of
          tkString, tkLString, tkWString, tkUString:
            FieldDef.DataType := ftString;
          tkInteger, tkInt64:
            FieldDef.DataType := ftInteger;
          tkFloat:
            FieldDef.DataType := ftFloat;
          tkEnumeration:
            FieldDef.DataType := ftBoolean;
          tkVariant:
            FieldDef.DataType := ftVariant;
          tkClass:
            if Prop.PropertyType.AsInstance.MetaclassType = TDateTime then
              FieldDef.DataType := ftDateTime;
          // Add support for more property types as needed
        end;
      end;
    finally
      Ctx.Free;
    end;

    MyDataSet.CreateDataSet;

 

 

Edited by David Schwartz

Share this post


Link to post
24 minutes ago, David Schwartz said:

[I had no idea there was such a thing as TListDataSet component in Delphi!]

Because there isn't (at least not in the RTL) - ChatGPT is making that up (as so often).

  • Like 2
  • Haha 2

Share this post


Link to post

 

 

2 minutes ago, Stefan Glienke said:

Because there isn't (at least not in the RTL) - ChatGPT is making that up (as so often).

HEHE ... I do know of something similar. 

 

I did ask this:

 

Where is TListDataSet found?

 

TListDataSet is part of the Data.DB unit in Delphi. It should be available in all recent versions of Delphi.

Note that TListDataSet is not a visual component, so you won't find it in the component palette. You'll need to create it in code, like this:

 

uses
  Data.DB;

var
  MyListDataSet: TListDataSet;
begin
  MyListDataSet := TListDataSet.Create(nil);
  try
    // Use the TListDataSet here...
  finally
    MyListDataSet.Free;
  end;
end;

Once you've created the TListDataSet, you can use it like a regular TDataSet.

 

-----------------------------------------------------------------

 

It seems to know a lot about something that doesn't exist. It makes me wonder how much proprietary / restricted / unpublished data this thing was trained with.

 

Share this post


Link to post

Even if this TListDataSet existed, I do not think that the proposed approach is optimal.

Share this post


Link to post
4 minutes ago, Kryvich said:

Even if this TListDataSet existed, I do not think that the proposed approach is optimal.

in what respect? I mean ... what kind of use-case are you thinking of?

 

I asked about this because I've got a bunch of JSON data (array of records) that I'm stuffing into objects added to a TList, and it seems the only way to get something I need is to use a DB-aware control to view them. So I need to get them into a dataset so they can be viewed. Then the whole thing gets thrown away.

 

So the choice is to go from JSON --> TDataSet or TList<T> --> TDataSet, both of which are dependent on the same issues:

 

How much time do you want to spend writing code that speeds this up by less than a second?

 

It's a little funny to me that all of this great technology we have at our fingertips is all rooted in stuff designed back in the 90's to support Client/Server database technology while today a large amount of our work centers around data shipped between servers as JSON packets, that's either parsed and used immediately or stuffed into classes, and is mostly transient and never intended to be put into any kind of structured DB.

 

There are even plenty of NO-SQL DBs available today to help manage this data.

 

Yet the most useful visual components are all driven off of TDataSets that are intended to be connected to databases.

 

DevEx grids are incredible, but last I saw, they're totally driven off of TDataSets and are useless for JSON data and lists of objects.

 

Edited by David Schwartz
  • Like 1

Share this post


Link to post

@David Schwartz 
The chain TList -> TClientDataSet -> TListDataSet is too long. It would be enough TList -> TClientDataSet. The client dataset is a dataset, so the problem is solved.

Share this post


Link to post
7 minutes ago, Kryvich said:

@David Schwartz 
The chain TList -> TClientDataSet -> TListDataSet is too long. It would be enough TList -> TClientDataSet. The client dataset is a dataset, so the problem is solved.

honestly, not having seen or heard of this TListDataSet, I couldn't really tell what it was doing there. 


TDataSets have a specific interface, much of which is navigational in nature. TLists have some navigation, and the nature of CRUD operations are different. So you'd need an adapter to make them behave more like TDataSets.

 

The one component I'm familiar with is more direct. 

Edited by David Schwartz

Share this post


Link to post
1 hour ago, David Schwartz said:

I've been asking ChatGPT (free version) lots of questions about Delphi and things that a lot of devs would have trouble answering, and I'm quite amazed at the responses I've been getting. I think StackOverflow has met its match! It even does a decent job of explaining what the code is doing.

image.png.5d7debebb83d71968d8fc38626a04601.png

Edited by Anders Melander
  • Haha 4

Share this post


Link to post
1 hour ago, David Schwartz said:

It makes me wonder how much proprietary / restricted / unpublished data this thing was trained with.

None. It's a language robot. The content is always made up, even if it's accidentally true.

I asked to show me the implementation of TListDataSet and it was like ListDataSet: TClientDataSet;

 

Share this post


Link to post
5 minutes ago, Kryvich said:

In particular, The Dduce library.

DDuce does not have a TListDataSet (anymore?) it uses TObjectDataSet from Spring4d 

  • Like 1

Share this post


Link to post

Ya know ... it's easy to dismiss things that it does as mistakes or just stuff it makes up, but to me they represent inferences that point to other things to look into. This is actually something I can personally relate to, as a lot of things I say get dismissed as nonsense. A lot of them turn out to be pretty damned accurate later on... I chalk this up to Asperger's. Not sure if it's a blessing or a curse.

 

Anyway I asked ChatGPT to show the code for that non-existent TListDataSet and ... if you've got a paid account, it might generate an entire unit. With the free account, it kept quitting about half-way through the code. 


 

Share this post


Link to post

That's what I was talking about. AI won't kill us in the way you have seen it in the television. It will kill us with wrong answers.

  • Like 4
  • Haha 1

Share this post


Link to post
25 minutes ago, Attila Kovacs said:

That's what I was talking about. AI won't kill us in the way you have seen it in the television. It will kill us with wrong answers.

That would be suicide not murder, because wrong answers kill only if the answer is accepted without any critical thought at all.

(OK, it would probably kill about 90% of all people. Fair enough.)

  • Haha 3

Share this post


Link to post

The problem isn't the source of the information. It's how the information is being used and framed / portrayed.

 

Anybody who has been following what's going on with the defamation suits from Dominion and Smartmatic against Fox, their management team, and their on-air lying sacks of sh*t, can see how the people running Fox are clearly targeting viewers who have such flawed critical thinking skills that they'll fall for anything the talking heads on Fox say as long as it fits a particular pattern of communication or point of view.

 

I have a friend who's retired, and all he watches on TV is Fox. I called him to ask if he'd make me a small loan for a few days and he said "sure, but I need to get cash." I said, "Why? What's wrong with Zelle?" He said, "Haven't you heard? The IRS is coming after anybody who uses payment things like Zelle for sending more than $600 to ANYBODY! I don't want to deal with the IRS over a stupid loan like this!" I thought, "Oh, boy, I guess this is the latest crock of BS that Fox is scaring people about this week..." He's on Social Security and doesn't even file a tax return because he doesn't earn enough, and yet he's worried about getting audited by the IRS because of nonsense Fox is blathering on about this week to make Biden look bad. It's pretty hard to deal with people who can't even break down the most simple things they hear or read in the media as they may or may not apply to them! 

 

Now we've got ChatGPT that is, in all likelihood, far more accurate and less biased than Fox, and yet people are up in arms over the mistakes it seems to be making. Sure, I've found several. But Dominion and Smartmatic are very likely to get default judgments against Fox to the tune of nearly $4 billion for the mountain of evidence their lawsuit discovery processes have shown that Fox exec and talking heads have engaged in a steady practice of telling lies to their viewers in order to boost their ratings and profits. Period. And the people who make the most noise about ChatGPTs errors probably don't even realize Fox is FAR less reliable and truthful -- nor will they even accept that as a possibility.

 

 

There was a book published in 1976 by Joseph Wesienbaum called "Computer Power and Human Reason". He was the founder of MIT's AI Lab. At one point in the book, he said he was asked by a reporter something like this: "What is it that humans can do that judges, psychologists, and other experts can do that computers cannot do?" His response was, "the question is what we as humans should allow or not allow computers to do that humans do."

 

I have not found that particular quote, but here are some others I found onilne:

 

https://www.goodreads.com/author/quotes/496834.Joseph_Weizenbaum

Edited by David Schwartz
  • Like 2

Share this post


Link to post
55 minutes ago, David Schwartz said:

t's easy to dismiss things that it does as mistakes or just stuff it makes up, but to me they represent inferences that point to other things to look into.

It is fine if you find ChatGPT useful for something. But just because it is useful to you, does not mean it is useful to others. 

  • Like 1

Share this post


Link to post

ChatGPT isn't limited to coding. Interesting video about GPT-4:
 

 

Edited by toms

Share this post


Link to post
1 hour ago, dummzeuch said:

That would be suicide not murder, because wrong answers kill only if the answer is accepted without any critical thought at all.

The problem is that you don't even realize whether a human or an AI is serving you, and we will rely on them for more and more decision making.

Share this post


Link to post
5 hours ago, David Schwartz said:

in what respect? I mean ... what kind of use-case are you thinking of?

 

I asked about this because I've got a bunch of JSON data (array of records) that I'm stuffing into objects added to a TList, and it seems the only way to get something I need is to use a DB-aware control to view them. So I need to get them into a dataset so they can be viewed. Then the whole thing gets thrown away.

 

So the choice is to go from JSON --> TDataSet or TList<T> --> TDataSet, both of which are dependent on the same issues:

 

How much time do you want to spend writing code that speeds this up by less than a second?

 

It's a little funny to me that all of this great technology we have at our fingertips is all rooted in stuff designed back in the 90's to support Client/Server database technology while today a large amount of our work centers around data shipped between servers as JSON packets, that's either parsed and used immediately or stuffed into classes, and is mostly transient and never intended to be put into any kind of structured DB.

 

There are even plenty of NO-SQL DBs available today to help manage this data.

 

Yet the most useful visual components are all driven off of TDataSets that are intended to be connected to databases.

 

DevEx grids are incredible, but last I saw, they're totally driven off of TDataSets and are useless for JSON data and lists of objects.

 

If you need a Grid fmx/vcl to connect to TList of records etc, TeeGrid does it, without TDataset: https://github.com/Steema/TeeGrid-VCL-FMX-Samples/tree/master/demos/VirtualData/TList

 

 

Share this post


Link to post

this can help you?  https://github.com/viniciussanchez/dataset-serialize

 

Sample:  https://raw.githubusercontent.com/viniciussanchez/dataset-serialize/master/img/img-02.png

Quote

DataSet Serialize is a set of features to make working with JSON and DataSet simple.

It has features such as exporting or importing records into a DataSet, validate if JSON has all required attributes (previously entered in the DataSet), exporting or importing the structure of DataSet fields in JSON format.

In addition to managing nested JSON through master detail or using TDataSetField (you choose the way that suits you best).

All this using class helpers, which makes it even simpler and easier to use.

 

Edited by programmerdelphi2k

Share this post


Link to post

Memory table? I believe all serious DB-aware libs have it. However, clientdataset sample looks nice as well. It now is able to store data? Last time I touched it it was just a dataset API wrapper requiring many boilerplate code to function

Edited by Fr0sT.Brutal

Share this post


Link to post

Y'all seem to have missed the point -- this is what people are using StackOverflow for most of the time, and most of that code isn't any better than what ChatGPT produces. 

 

The biggest difference is there are a bunch of smartypants mods on SO who are constantly flagging crappy code, correcting obvious errors, and making tons of commentary about the code, the poster, and each other's comments.

 

It's interesting how this thread looks so similar to a typical SO post.

 

 

 

Edited by David Schwartz

Share this post


Link to post

@David Schwartz But that is exactly the point: ChatGPT just blurts out unchecked stuff someone might naively use and if it compiles ... ships it. No matter what happens then. And that is simply unacceptable and dangerous, no matter how fascinating (or in my case not) on may consider the subject.

  • Like 2

Share this post


Link to post
4 hours ago, David Schwartz said:

Y'all seem to have missed the point -- this is what people are using StackOverflow for most of the time, and most of that code isn't any better than what ChatGPT produces. 

 

The biggest difference is there are a bunch of smartypants mods on SO who are constantly flagging crappy code, correcting obvious errors, and making tons of commentary about the code, the poster, and each other's comments.

 

It's interesting how this thread looks so similar to a typical SO post.

I think we are down to the real issue here: one's own personality.

 

I rather filter out some ego-stroking to get good peer-reviewed advice than some untested garbage but I know people that are already offended when you say: "Sorry, but there is a slight possibility of you being not 100% correct here" (actually meaning: you could not be more wrong). People with a personality like that are usually the ones complaining about SO. I am worried that their solution is using AI-provided help that is completely unchecked and will turn into the software that runs the world in the future.

  • Like 3

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×