Jump to content

Arnaud Bouchez

Members
  • Content Count

    81
  • Joined

  • Last visited

  • Days Won

    4

Arnaud Bouchez last won the day on July 22

Arnaud Bouchez had the most liked content!

Community Reputation

90 Excellent

3 Followers

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Arnaud Bouchez

    HEIC library

    Brillant! Do you know if it is compatible with the built-in https://blogs.windows.com/windowsexperience/2018/03/16/announcing-windows-10-insider-preview-build-17123-for-fast/#hL2gI3IBkfsGuK6d.97 ? Do you know the WIC identifiers involved?
  2. Arnaud Bouchez

    Unit testing cross platform code

    We don't use Delphi for other platforms.... but FPC... There is no plan yet, due to how incompatible cross-platform was in Delphi. And even with ARC disabled, I am not sure it would be worth it. There is a very small test framework in our Cross-Platform client units. See https://github.com/synopse/mORMot/blob/master/CrossPlatform/SynCrossPlatformTests.pas It is very lightweight, and should work on all platforms...
  3. Arnaud Bouchez

    SChannel TLS - perform TLS communication with WinAPI

    For information, our Open Source https://github.com/synopse/mORMot/blob/master/SynCrtSock.pas supports SChannel as TLS layer since some time, for its raw socket layer. Of course, there is the additional WinInet/WinHTTP API for HTTP requests, which supports proper Proxy detection. Its SChannel implementation is more concise that your propose, and it works from Delphi 6 and up, and also for FPC. See https://github.com/synopse/mORMot/blob/5777f00d17fcbe0378522ceddceb0abece1dd0e3/SynWinSock.pas#L847
  4. Arnaud Bouchez

    Unit testing cross platform code

    We use our Open Source https://github.com/synopse/mORMot/blob/master/SynTests.pas unit. It is cross-platform and cross-compiler (FPC and Delphi). But it is mostly about server-side process and Win32/Win64 for Delphi. It is cross-platform (Win, BSD, Linux, i386/x86-64/arm32/aarch64) for FPC.
  5. It would make sense only if your data consist in text files, and you want to keep versioning of the information. A regular SQL database would replace the old data, so you would need to log the old values in a dedicated table. You can use the git command-line for all features you need. Just call it with the proper argument from your Delphi application. But I would rather take a look at https://www.fossil-scm.org/home/doc/trunk/www/index.wiki It is an efficient Distributed Version Control Management system, very similar to git, but with a big difference: "Self-Contained - Fossil is a single self-contained stand-alone executable. To install, simply download a precompiled binary for Linux, Mac, or Windows and put it on your $PATH. Easy-to-compile source code is also available" So you could be able to much easier integrate it to your own software. It has some other nice features - like an integrated Web Server - which could be easy for you. Here also, you would need to call the fossil command line from your Delphi application.
  6. Arnaud Bouchez

    JSON as a way to save information in Firebird

    @aehimself I do not have the same negative experience in practice. In fact, your last point gives light to the previous one: "DB engine has built-in JSON support" is needed. I stored JSON in DB with great success for several projects. Especially in a DDD project, we use our ORM to store the "Aggregate" object, with all its associated data objects and arrays serialized as JSON, and some indexed fields for quick query. If the architecture starts from the DB, which is so 80s, using JSON doesn't make sense. But if the architecture starts from the code, which is what is recommended in this century with new features like NoSQL and ORM running on high-end hardware, then you may have to enhance your design choices. Normalizing data and starting from the DB is perfectly fine, for instance if you make RAD or have a well-known data layout (e.g. accounting), but for a more exploring project, it will become more difficult to maintain and evolve. "- Some database engines can not search in BLOB fields. Now it might not be an issue in the beginning but it makes investigating data corruption / debugging processing issues a living nightmare" -> this is why I propose to duplicate the searched values in its own indexed fields, and only search the JSON once it is refined; and do not use BLOB binary fields, but CTEXT fields. "Downloading blob fields are slow, no matter what" -> it is true if you download it, but if the JSON process is done on the server itself, using JSON functions as offered e.g. by PostgreSQL or SQLite3, it is efficient (once you pre-query your rows using some dedicated indexed fields) "they have no issues handling a larger number of columns" -> main idea of using JSON is not to have a fixed set of columns, but being able to store anything, with no pre-known schema, and with several level of nested objects or arrays.
  7. Arnaud Bouchez

    Embedded MongoDB

    MongoDB benefit is to be installed in its server(s), with proper replication. Using it stand-alone is pointless. Use SQlite3 as embedded database. It supports JSON https://www.sqlite.org/json1.html efficiently. In practice, on some production project we used: - SQLite3 for almost everything (up to 1TB databases) - and we usually create several databases, e.g. per-user DB - MongoDB for storing huge content (more than 1TB databases) with replication: typically used as an archive service of "cold" data, which can be queried efficiently if you defined the proper indexes To let all this work from Delphi, we use our OpenSource http://mormot.net ORM, which is able to run efficiently on both storages, with the exact same code. The WHERE SQL query clauses are even translated on the fly to MongoDB pipelines by the ORM. One main trick is to put raw data as JSON in the RawJSON or TDocVariant ORM fields, then duplicate the fields to be queried as stand-alone ORM properties, with a proper index. Then you can query it very efficiently.
  8. Arnaud Bouchez

    AES Encryption - FMX

    You are right, SynCrypto is fine with FMX running on Windows - and it uses RawByteString or TBytes as required since Delphi 2009. But it is not a OS compatibility problem - it is a compiler issue. To be fair, it's Delphi cross-platform compiler/RTL which is designed poorly, especially all the backward compatibility breaks they made about strings and heap. Their recent step back is a clear hint of their bad design choices. There is no problem to use SynCrypto on Windows, Linux, BSD, Darwin, for Intel/AMD or ARM 32-bit or 64-bit CPU, if you use FPC. But we didn't lose time with targets breaking too much the existing code base. I am happy I didn't spend weeks making mORMot ARC-compatible - which is now deprecated! - and focused instead on FPC compatibility and tuning. Which was very rewarding.
  9. Arnaud Bouchez

    JSON as a way to save information in Firebird

    For a regular SQL DB, I would use a BLOB SUB_TYPE TEXT field, to store the JSON content. Then duplicate some JSON fields in a dedicated stand-alone SQL field (e.g. a "id" or "name" JSON field into regular table.id or table.name fields in addition to the table.json main field), for easy query - with an index if speed is mandatory. So, start with JSON only (and a key field), then maybe add some dedicated SQL fields for easier query, if necessary. side note: I would rather use SQLite3 or PostgreSQL for efficiently storing JSON content: both have efficient built-in support. Or a "JSON native" database like MongoDB.
  10. Arnaud Bouchez

    Good practices with nested methods

    I don't agree - don't add new private methods. It is not SOLID. Try to keep the class definition small and readable. Rather add a hidden object or class in your implementation section.
  11. Arnaud Bouchez

    Recommended Cryptographic Library

    Our Open-Source https://github.com/synopse/mORMot/blob/master/SynCrypto.pas has almost all that you require. About performance, it is the only one in the Delphi area using AES-NI and optimized SSE3/SSE4.2 assembly - as far as I know. So it should blow alternatives. It is cross-compiler (Delphi and FPC) and cross-platform (Windows, Linux, BSD... thanks to FPC). For elliptical curves, see its sibbling https://github.com/synopse/mORMot/blob/master/SynEcc.pas It supports only secp256r1 but it is feature complete (e.g. simple CA management) and fast (1 ms to create a key pair, 0.4 ms to sign or verify on x86-64) - also cross-platform and cross-compiler. See the documentation at https://synopse.info/files/html/Synopse mORMot Framework SAD 1.18.html#TITL_187 Both are highly maintained, and used on production since years. They don't require any external dll (like OpenSSL) which tends to be a maintenance nightmare on Windows.
  12. Arnaud Bouchez

    Good practices with nested methods

    Yes, @Bill Meyer is right: do not put the nested functions part of the main class. It would break SOLID principles for sure - at least the single responsibility. Always favor composition in OOP. About refactoring and breaking huge functions, you could take a look at those slides: Following these proposals, for code refactoring, I would move the code into dedicated records with methods (or classes).
  13. Arnaud Bouchez

    Firebird Encryption options

    Switch to a n-Tier architecure is the way to go. Keep the database locally on your server computer (or network), then use regular REST/JSON over secure HTTPS for the communication with clients. HTTPS will be much easier to secure and scale than forcing encryption with the database driver. Certificate management is a difficult think to do - I have seen so many solutions running fine... until a certificate becomes obsolete. 😉 We usually use a nginx server as reverse proxy, with https://letsencrypt.org/ certificate management.
  14. Arnaud Bouchez

    Good practices with nested methods

    A quick and simple rule would be to define only mandatory variables as shared for the nested procedures, i.e. above them. That is, try to keep all variables of the main block in the lower part of the code, just before the main block. Just as you did. From my experiment, nested functions are fine if there is only 1 (or 2) of them. Once I reach the number of 2/3 nested functions, I usually define a private record type, with proper methods. It is kept private in the implementation section of the unit. The trick of using a record with methods, and not a class, allows to allocate it on the stack in the main method, with no try..finally Free block. It is much cleaner (more SOLID), and also much more extendable. The main benefit is that it is re-usable: you could reuse some code, in another function. Last but not least, you have the possibility to add a unitary test method, and browse easier the code in your IDE.
  15. Arnaud Bouchez

    With's the deal with "With"?

    with SomeUnitName do doesn't compile on my Delphi 10.3 (nor FPC). Compiler complains with [dcc64 Error] Test.dpr(200): E2029 '.' expected but 'DO' found
×