Jump to content

Lars Fosdal

Administrators
  • Content Count

    3303
  • Joined

  • Last visited

  • Days Won

    110

Everything posted by Lars Fosdal

  1. Lars Fosdal

    Null value for T

    TRec<T> = record value: T; procedure Init; end; procedure TRec<T>.Init; begin Value := Default(T); end; TRec<Integer> = record value: Integer; // Default(T) = 0 end; TRec<TObject) = record value: TObject; // Default(T) = NIL end; // Assuming nullables would look like the C# equivalents TRec<Integer?> = record value: Integer?; // Default(T) = NULL end; TRec<TObject?) = record value: TObject?; // Default(T) = NULL end; For nullable object references - will we have a non-NULL that is nil? I guess the C# solution makes sense, although there is a difference between NULL (never assigned) and nil ( known non-reference assigned).
  2. Lars Fosdal

    Best way to refresh static data

    You know me. I am always in a state of bewilderment 🙂 Based on your updated sync requirements description, I'll stop envisioning a new generation of your system, and instead tell you about how I solved a similar need for synchronization. I did distributed stock, energy and weather market data databases for well over a decade. The solution was database agnostic and the central server generated change instructions - which technically were binary scripts for adding, changing or removing data. The change scripts were sequenced in chronological order by changes done at the central server, so that to do a refresh, the client requested an update from the last synch point, and then convert the list of change instructions to operations relevant to the local database. The change instruction format remained unchanged even though the underlying databases changed from flat files, to client side Paradox, to server side sql over a tcp connection. I still shudder at the memory of having terabytes of Paradox tables that I couldn't touch except through the change instructions 😛 Today, these data would have been retrieved through a REST interface.
  3. I liked the good old RESTful Web Services by Leonard Richardson and Sam Ruby on O'Reilly Media - although it is a bit web-centric. It is indeed complex. Some times peek/poke is the right way, while at other times you do want structured "batch" updates. The design needs to be governed by the nature of the API usage, the amount of concurrent use, the complexity of the data.
  4. Lars Fosdal

    Null value for T

    This is going to get interesting if we get nullable generic types.
  5. Lars Fosdal

    Best way to refresh static data

    If you have thousands of documents related to a case - how many of those would be opened in the same sitting? If you are able to reach the server at any time, I would synchronize the catalog only and pull the documents on demand to an MRU cache You could even keep MFU statistics to pre-load the most frequently used docs at first connect. Personally, I would consider having it all server-side with a web UI. Then again - this is the kind of problem that Office 365 and SharePoint really excels at - including tried and tested security models from all angles.
  6. Lars Fosdal

    Delphi in the UK

    C# is not completely alien for a Delphi dev, once you get past the begin/end abstinence and operator learning curve. It is also low cost to learn - since you get the tools more or less for free (unless you need the heavy hitter stuff).
  7. Lars Fosdal

    Best way to refresh static data

    I have fallen into the trap of underestimating the complexity of cross-database code before. It is no walk in the park. Each database has numerous functions / best practices that go beyond "standard" SQL. Consider MS SQL's FileStream vs Oracle SecureFile / LOBs. The first is documented for FireDAC, the second is not. Do you need to encrypt the traffic between the client and the server? FireDAC SQL Server driver supports encryption. No mention of it in the Oracle FireDAC doc, or the PostgreSQL FireDAC doc. Off-topic: Down the line, you may need to support Azure, AWS, Oracle Cloud, etc. Just curious: Why must the documents be downloaded? Due to usage requirements in locations without network access?
  8. Lars Fosdal

    Best way to refresh static data

    Given that various databases have significantly different ways of storing files and optmize queries, I would hide the access behind a REST service. I'd go so far as to have entirely separate services for the various databases I needed to support. That would make it possible to do compression in a generic way, not having to rely on the database capabilities. It also would allow the client to be "ignorant" of the database specifics - and allow you to do changes and optimizations server-side without having to change the client.
  9. Lars Fosdal

    Best way to refresh static data

    In a good database, the cost of complicated where statements usually is limited once you have tweaked your indexes. Not sure you can get away from those where statements if the client will be receiving NEW rows once every now and then. Not sure how good Postgre is with temp tables., but in MS SQL you could write your existing id array to a temp table, and do a join query. Probably more efficient than trying to match thousands of IDs in an IN statement.
  10. Lars Fosdal

    Dynamic creation of SQL queries

    @aehimself Just a thought. You may need to support "as" naming to handle duplicate field names in table joins or IsNull code. select aStrField, IsNull(aIntField, 0) as aIntField from aTable Without the as - the aIntField will not be named in the result set - at least not for MS SQL. Then there is the question of count, max, min, and so forth... Once you open for custom queries - you basically open a can of feature requests 😉
  11. Lars Fosdal

    Why can't I install this monospaced font in Delphi ?

    I still haven't found anything that beats Adobe Source Code Pro
  12. Lars Fosdal

    In-App Clipboard

    A bit of Googling dug up http://delphidabbler.com/articles?article=9 with src https://bitbucket.org/delphidabbler/article-9-demo/src/master/ which demos the basics - but you'd still need to do the checks to figure out what is relevant to your own app.
  13. Lars Fosdal

    In-App Clipboard

    I haven't seen one, but I haven't really been looking for one. I guess you have these links already... https://docs.microsoft.com/en-gb/windows/win32/dataxchg/clipboard https://docs.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-setclipboardviewer
  14. Lars Fosdal

    Pimlico: Microservices in Delphi - Part 1

    Friends don't make friends use Synchronize.
  15. Lars Fosdal

    Bug in Delphi string behavior?

    Not the programming error - the possible need for a hint or a warning that helps a programmer avoid the error.
  16. Lars Fosdal

    Bug in Delphi string behavior?

    QP it, perhaps?
  17. Lars Fosdal

    Bug in Delphi string behavior?

    Would it make sense to have a compiler hint for referencing initialized variables with an out parameter?
  18. Lars Fosdal

    Bug in Delphi string behavior?

    It is actually documented: http://docwiki.embarcadero.com/RADStudio/Rio/en/Parameters_(Delphi)#Out_Parameters Hence, since the const argument contains the same reference...
  19. Lars Fosdal

    Bug in Delphi string behavior?

    procedure TForm1.AnsiUpperTest; var s, o:string; begin s:='default'; AnsiUpperTestConvert(s,o); end; Adding a separate output variable helps. Can it be that the const DefaultValue is cleared by the out reference? Alternatives: Use a var param or a function result.
  20. YMMV, by a LOT. We don't use data-aware controls at all, but do all the DB work behind the scenes and pass custom classes to the UIs. These classes have methods to retrieve themselves from the DB, save themselves, as well as various processing methods, and we use helper/proxy-classes to simplify populating the UI as well as taking input from the UI. The source of the data doesn't matter to the UI, and we found it easier to have absolute control over the UI behavior and data updates and creation. Our UIs are much more than CRUD interfaces, as the data types are very complex and interdependent, as well as manipulated from multiple systems. But - in the end - we do a lot of explicit "wiring" in code in the UI proxies. For other solutions, data-aware components can work perfectly, but TBH, I've only worked with one solution that used them, and they had written an entire ORM to handle their data retrieval and input from DB to UI and back,
  21. Lars Fosdal

    Writing DLL functions unit

    Without documentation about the parameters of these functions and their types, you will be unlikely to succeed.
  22. Lars Fosdal

    Squint and read: CreateFormFromStings

    Mine too, especially when I've written the semantically correct word, but the compiler barfs because the actual word in the code is misspelled.
  23. https://larsfosdal.blog/2019/08/06/generic-command-line-parser-for-delphi-10-3-x/ I wrote an open source command line parser for Delphi. https://gist.github.com/LarsFosdal/f8a3e2a7caa5e541e4c04f10dfdfcfff Feedback appreciated.
  24. Lars Fosdal

    Generic Command Line Parser for Delphi 10.3.x

    The parser only deals with the parsing of a basic syntax. The interpretations of the validity of variations of switches, flags and arguments still has to be built on top of the base parser. I decided not to write those parts, as there are so many (potentially conflicting) ways to write it. It should be easy to add that layer yourself, though.
  25. Lars Fosdal

    Generic Command Line Parser for Delphi 10.3.x

    Double (or multiple) switch chars work. But - as mentioned: the syntax for multiple arguments to an option is (arg1, arg2, ..., arg n) If you need the separator as part of a string, you quote the string. (art1, "this , is in arg2", 'this has a " in it') Parse(' --strings="String A, StringB,StringC, String D and E"') 1 Switch[--] Option[strings] Flag[=] Values["String A, StringB,StringC, String D and E"] AsString('strings'): String A, StringB,StringC, String D and E
×