David Schwartz 427 Posted March 15, 2023 (edited) 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 March 15, 2023 by David Schwartz Share this post Link to post
Stefan Glienke 2009 Posted March 15, 2023 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). 2 2 Share this post Link to post
David Schwartz 427 Posted March 15, 2023 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
Kryvich 165 Posted March 15, 2023 Even if this TListDataSet existed, I do not think that the proposed approach is optimal. Share this post Link to post
Attila Kovacs 629 Posted March 15, 2023 http://www.x-files.pl/components/xdbdata.html 1 Share this post Link to post
David Schwartz 427 Posted March 15, 2023 (edited) 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 March 15, 2023 by David Schwartz 1 Share this post Link to post
Kryvich 165 Posted March 15, 2023 @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
David Schwartz 427 Posted March 15, 2023 (edited) 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 March 15, 2023 by David Schwartz Share this post Link to post
Anders Melander 1795 Posted March 15, 2023 (edited) 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. Edited March 15, 2023 by Anders Melander 4 Share this post Link to post
Attila Kovacs 629 Posted March 15, 2023 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
Kryvich 165 Posted March 15, 2023 (edited) @David Schwartz If you need a ready to use solution, you may look at the answers to this question: https://stackoverflow.com/questions/9533760/how-can-i-get-a-dataset-of-in-memory-objects In particular, The Dduce library, TListDataSet<T>. Edited March 15, 2023 by Kryvich Share this post Link to post
Stefan Glienke 2009 Posted March 15, 2023 5 minutes ago, Kryvich said: In particular, The Dduce library. DDuce does not have a TListDataSet (anymore?) it uses TObjectDataSet from Spring4d 1 Share this post Link to post
David Schwartz 427 Posted March 15, 2023 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
Attila Kovacs 629 Posted March 15, 2023 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. 4 1 Share this post Link to post
dummzeuch 1506 Posted March 15, 2023 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.) 3 Share this post Link to post
David Schwartz 427 Posted March 15, 2023 (edited) 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 March 15, 2023 by David Schwartz 2 Share this post Link to post
Dalija Prasnikar 1399 Posted March 15, 2023 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. 1 Share this post Link to post
toms 29 Posted March 15, 2023 (edited) ChatGPT isn't limited to coding. Interesting video about GPT-4: Edited March 15, 2023 by toms Share this post Link to post
Attila Kovacs 629 Posted March 15, 2023 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
david berneda 19 Posted March 15, 2023 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
programmerdelphi2k 237 Posted March 15, 2023 (edited) 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 March 15, 2023 by programmerdelphi2k Share this post Link to post
Fr0sT.Brutal 900 Posted March 16, 2023 (edited) 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 March 16, 2023 by Fr0sT.Brutal Share this post Link to post
David Schwartz 427 Posted March 16, 2023 (edited) 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 March 16, 2023 by David Schwartz Share this post Link to post
Sherlock 663 Posted March 16, 2023 @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. 2 Share this post Link to post
Stefan Glienke 2009 Posted March 16, 2023 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. 3 Share this post Link to post