-
Content Count
3416 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Lars Fosdal
-
GetIt Package Manager Item buttons only partially visible
Lars Fosdal replied to PeterPanettone's topic in Delphi IDE and APIs
It could be that Windows 10 gives better scaling results than the ancient Windows 7, since it is better at dealing with multiple displays and varying DPI. -
Delphi compiler need to be opensourced
Lars Fosdal replied to AlekXL's topic in RTL and Delphi Object Pascal
I am totally for expanding FPC to cover everything Delphi can do and more. I would welcome it and applaud it. I don't think EMBT would mind, either. Giving up their own compiler is completely different thing. However, I don't believe FPC will ever catch up. Look at attributes which are still not supported. My Delphi code won't even compile on FPC, and that is not a EMBT problem. -
Delphi compiler need to be opensourced
Lars Fosdal replied to AlekXL's topic in RTL and Delphi Object Pascal
All of this is basically a fantasy. The odds that EMBT/Idera would consider doing it, are slim to none, IMO. -
I unabashedly summon the wisdom of @Uwe Raabe and hope he has some answers for me 🙂 I have a base class that wraps the to/from JSON conversion for me and also contain some other helper functions type TJsonElement = class public class function CreateFromJson<T: TJsonElement, constructor>(const aJson: string): T; class function LoadFromFile<T:TJsonElement, constructor>(const aFileName: String):T; class function PrettyFormat(const aJsonString: String; const AsHTML:Boolean = False; const UnEscapeJson:Boolean = False):String; function AsJsonString: string; end; And I am currently using TArray<T> to do lists, but it gets old writing helpers for each TArray<T> variation, so I'd like to do something like this and wrap a TArray to do all the chores of insert, add, clear, remove, delete, etc. once and for all I'd add these explicitly as methods of TJsonList. type TJsonList<T: TJsonElement, constructor> = class(TJsonElement) type JArray = TArray<T>; private FItems: JArray; function GetItem(Index: Integer): T; procedure SetItem(Index: Integer; const Value: T); public function Add: T; function Add(const aItem: T): T; procedure Remove(const aItem: T); // etc etc property Items{Index:Integer]: T read GetItem write SetItem; default; end; type TThing = class(TJsonElement) private Fprop: string; public property prop: string read Fprop write Fprop; end; // current way TThingArray = TArray<TThing>; TArrayContainer = class(TJsonElement) private Fthings: TThingArray; public property things: TThingArray read Fthings write Fthings; end; // new way TThingList = class(TJsonList<TThing>); TListContainer = class(TJsonElement) private Fthings: TThingList; public property things: TThingList read Fthings write Fthings; end; So, what is the problem? Assume that the two objects have been created and a couple of TThing elements added. TArrayContainer.ToJsonString will output { "things": [{ "prop": "A" }, { "prop": "B" }] } Without a converter/reverter, TListContainer.ToJsonString will output { "things": { "items": [{ "prop": "A" }, { "prop": "B" }] } } So, Challenge 1: Can I make a converter/reverter that will not output things as an object, but hide items and simply output an array of TThing? Challenge 2: Can I make the conversion override permanent, so that I don't have to use an attribute for every instance and descendant of TJsonList<T>?
-
Ok, Thanks for taking time to check it out!
-
Also - I guess a non-generic class inbetween will be needed for "is" checks. i.e. TJsonElement = class abstract ... end; TJsonList = class abstract (TJsonElement); TJsonList<T> = sealed class (TJsonList) ... end;
-
Updated JsonListTestCase.pas and removed the test data initialization from the constructor 😛 to make the restore test more credible. JsonListTestCase.pas
-
Yes - that is the goal. Remain compatible with the original format, but have reusable code for lists. In theory, it is probably better to have the internal type being a TObjectList<T> to get more functionality "for free". The conversion would break if you add other properties to the TJsonList<T> class - but I can safeguard against that f.x. by sealing the class etc. Test project attached (Note that the test classes does not do proper memory management on free). JsonListTest.dpr JsonListTestType.pas JsonListTestCase.pas Output: TTestArray Original: { "things":[ { "prop":"A1" }, { "prop":"B1" } ] } TTestArray Restored: { "things":[ { "prop":"A1" }, { "prop":"B1" } ] } TTestList Original: { "things":{ "items":[ { "prop":"A2" }, { "prop":"B2" } ] } } TTestList Restored: { "things":{ "items":[ { "prop":"A2" }, { "prop":"B2" } ] } } Press Enter: JsonListTestCase.zip
-
[Firedac] Truncation error on Firebird select query
Lars Fosdal replied to Jacek Laskowski's topic in Databases
@Dmitry Arefiev - Can you shine some light on this? Is it a bug or "as designed"? -
[Firedac] Truncation error on Firebird select query
Lars Fosdal replied to Jacek Laskowski's topic in Databases
That looks like a bug. Create a QP entry, perhaps? -
Delphi compiler need to be opensourced
Lars Fosdal replied to AlekXL's topic in RTL and Delphi Object Pascal
Regardless of closed or open source - the Delphi Windows compilers and debuggers need a significant overhaul - not to mention the insight background "compiling" - which IMO just as well could be using the actual compiler and background compilation. -
Rio 10.3.1 Debugger is often dead after a second build.
Lars Fosdal replied to David Szkilnyk's topic in Delphi IDE and APIs
I haven't seen this exact problem - but the debugger periodically stops working after a number of build/debug/edit/build cycles. Another issue that annoys me more, is that after debugging you have to compile again to have code completion work again. You don't even need a full compile, just Ctrl-F9 and Esc to interrupt it, and code completion is back in function. -
[Firedac] Truncation error on Firebird select query
Lars Fosdal replied to Jacek Laskowski's topic in Databases
I assume the problem does not happen if you trim :PARAM manually? Could it be that StrsTrim2Len only deals with insert/update parameterization and not selects? -
Wow, first time using repeat ... until
Lars Fosdal replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
The other day, I discovered that you can't use Exit() in a finally section. Needless to say, I had a second go at that code. -
My android app restarts on permission request
Lars Fosdal replied to Yaron's topic in Cross-platform
function SelectDirectory calls ForceDirectories, and there is no raise in the TDirectoryListBox class. Anyways - ForceDirectories can cause an exception under the specified circumstances - so the real question is: What is the content of PIKAFolder when it is passed to ForceDirectories, and - if not blank - what happens if the folder already exists? -
My android app restarts on permission request
Lars Fosdal replied to Yaron's topic in Cross-platform
Actually, http://docwiki.embarcadero.com/CodeExamples/Rio/en/DirListBoxUpdate_(C%2B%2B) says and a look at it in the source code verifies it. -
My android app restarts on permission request
Lars Fosdal replied to Yaron's topic in Cross-platform
Is there a risk that ForceDirectories can fail with an exception? /offtopic: Comparisons with boolean values make me cringe. -
A Curious Inheritance Problem... what pattern solves it?
Lars Fosdal replied to David Schwartz's topic in RTL and Delphi Object Pascal
@David Schwartz - What about vanilla FireDAC? Doesn't the FD drivers fully hide the differences between Oracle and PostgreSQL? -
A Curious Inheritance Problem... what pattern solves it?
Lars Fosdal replied to David Schwartz's topic in RTL and Delphi Object Pascal
@Remy Lebeau Yeah, that can be a good idea. Or, you do like we do, and have various custom query builder classes that produce a final string - which you then pass on. -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
I wonder when we will get nullable types. That will be awesome for DB related code. -
A Curious Inheritance Problem... what pattern solves it?
Lars Fosdal replied to David Schwartz's topic in RTL and Delphi Object Pascal
A rough draft from the top of my head. I've made the two query types look a little different from what they probably actually are to point out how the encapsulation hides the differences. Your actual wrapper will be different, and the number of methods that you need to wrap depends on the various TDataSet descendants and how you use them now. The wrapper exposes the properties and methods I need. type TxQuery<T: TDataSet> = class abstract private FiQuery: T; protected procedure SetSQL(aValue: string); ; virtual; abstract; function GetSQL: string; virtual; abstract; function GetDataSet: TDataSet; virtual; abstract; property iQuery: T read FiQuery write FiQuery; public procedure Execute; virtual; abstract; property SQL: string read GetSQL write SetSQL; property DataSet: TDataSet read GetDataSet; end TxQueryClass = class of TxQuery; TxOraQuery = class TxQuery<TOracleDataset> protected procedure SetSQL(aValue: string); override; function GetSQL: string; override; function GetDataSet: TDataSet; virtual; abstract; end; TxPgQuery = class TxQuery<TPgQuery> protected procedure SetSQL(aValue: string); override; function GetSQL: string; override; function GetDataSet: TDataSet; virtual; abstract; end; procedure TxOraQuery.SetSQL(aValue: string); begin iQuery.SQL.Text := aValue; end; function TxOraQuery.GetSQL: string; begin Result := iQuery.SQL.Text; end; function TxOraQuery.GetDataSet: TDataSet; begin Result := iQuery; end; procedure TxPgQuery.SetSQL(aValue: string); begin iQuery.SQL := aValue; end; function TxPgQuery.GetSQL: string; begin Result := iQuery.SQL; end; function TxPgQuery.GetDataSet: TDataSet; begin Result := iQuery.DataSet; end; type TForm1 = class(TForm) var QryClass: TxQueryClass; procedure FormCreate; procedure TestQuery(aQuery: TxQuery; aSQL: string); end; procedure TForm1.FormCreate; begin if Config = Pg then QryClass := TxPgQuery else QryClass := TxOraQuery; end; procedure TForm1.TestQuery; var Qry: TxQuery; SQL: string; begin Qry := QryClass.Create; Proc1(Qry, aSQL); end; procedure TForm1.Proc1(aQuery: TxQuery; aSQL: string); begin aQuery.DataSet.Close; aQuery.SQL := aSQL; aQuery.DataSet.Open; ... end; -
A Curious Inheritance Problem... what pattern solves it?
Lars Fosdal replied to David Schwartz's topic in RTL and Delphi Object Pascal
I'll get back to you on this, @David Schwartz Think base class, inheritance and encapsulation. -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
Thanks guys, Good observations. The dates in question are set to whatever FireDAC returns from a SQL Server datetime field, which typically appears to be 0 for NULL. The set date range is always in the future, relatively speaking. If the date is less than today, it is an expired dairy product by definition. We don't sell those 😉 I'll change the requirement for blank dates to be <= 1.0 to be on the safe side. -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
At least that confirms that I am not blind. EMBT has fumbled on the doc here. Too bad as I have I wanted to use a custom converter to take a Json stream that have a mixed type list and convert it to/from a single object in Delphi, but I didn't have the patience and aptitude to dig that deep. { "list": [ 5, "thing", {"object":"type"} ] } It is the Message structure from the Google+Exporter Json https://docs.google.com/document/d/1gOYJe61sI1GbO9qpFZJtwY3vdsZalsxtPgUnB2cvzAw/edit -
TJson - Strip TDateTime property where value is 0?
Lars Fosdal replied to Lars Fosdal's topic in Network, Cloud and Web
@Uwe RaabeThat is beautiful! But - where the heck is the documentation for this!?