-
Content Count
3323 -
Joined
-
Last visited
-
Days Won
110
Posts posted by Lars Fosdal
-
-
-
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.
-
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 -
-
We chose to do wrapper classes that further abstract the actual database types away from our code. Hence, in our code, there is no difference between running a BDE wrapped ADO connection and a FireDAC connection.
Those classes use old school encapsulation to hide such differences from our code with very little overhead.
- 1
-
Thanks! Neither suggestion is "perfect", but that gives me something to work with.
I wonder how expensive it would be to do suggestion 1 for every structure that I use?
There are supposed to be ways to plug in validators and converters for TJson & family, but the documentation is non-existent, and I don't want to take time to reverse engineer it all.
-
Consider this pseudo code
uses Rest.Json; TDateClass = class private FHasDate: TDateTime; FNoDate: TDateTIme; public constructor Create; property HasDate: TDateTime read FHasDate write FHasDate; property NoDate: TDateTime read FNoDate write FNoDate; end; constructor TDateClass.Create; begin HasDate := Now; NoDate := 0; end; var Json: String; DateClass: TDateClass; begin DateClass := TDateClass.Create; Json := TJson.ObjectToJsonString(Self, [joIgnoreEmptyStrings, joIgnoreEmptyArrays, joDateIsUTC, joDateFormatISO8601]);
which results in the Json string looking like
{ "HasDate":"2019-02-14T06:09:00.000Z", "NoDate":"1899-12-30T00:00:00.000Z", }
while the ideal result would be
{ "HasDate":"2019-02-14T06:09:00.000Z", }
Q:Is there a way to make TDateTime properties with a zero value be output as an empty string - and hence be stripped?
-
We do all data change via SPs of which some do not do explicit transaction handling.
The current SP call handling will detect if the call was a deadlock victim and rerun it if necessary - but that basically escalates the risk of yet another deadlock.
The bigger sites have nearly a hundred pickers - so the odds for concurrent access = inevitable.
We need to identify where we do not need exclusive access and explicitly use NoLock where appropriate.
We need to identify where transactions will be feasible / required.We need to identify a best practice for resource allocation.
The challenge is that the rules are complex and the dataset is dynamic (pallets are emptied and replaced many, many times during a day).
f.x. get the best pick position for n items of article x with date requirement y which has the best fit for our pick route and least incoming traffic.
To further complicate it, different clients have different rules for date requirements due to longer transports or specific rules per article for shorter requirements due to high turnover. The list of these varying parameters go on and on.If two clients make the same request at the same time - one has to be the winner of what may be a scarce resource, while the other needs a viable plan b.
The pick request may consume the remaining items on one pallet, and then grab the rest from the next pallet - if there is one.To further complicate it, the allocation may need to be split onto multiple deliveries to multiple clients within the pick order.
What is blatantly clear is that we currently are not doing it the optimal way.
-
-
Debugger improvements were on the most recent roadmaps, wasn't they?
-
17 hours ago, Remy Lebeau said:In some piece of code somewhere, a pointer was set to $DEADBEEF, most likely after the object it was pointing to had been freed, and then that same pointer was used afterwards by code running at address $0040CEEC trying to access a data member at offset -8 ($DEADBEE7) via that pointer. Magic addresses like $DEADBEEF are commonly used for debugging such mistakes.
[deletia]
1Excellent analysis, Remy.
As I often do, I did not ask the right question - which should have been: What sets dead memory references to $DEADxxxx? RTL? EurekaLog? OS?
-
It would have been so nice if the Tabs menu had been sorted by most recently used on top!
-
-
The question is: Which programmer?
What raises the AV? -
Also spotted: Read of address DEADC00B.
Normally I'd expect to see things like this
EUseAfterFreeError: Application made attempt to call method of already deleted object: $071EC5A0 OBJECT [TMyClass] 404 bytes. -
Does anyone recognize that seemingly hardcoded address?
The call stack indicates that it happens in Rio 10.3.1 source - but searching the source does not yield anything.
Can it be Eurekalog that tries to tell me something about referencing a deleted or inaccessible piece of memory?
#BAD: EAccessViolation: Access violation at address 0040CEEC in module 'MyApp.exe'. Read of address DEADBEE7. DBServer\INDUSTRIELL\DBName # 3017235 20.03.2019 13:23:06 (Brukerinterface, CRITICAL) MyApp_ClientId @ [0040CEEC] System._UStrAsg __________ CallStack [0040CEEC] System._UStrAsg [01561AF4] System.Generics.Collections.pas.{GridSet}TGridSet.TFieldValue<System.string>.SetValue (Line 4745, "System.Generics.Collections.pas") [0156241F] System.Generics.Collections.pas.{GridSet}TGridSet.TFieldValue<System.string>.CopyRow (Line 4745, "System.Generics.Collections.pas") [01558452] GridSet.TGridSet.CopyRow (Line 1002, "GridSet.pas") [01B92885] frmPSDExpeditionDeliveries2.TDeliverySet.UpdateFromDeliverySet (Line 4108, "frmPSDExpeditionDeliveries2.pas") [01B8F919] frmPSDExpeditionDeliveries2.TDeliveryGrid.RefreshByRouteList (Line 3671, "frmPSDExpeditionDeliveries2.pas")
-
On 3/16/2019 at 2:40 PM, jobo said:- handling the «grabbing» might be easier, quicker, more robust, if handled by a single, atomic Grab Stored Procedure (considering the denormalisation)»
That's why I'd like to find an SQL group to get some hints to best practices
- which version is in use?
2008r2, 2012, 2016
- could you elaborate «..the actual grabbing is totally void of transactions..» please?
Some of the current code does not do explicit transaction handling at all.
- or describe the workflow a little?
That would become very detailed, very quickly2 -
Ref. paths and VCS systems...
We use standard pathsC:\SomeFolder\Projects
Common
ThisCollection
ThatCollection
ExternalLib1
Lib2
Proj1
Proj2We also use a $BIN environment var to direct the project outputs. Allows the team members great freedom for where to put their source, and where to direct the output.
and try to ensure that all project search or include paths are on this form ..\Common\ThisCollection
Those are stored in the .dproj which can be committed to the VCS.That also allows me to check out various versions
Projects <- my typical working branch switched between trunk/pilot/live
Projects.Rio <- while still on Tokyo, but testing Rio
Projects.Trunk
Projects.Pilot
Projects.Live
- 1
-
Somewhat off topic, but related.
Ctr+-F12 gives you a list of units to open, and I assumed it was from the search paths and project paths,Turns out that it also will look at the .dpr uses statement.
Ideally, the paths should be relative...
uses
SomeUnit in '..\RelativeFolder\SomeUnit.pas'
But, I had a stale test project in my project group where the uses path used an explicit path
uses
SomeUnit in 'c:\Obsolete.Path\to\RelativeFolder\SomeUnit.pas'
So, pressing Ctrl+F12 gave me both of these - even if Obsolete.Path didn't exist.
- 1
-
On 3/12/2019 at 12:44 PM, Hans J. Ellingsgaard said:There is at NOLOCK isolationlevel, that will minimize risk of locking, but it will not be suitable, if there is a risk of data being changed during the execution of the query. Another thing to do is to make sure that all the fields in the where clause and the joins are indexed to avoid tablescans.
4I usually limit NOLOCK to queries for
- data that is used as viewing info (i.e. not acted upon)
- data that are currently in the custody of the client (i.e. not likely to be changed by other processes) -
21 hours ago, azrael_11 said:I plan in the future to be multi platform so what is the best way to do that?
Thank you.
For Windows, the norm would be to install the font. AddFontResource could be used, but as you demonstrated, it doesn't seem to work as intended?
For MacOS, I would also assume that installing the font is recommended.
I've not used custom fonts with FMX on Android or iOS, so I can't answer that.- 1
-
21 hours ago, Rudy Velthuis said:That is something that needs to be addressed too, certainly, but it would not be on the top of my list.
I literally do that failing Generics Ctrl-Click several times a day. I guess I am a slow learner 😛
I also wish that the Insight mechanism would deduce the most likely class types in scope and let me select one as jump target, and not ALWAYS send me to the virtual/abstract declarations of the base class.
-
31 minutes ago, Sherlock said:Have you been hiding in a cave? 😄
Virtually, yes. Seriously busy days atm.
Themed IDE = Lipstick on pig.
I just deadlocked the IDE while trying to abort a compile/run - F9 then Escape -> Not responding.
-
2 minutes ago, Silver Black said:Altready installed IDEFixPack?
1Is there a FixPack for 10.3.1 ?
- 1
A Curious Inheritance Problem... what pattern solves it?
in RTL and Delphi Object Pascal
Posted
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.