support for delphi 11.1

This commit is contained in:
Razor12911
2022-05-13 13:05:10 +02:00
parent 8ceccef928
commit 39fb5ae479
167 changed files with 8914 additions and 3205 deletions

View File

@@ -28,7 +28,7 @@ HtmlSideBar=Overview/Meet the mORMot:SOURCE,Download/How to install:TITL_113,API
; the sidebar first links, for html export
{\b Document License}
{\i Synopse mORMot Framework Documentation}.\line Copyright (C) 2008-2020 Arnaud Bouchez.\line Synopse Informatique - @https://synopse.info
{\i Synopse mORMot Framework Documentation}.\line Copyright (C) 2008-2022 Arnaud Bouchez.\line Synopse Informatique - @https://synopse.info
The {\i Synopse mORMot Framework Source Code} is licensed under GPL / LGPL / MPL licensing terms, free to be included in any application.
;This documentation has been generated using {\i Synopse SynProject} - @https://synopse.info/fossil/wiki?name=SynProject
;This document is a free document; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
@@ -136,7 +136,7 @@ The main approach of this framework is to avoid @*RAD@ in the development of pro
: Expected Use
Any application which need moderate database usage (up to some GB of data) with easy setup and administration, together with a secure @*ACID@ behavior in a Client-Server environment should consider using the {\i Synopse mORMot Framework}.
: Requirement Exceptions
This framework was developed in order to run mainly under any {\i Delphi} compiler, from version {\i Delphi} 6 to version {\i Delphi 10.3 Rio}.
This framework was developed in order to run mainly under any {\i Delphi} compiler, from version {\i Delphi} 6 to the latest Delphi version ({\i Delphi 11 Alexandria} at time of this writing).
On the {\i server side}, it targets both {\i Win32} and {\i Win64} platforms (using the 64-bit compiler included in latest {\i Delphi} XE2 and up).
For clients, in addition to those {\i Win32} / {\i Win64} platforms, you have cross-platform code generation abilities, for any {\i Delphi} or {\i @*FreePascal@} target (including {\i @*OSX@} and mobile {\i iOS} or {\i Android}), or AJAX / HTML5 clients via {\i @*Smart Mobile Studio@} - see @90@.
=[License]
@@ -464,7 +464,7 @@ The {\i Synopse mORMot Framework} shall provide User Interface and Report genera
Such a ribbon-oriented interface shall be made available, in a per-table approach, and associated reports.
Here is a sample of screen content, using proprietary TMS components:
%synfiletms.png
And here is the same application compiled using only VCL components, available from {\i Delphi} 6 up to {\i Delphi 10.3 Rio}:
And here is the same application compiled using only VCL components, available from {\i Delphi} 6 up to the latest available {\i Delphi} version:
%synfilevcl.png
[SRS-DI-2.3.1]
@@ -570,7 +570,7 @@ DisplayName=mORMot Framework Overview
:Synopse mORMot Overview
%IamLost.png
{\i Synopse mORMot} is an Open Source @*Client-Server@ @*ORM@ @*SOA@ @*MVC@ framework for {\i Delphi} 6 up to {\i Delphi 10.3 Rio} and @*FPC@, targeting {\i Win/@*Linux@} for the server, and any platform for clients (including mobile or AJAX).
{\i Synopse mORMot} is an Open Source @*Client-Server@ @*ORM@ @*SOA@ @*MVC@ framework for {\i Delphi} 6 up to the latest available {\i Delphi} version and @*FPC@ 3.2, targeting {\i Win/@*Linux@} for the server, and any platform for clients (including mobile or AJAX).
The main features of {\i mORMot} are therefore:
- {\i ORM/ODM}: objects persistence on almost any database (SQL or NoSQL);
- {\i SOA}: organize your business logic into @*REST@ services;
@@ -708,7 +708,7 @@ At first, some points can be highlighted, which make this framework distinct to
- More than 1800 pages of documentation;
- {\i Delphi}, {\i FreePascal}, mobile and @*AJAX@ clients can share the same server, and ORM/SOA client access code can be generated on request for any kind of application - see @86@;
- Full source code provided - so you can enhance it to fulfill any need;
- Works from {\i Delphi} 6 up to {\i Delphi 10.3 Rio} and FPC 2.6.4/2.7.1/3.x, truly Unicode (uses @*UTF-8@ encoding in its kernel, just like JSON), with any version of {\i Delphi} (no need to upgrade your IDE).
- Works from {\i Delphi} 6 up to the latest available {\i Delphi} version and FPC 3.2.x, truly Unicode (uses @*UTF-8@ encoding in its kernel, just like JSON), with any version of {\i Delphi} (no need to upgrade your IDE).
\page
: Benefits
As you can see from the previous section, {\i mORMot} provides a comprehensive set of features that can help you to manage your crosscutting concerns though a reusable set of components and core functionality.
@@ -1364,7 +1364,7 @@ In the following next paragraphs, we'll comment some main features of the lowest
- {\f1\fs20 @*TDocVariant@} custom {\f1\fs20 variant} type for dynamic schema-less {\i object} or {\i array} storage.
Other shared features available in {\f1\fs20 SynTests.pas} and {\f1\fs20 SynLog.pas} will be detailed later, i.e. @*Test@ing and @*Log@ging - see @12@.
:32 Unicode and UTF-8
Our {\i mORMot} Framework has 100% UNICODE compatibility, that is compilation under {\i Delphi} 2009 and up (including latest {\i Delphi 10.3 Rio} revision). The code has been deeply rewritten and @*test@ed, in order to provide compatibility with the {\f1\fs20 String=UnicodeString} paradigm of these compilers. But the code will also handle safely Unicode for older versions, i.e. from {\i Delphi} 6 up to {\i Delphi} 2007.
Our {\i mORMot} Framework has 100% UNICODE compatibility, that is compilation under {\i Delphi} 2009 and up (including the latest available {\i Delphi} version). The code has been deeply rewritten and @*test@ed, in order to provide compatibility with the {\f1\fs20 String=UnicodeString} paradigm of these compilers. But the code will also handle safely Unicode for older versions, i.e. from {\i Delphi} 6 up to {\i Delphi} 2007.
From its core to its uppermost features, our framework is natively @**UTF-8@, which is the de-facto character encoding for @*JSON@, {\i @*SQLite3@}, and most supported database engines. This allows our code to offer fast streaming/parsing in a @*SAX@-like mode, avoiding any conversion between encodings from the storage layer to your business logic. We also needed to establish a secure way to use strings, in order to handle all versions of {\i Delphi} (even pre-Unicode versions, especially the {\i Delphi} 7 version we like so much), and provide compatibility with the {\i @*FreePascal@ Compiler}. This consistency allows to circumvent any RTL bug or limitation, and ease long-term support of your project.
Some string types have been defined, and used in the code for best cross-compiler efficiency:
- {\f1\fs20 @**RawUTF8@} is used for every internal data usage, since both {\i SQLite3} and JSON do expect UTF-8 encoding;
@@ -1463,7 +1463,7 @@ Here is how those new methods work:
! if GroupA.Find(v)<0 then // fast binary search
! ShowMessage('Error: 1500 not found!');
Some unique methods like {\f1\fs20 Slice, Reverse} or {\f1\fs20 AddArray} are also available, and mimic well-known Python methods.
Still closer to the generic paradigm, working for {\i Delphi} 6 up to {\i Delphi 10.3 Rio}, without the need of the slow enhanced RTTI, nor the executable size overhead and compilation issues of generics...
Still closer to the generic paradigm, working for {\i Delphi} 6 up to the latest available {\i Delphi} version, without the need of the slow enhanced RTTI, nor the executable size overhead and compilation issues of generics...
: Capacity handling via an external Count
One common speed issue with the default usage of {\f1\fs20 TDynArray} is that the internal memory buffer is reallocated when you change its length, just like a regular {\i Delphi} {\i dynamic array}.
That is, whenever you call {\f1\fs20 Add} or {\f1\fs20 Delete} methods, an internal call to {\f1\fs20 SetLength(DynArrayVariable)} is performed. This could be slow, because it always executes some extra code, including a call to {\f1\fs20 ReallocMem}.
@@ -1829,7 +1829,7 @@ When working with complex documents, e.g. with @*BSON@ / {\i @*MongoDB@} documen
: Advanced TDocVariant process
:194 Number values options
By default, {\f1\fs20 TDocVariantData} will only recognize {\f1\fs20 integer}, {\f1\fs20 Int64} and {\f1\fs20 currency} - see @33@ - as number values. Any floating point value which may not be translated to/from @*JSON@ textual representation safely will be stored as a JSON string, i.e. if it does match an integer or up to 4 fixed decimals, with 64-bit precision. We stated that JSON serialization should be conservative, i.e. serializing then unserializing (or the other way round) should return the very same value; parsing JSON is a matter of (difficult) choices - see @http://seriot.ch/parsing_json.php#5 - and we choose to be paranoid and not loose information by default.
You can set the {\f1\fs20 @*dvoAllowDoubleValue@} option to {\f1\fs20 TDocVariantData}, so that such floating-point numbers will be recognized and stored as {\f1\fs20 @*double@}. In this case, only {\f1\fs20 varDouble} storage will be used for the {\f1\fs20 variant} values, i.e. 64-bit IEEE 754 {\f1\fs20 double} values, handling 5.0 x 10^-324 .. 1.7 x 10^308 range. With such floating-point values, you may loose precision and digits during the JSON serialization process: this is why it is not enabled by default.
You can use the {\f1\fs20 @*_JsonFastFloat()@} wrapper or set the {\f1\fs20 @**dvoAllowDoubleValue@} option to {\f1\fs20 TDocVariantData}, so that such floating-point numbers will be recognized and stored as {\f1\fs20 @**double@}. In this case, only {\f1\fs20 varDouble} storage will be used for the {\f1\fs20 variant} values, i.e. 64-bit IEEE 754 {\f1\fs20 double} values, handling 5.0 x 10^-324 .. 1.7 x 10^308 range. With such floating-point values, you may loose precision and digits during the JSON serialization process: this is why it is not enabled by default.
Also note that some JSON engines do not support 64-bit integer numbers. For instance, {\f1\fs20 @*JavaScript@} engines handle only up to @*53-bit@ of information without precision loss (called the {\i significand} bits), due to their internal storage as a 8 bytes IEEE 754 container. In some cases, it is safest to use JSON string representation of such numbers, as is done with the {\f1\fs20 woIDAsIDstr} value of {\f1\fs20 TTextWriterWriteObjectOption} for safe serialization of {\f1\fs20 TSQLRecord.ID} ORM values.
If you want to work with high-precision floating point numbers, consider using {\f1\fs20 @*TDecimal128@} values, as implemented in {\f1\fs20 SynMongoDB.pas}, which supports 128-bit high precision decimal, as defined by the {\i IEEE 754-2008 128-bit decimal floating point} standard, and handled in {\i MongoDB} 3.4+. Their conversion to/from text - therefore to/from JSON - won't loose nor round any digit, as soon as the value fits in its 128-bit storage.
: Object or array document creation options
@@ -4610,7 +4610,7 @@ In the above query expression, the {\f1\fs20 rank()} function is used over the d
In any database, there is a need to define how column data is to be compared. It is needed for proper search and ordering of the data. This is the purpose of so-called {\i @**collation@s}.
By default, when {\i SQLite} compares two strings, it uses a collating sequence or collating function (two words for the same thing) to determine which string is greater or if the two strings are equal. {\i SQLite} has three built-in collating functions: BINARY, NOCASE, and RTRIM:
- BINARY - Compares string data using {\f1\fs20 memcmp()}, regardless of text encoding.
- NOCASE - The same as binary, except the 26 upper case characters of ASCII are folded to their lower case equivalents before the comparison is performed. Note that only ASCII characters are case folded. Plain {\i SQLite} does not attempt to do full @*Unicode@ case folding due to the size of the tables required - but you could use {\i mORMot}'s SYSTEMNOCASE or WIN32CASE/WIN32NOCASE custom collations for enhanced case folding support (see below);
- NOCASE - The same as binary, except the 26 upper case characters of ASCII are folded to their lower case equivalents before the comparison is performed. Note that only ASCII characters are case folded. Plain {\i SQLite} does not attempt to do full @*Unicode@ case folding due to the size of the tables required - but you could use {\i mORMot}'s SYSTEMNOCASE, or WIN32CASE/WIN32NOCASE custom collations for enhanced case folding support (see below);
- RTRIM - The same as binary, except that trailing space characters are ignored.
In the {\i mORMot} ORM, we defined some additional kind of collations, via some internal calls to the {\f1\fs20 sqlite3_create_collation()} API:
|%25%60
@@ -4632,6 +4632,7 @@ The following collations are therefore available when using {\i SQLite3} within
|NOCASE|Default ASCII 7 bit comparison
|RTRIM|Default {\f1\fs20 memcmp()} comparison with right trim
|SYSTEMNOCASE|{\i mORMot}'s Win-1252 8 bit comparison
;|UNICODENOCASE|{\i mORMot}'s Unicode 10.0 comparison
|ISO8601|{\i mORMot}'s date/time comparison
|WIN32CASE|{\i mORMot}'s comparison using case-insensitive Windows API
|WIN32NOCASE|{\i mORMot}'s comparison using not case-insensitive Windows API
@@ -4639,17 +4640,17 @@ The following collations are therefore available when using {\i SQLite3} within
Note that WIN32CASE/WIN32NOCASE will be slower than the others, but will handle properly any kind of complex scripting. For instance, if you want to use the Unicode-ready Windows API at database level, you can set for each database model:
! aModel.SetCustomCollationForAll(sftUTF8Text,'WIN32CASE');
! aModel.SetCustomCollationForAll(sftDateTime,'NOCASE');
On non-Windows platform, it will either use the system ICU library (if available), or fallback to the FPC RTL with temporary {\f1\fs20 UnicodeString} values - which requires to include `cwstrings` in your project uses clause. Note that depending on the library used, the results may not be consistent: so if you move a {\i SQLite3} database file e.g. from a Windows system to a Linux system with WIN32CASE collation, you should better regenerate all your indexes!
If you use non-default collations (i.e. SYSTEMNOCASE/ISO8601/WIN32CASE/WIN32NOCASE), you may have trouble running requests with "plain" {\i SQLite3} tools. But you can use our {\f1\fs20 @*SynDBExplorer@} safely, since it will declare all the above collations.
When using external databases - see @27@, if the content is retrieved directly from the database driver and by-passes the virtual table mechanism - see @20@, returned data may not match your expectations according to the custom collations: you will need to customize the external tables definition by hand, with the proper SQL statement of each external DB engine.
Note that {\i @*mORMot 2@} offers a new UNICODENOCASE collation, which follows Unicode 10.0 without any Windows or ICU API call, so is consistent on all systems - and is also faster.
: REGEXP operator
Our {\i SQLite3} engine can use {\i @**regular expression@} within its SQL queries, by enabling the {\f1\fs20 @**REGEXP@} operator in addition to standard SQL operators ({\f1\fs20 = == != <> IS IN LIKE GLOB MATCH}). It will use the Open Source PCRE library to perform the queries.
In order to enable the operator, you should include unit {\f1\fs20 SynSQLite3RegEx.pas} to your uses clause, and register the {\f1\fs20 RegExp()} SQL function to a given {\i SQLite3} database instance, as such:
!uses SynCommons, mORmot, mORMotSQLite3,
!! SynSQLite3RegEx;
! ...
Our {\i SQLite3} engine can use {\i @**regular expression@} within its SQL queries, by enabling the {\f1\fs20 @**REGEXP@} operator in addition to standard SQL operators ({\f1\fs20 = == != <> IS IN LIKE GLOB MATCH}).
: Default REGEXP Engine
By default, and since mORMot 1.18.6218 (25 January 2021), our static {\i SQlite3} engine includes a compact and efficient enough C extension, as available from the official {\i SQLite3} project source code tree. It is included with the official amalgamation file during our compilation phase.
So you don't need to do anything to be able to use the REGEX operator in your queries:
!Server := TSQLRestServerDB.Create(Model,'test.db3');
!try
!! CreateRegExpFunction(Server.DB.DB);
! with TSQLRecordPeople.CreateAndFillPrepare(Client,
!! 'FirstName REGEXP ?',['\bFinley\b']) do
! try
@@ -4667,6 +4668,20 @@ The above code will execute the following SQL statement (with a prepared paramet
! SELECT * from People WHERE Firstname REGEXP '\bFinley\b';
That is, it will find all objects where {\f1\fs20 TSQLRecordPeople.FirstName} will contain the {\f1\fs20 'Finley'} word - in a regular expression, {\f1\fs20 \\b} defines a word {\f1\fs20 b}oundary search.
In fact, the {\f1\fs20 REGEXP} operator is a special syntax for the {\f1\fs20 regexp()} user function. No {\f1\fs20 regexp()} user function is defined by default and so use of the {\f1\fs20 REGEXP} operator will normally result in an error message. Calling {\f1\fs20 CreateRegExFunction()} for a given connection will add a SQL function named "{\f1\fs20 regexp()}" at run-time, which will be called in order to implement the {\f1\fs20 REGEXP} operator.
: PCRE REGEXP Engine
If you want to use the Open Source PCRE library to perform the searches, instead of this default C extension, you should include the {\f1\fs20 SynSQLite3RegEx.pas} unit to your uses clause, and register the {\f1\fs20 RegExp()} SQL function to a given {\i SQLite3} database instance, as such:
!uses SynCommons, mORmot, mORMotSQLite3,
!! SynSQLite3RegEx;
! ...
!Server := TSQLRestServerDB.Create(Model,'test.db3');
!try
!! CreateRegExpFunction(Server.DB.DB);
! with TSQLRecordPeople.CreateAndFillPrepare(Client,
!! 'FirstName REGEXP ?',['\bFinley\b']) do
! try
! while FillOne do begin
! Check(LastName='Morse');
! ...
It will use the statically linked PCRE library as available since {\i Delphi} XE, or will rely on the {\f1\fs20 PCRE.pas} wrapper unit as published at @http://www.regular-expressions.info/download/TPerlRegEx.zip for older versions of {\i Delphi}.
This unit will call directly the @*UTF-8@ API of the PCRE library, and maintain a per-connection cache of compiled regular expressions to ensure the best performance possible.
:60 ACID and speed
@@ -4752,7 +4767,8 @@ Note that the virtual table module name is retrieved from the class name. For in
To handle external databases, two dedicated classes, named {\f1\fs20 TSQLVirtualTableExternal} and {\f1\fs20 TSQLVirtualTableCursorExternal} will be defined in a similar manner - see @%%HierExternalTables@ @30@.
As you probably have already stated, all those Virtual Table mechanism is implemented in {\f1\fs20 mORMot.pas}. Therefore, it is independent from the {\i @*SQLite3@} engine, even if, to my knowledge, there is no other SQL database engine around able to implement this pretty nice feature.
: Defining a Virtual Table module
Here is how the {\f1\fs20 TSQLVirtualTableLog} class type is defined, which will implement a @*Virtual Table@ module named "{\f1\fs20 Log}". Adding a new module is just made by overriding some {\i Delphi} methods:
Here is how the {\f1\fs20 TSQLVirtualTableLog} class type is defined, which will implement a @*Virtual Table@ module named "{\f1\fs20 Log}". Note that the {\i SQLite3} virtual table module name will be computed from the class name, trimming its first characters, e.g. {\f1\fs20 TSQLVirtualTable{\b Log}} will trim trailing {\f1\fs20 TSQLVirtualTable} and define a {\f1\fs20 'Log'} virtual module.
Adding a new module is just made by overriding some {\i Delphi} methods:
! TSQLVirtualTableLog = class(TSQLVirtualTable)
! protected
! fLogFile: TSynLogFile;
@@ -7431,7 +7447,7 @@ In practice, for your project, you will have several possibilities to create a C
|SOA Interfaces|RPC REST|RPC
|SOA Methods|Full REST/HTTP|Verbose
|MVC Web|Web site + AJAX|HTML-oriented
|ORM REST|Tests or internal use|Security/design flows
|ORM REST|Tests or internal use|Security/design flaws
|%
In a nutshell,
- {\i SOA Interfaces} - see @63@ - is the preferred way to build both public and private services: both client and server code will be defined from {\f1\fs20 interface} types, including sessions management, stubbing/mocking, documentation generation, and security features.
@@ -9668,7 +9684,7 @@ If you compare with existing mocking frameworks, even in other languages / platf
- Most common parameters and results can be defined as simple {\f1\fs20 array of const} in the {\i Delphi} code, or by supplying JSON arrays (needed e.g. for more complex structures like {\f1\fs20 record} values);
- Execution trace retrieval in easy to read or write text format (and not via complex "fluent" interface e.g. with {\f1\fs20 When} clauses);
- Auto-release of the {\f1\fs20 TInterfaceStub TInterfaceMock TInterfaceMockSpy} generator instance, when the interface is no longer required, to minimize the code to type, and avoid potential memory leaks;
- Works from {\i Delphi} 6 up to {\i Delphi 10.3 Rio} - since no use of syntax sugar like generics, nor the {\f1\fs20 RTTI.pas} features;
- Works from {\i Delphi} 6 up to the latest available {\i Delphi} version - since no use of syntax sugar like generics, nor the {\f1\fs20 RTTI.pas} features;
- Very good performance (the faster {\i Delphi} mocking framework, for sure), due to very low overhead and its reuse of {\i mORMot}'s low-level interface-based services kernel using JSON serialization, which does not rely on the slow and limited {\f1\fs20 TVirtualInterface}.
: Stubbing complex return values
Just imagine that the {\f1\fs20 ForgotMyPassword} method does perform an internal test:
@@ -9881,7 +9897,7 @@ Here are the key features of the current implementation of services using interf
|Server factory|You can get an implementation on the server side
|Client factory|You can get a "fake" implementation on the client side, remotely calling the server to execute the process
|Cross-platform clients|A {\i mORMot} server is able to generate cross-platform client code via a set of templates - see @86@
|Auto marshalling|The contract is transparently implemented: no additional code is needed e.g. on the client side, and will handle simple types (strings, numbers, dates, sets and enumerations) and high-level types (objects, collections, records, dynamic arrays, variants) from {\i Delphi} 6 up to {\i Delphi 10.3 Rio}
|Auto marshalling|The contract is transparently implemented: no additional code is needed e.g. on the client side, and will handle simple types (strings, numbers, dates, sets and enumerations) and high-level types (objects, collections, records, dynamic arrays, variants) from {\i Delphi} 6 up to the latest available {\i Delphi} version
|Flexible|Methods accept per-value or per-reference parameters
|Instance lifetime|An implementation class can be:\line - Created on every call,\line - Shared among all calls,\line - Shared for a particular user or group,\line - Dedicated to the thread it runs on,\line - Alive as long as the client-side interface is not released,\line - Or as long as an @*authentication@ session exists
|@*Stateless@|Following a standard request/reply pattern
@@ -9983,7 +9999,7 @@ You can therefore define complex {\f1\fs20 interface} types, as such:
! /// validates ArgsInputIsOctetStream raw binary upload
! function DirectCall(const Data: TSQLRawBlob): integer;
! end;
Note how {\f1\fs20 SpecialCall} and {\f1\fs20 ComplexCall} methods have quite complex parameters definitions, including dynamic arrays, sets and records. DirectCall will use binary POST, by-passing @*Base64@ JSON encoding - see @197@. The framework will handle {\f1\fs20 const} and {\f1\fs20 var} parameters as expected, i.e. as input/output parameters, also on the client side. Any simple types of dynamic arrays (like {\f1\fs20 TIntegerDynArray}, {\f1\fs20 TRawUTF8DynArray}, or {\f1\fs20 TWideStringDynArray}) will be serialized as plain JSON arrays - the framework is able to handle any dynamic array definition, but will serialize those simple types in a more AJAX compatible way, thanks to the enhanced RTTI available since to {\i Delphi} 2010.
Note how {\f1\fs20 SpecialCall} and {\f1\fs20 ComplexCall} methods have quite complex parameters definitions, including dynamic arrays, sets and records. {\f1\fs20 DirectCall} will use binary POST, by-passing @*Base64@ JSON encoding - see @197@. The framework will handle {\f1\fs20 const} and {\f1\fs20 var} parameters as expected, i.e. as input/output parameters, also on the client side. Any simple types of dynamic arrays (like {\f1\fs20 TIntegerDynArray}, {\f1\fs20 TRawUTF8DynArray}, or {\f1\fs20 TWideStringDynArray}) will be serialized as plain JSON arrays - the framework is able to handle any dynamic array definition, but will serialize those simple types in a more AJAX compatible way, thanks to the enhanced RTTI available since to {\i Delphi} 2010.
: TPersistent / TSQLRecord parameters
As stated above, {\i mORMot} does not allow a method {\f1\fs20 function} to return a {\f1\fs20 class} instance.
That is, you can't define such a method:
@@ -13659,7 +13675,7 @@ By default, the following security groups are created on a void database:
|%14%12%14%11%11%12%12%12
|\b Group|POST SQL|SELECT SQL|Auth R|Auth W|Tables R|Tables W|Services\b0
|Admin|Yes|Yes|Yes|Yes|Yes|Yes|Yes
|Supervisor|Yes|No|Yes|No|Yes|Yes|Yes
|Supervisor|No|Yes|Yes|No|Yes|Yes|Yes
|User|No|No|No|No|Yes|Yes|Yes
|Guest|No|No|No|No|Yes|No|No
|%
@@ -15736,7 +15752,7 @@ And even better, testing-driven coding can be encouraged:
It could sounds like a waste of time, but such coding improve your code quality a lot, and, at least, it help you write and optimize every implementation feature.
The framework has been implemented using this approach, and provide all the tools to write tests. In addition to what other {\i Delphi} frameworks offer (e.g. {\i DUnit / DUnitX}), the {\f1\fs20 SynTests.pas} unit is very much integrated with other elements of the framework (like logging), is cross-platform and cross-compiler, and provides a complete {\i stubbing / mocking} mechanism to cover @62@.
: Involved classes in Unitary testing
The @!TSynTest,TSynTestCase,TSynTests!Lib\SynTests.pas@ unit defines two classes (both inheriting from {\f1\fs20 TSynTest}), implementing a complete Unitary testing mechanism similar to {\i DUnit}, with less code overhead, and direct interface with the framework units and requirements (@*UTF-8@ ready, code compilation from {\i Delphi} 6 up to {\i Delphi 10.3 Rio} and FPC, no external dependency).
The @!TSynTest,TSynTestCase,TSynTests!Lib\SynTests.pas@ unit defines two classes (both inheriting from {\f1\fs20 TSynTest}), implementing a complete Unitary testing mechanism similar to {\i DUnit}, with less code overhead, and direct interface with the framework units and requirements (@*UTF-8@ ready, code compilation from {\i Delphi} 6 up to the latest available {\i Delphi} version and FPC, no external dependency).
The following diagram defines this class hierarchy:
\graph HierTSynTest TSynTest classes hierarchy
\TSynTests\TSynTest
@@ -15850,12 +15866,10 @@ Before any release all unitary regression tests are performed with the following
- {\i Delphi} 2007;
- {\i Delphi} 2010 (we assume that if it works with {\i Delphi} 2010, it will work with {\i Delphi} 2009, with the exception of {\f1\fs20 generic} compilation);
- {\i Delphi} XE4;
- {\i Delphi} XE6;
- {\i Delphi} XE7;
- {\i Delphi} 10 Seattle;
- {\i Delphi} 10.1 Berlin;
- {\i Delphi} 10.2 Tokyo;
- {\i Delphi} XE8;
- {\i Delphi} 10.3 Rio;
- {\i Delphi} 10.4 Sidney;
- {\i @*CrossKylix@} 3.0;
- {\i @*FPC@} 3.x - preferred is {\i 3.2 fixes}.
Target platforms are {\i Win32} and {\i Win64} for {\i Delphi} and {\i FPC}, plus {\i Linux 32/64} for {\i FPC} and {\i CrossKylix}.
@@ -16223,17 +16237,17 @@ Follow these steps:
- Finally, click on the "{\i Zip Archive}" link, available at the end of the "{\i Overview}" header, right ahead to the "{\i Other Links}" title. This link will build a {\f1\fs20 .zip} archive of the complete source code and download it to your browser.
: Expected compilation platform
The framework source code tree will compile and is tested for the following platforms:
- {\i Delphi} 6 up to {\i Delphi 10.3 Rio} compiler and IDE, with {\i @*FreePascal@ Compiler} (FPC) 3.x and {\i @*Lazarus@} support;
- {\i Delphi} 6 up to the latest {\i Delphi} compiler and IDE version, with {\i @*FreePascal@ Compiler} (FPC) 3.x and {\i @*Lazarus@} support;
- Server side on Windows 32-bit and @**64-bit@ platforms (FPC or {\i Delphi} XE2 and up expected when targeting {\i Win64});
- {\i @*Linux@} 32-bit and 64-bit platform for servers using the FPC 3.2 fixes branch - now stable and tested in production since years (especially {\i @*Debian@/@*Ubuntu@} on {\f1\fs20 x86_64});
- VCL client on Win32/Win64 - GUI may be compiled optionally with third-party non Open-Source @*TMS@ Components, instead of default VCL components - see @http://www.tmssoftware.com/site/tmspack.asp
- @69@ clients on any supported platforms;
- @90@ startup with 2.1, for creating @*AJAX@ / @*JavaScript@ / HTML5 / Mobile clients.
Some part of the library (e.g. {\f1\fs20 SynCommons.pas}, {\f1\fs20 SynTests.pas}, {\f1\fs20 SynLog.pas} {\f1\fs20 SynPDF.pas} or the @27@ units) are also compatible with {\i Delphi} 5.
If you want to compile {\i mORMot} unit into @*packages@, to avoid an obfuscated {\i [DCC Error] @*E2201@ Need imported data reference ($G) to access 'VarCopyProc'} error at compilation, you should defined the {\f1\fs20 USEPACKAGES} conditional in your project's options. Open {\f1\fs20 SynCommons.inc} for a description of this conditional, and all over definitions global to all {\i mORMot} units - see @45@.
If you want to compile {\i mORMot} unit into @**packages@, to avoid an obfuscated {\i [DCC Error] @*E2201@ Need imported data reference ($G) to access 'VarCopyProc'} error at compilation, you should defined the {\f1\fs20 USEPACKAGES} conditional in your project's options. Open {\f1\fs20 SynCommons.inc} for a description of this conditional, and all over definitions global to all {\i mORMot} units - see @45@. To avoid related {\i @*E1025@ Unsupported language feature: 'Object'} compilation error, you should probably also set "{\i Generate DCUs only}" in project's options "{\i C/C++ output file generator}".
The framework source code implementation and design tried to be as cross-platform and cross-compiler as possible, since the beginning. It is a lot of work to maintain compatibility towards so many tools and platforms, but we think it is always worth it - especially if you try not depend on {\i Delphi} only, which as shown some backward compatibility issues during its lifetime.
For HTML5 and Mobile clients, our main platform is {\i Smart Mobile Studio}, which is a great combination of ease of use, a powerful {\i SmartPascal} dialect, small applications (much smaller than FMX), with potential packaging as native iOS or {\i Android} applications (via {\i @*PhoneGap@}).
The latest versions of the {\i FreePascal Compiler} together with its great {\i Lazarus} IDE, are now very stable and easy to work with. We don't support {\i CodeTyphon}, since we found some licensing issue with some part of it (e.g. {\i Orca} GUI library origin is doubtful). So we recommend using {\i @*fpcupdeluxe@} - see @203@ - which is maintained by Alfred, a {\i mORMot} contributor. This is amazing to build the whole set of compilers and IDE, with a lot of components, for several platforms (this is a cross-platform project), just from the sources. I like {\i Lazarus} stability and speed much more than {\i Delphi} (did you ever tried to browse and debug {\i included} {\f1\fs20 $I ...} files in the {\i Delphi} IDE? with Lazarus, it is painless), even if the compiler is slower than {\i Delphi}'s, and if the debugger is less integrated and even more unstable than {\i Delphi}'s under Windows (yes, it is possible!). At least, it works, and the {\i Lazarus} IDE is small and efficient. Official {\i @*Linux@} support is available for {\i mORMot} servers, with full features in the {\i FPC} 3.2 branch - we use it on producing on {\i Linux} 64-bit since years.
The latest versions of the {\i FreePascal Compiler} together with its great {\i Lazarus} IDE, are now very stable and easy to work with. We don't support {\i CodeTyphon}, since we found some licensing issue with some part of it (e.g. {\i Orca} GUI library origin is doubtful). So we recommend using {\i @*fpcupdeluxe@} - see @203@ - which is maintained by Alfred, a {\i mORMot} contributor. This is amazing to build the whole set of compilers and IDE, with a lot of components, for several platforms (this is a cross-platform project), just from the sources. I like {\i Lazarus} stability and speed much more than {\i Delphi} (did you ever tried to browse and debug {\i included} {\f1\fs20 $I ...} files in the {\i Delphi} IDE? with Lazarus, it is painless), even if the compiler is slower than {\i Delphi}'s, and if the debugger is less integrated and even more unstable than {\i Delphi}'s under Windows (yes, it is possible!). At least, it works, and the {\i Lazarus} IDE is small and efficient. Official {\i @*Linux@} support is available for {\i mORMot} servers, with full features in the {\i FPC} 3.2 branch - we use it on production with {\i Linux} 64-bit since years.
: SQLite3 static linking for Delphi and FPC
{\i Preliminary note}: if you retrieved the source code from @https://github.com/synopse/mORMot you will have all the needed {\f1\fs20 .obj/.o} static files available in the expected folders. Just ignore this chapter.
In order to maintain our @https://synopse.info/fossil/timeline source code repository in a decent size, we excluded the {\f1\fs20 sqlite3.obj/.o} storage in it, but provide the full source code of the {\i @*SQlite3@} engine in a custom {\f1\fs20 sqlite3.c} file, ready to be compiled with all conditional defined as expected by {\f1\fs20 SynSQlite3Static.pas}. You need to add the official {\i SQlite3} amalgamation file from @https://www.sqlite.org/download.html and put its content into a {\f1\fs20 SQLite3\\amalgamation} sub-folder, for proper compilation. Our custom {\f1\fs20 sqlite3.c} file will add encryption feature to the engine. Also look into {\f1\fs20 SynSQlite3Static.pas} comments if there is any manual patch needed for proper compilation of the amalgamation sourece.
@@ -16374,7 +16388,7 @@ See @86@ for more information.
\page
:113 Delphi Installation
{\i Note: for FPC setup, see @125@.}
To setup mORMot for {\i Delphi 6} up to {\i Delphi 10.3 Rio}, you have two ways: either download the framework from archives, or clone our {\i GitHub} repository at @https://github.com/synopse/mORMot
To setup mORMot for {\i Delphi 6} up to the latest {\i Delphi} version, you have two ways: either download the framework from archives, or clone our {\i GitHub} repository at @https://github.com/synopse/mORMot
: Manual download
Download and uncompress the framework archives, including all sub-folders, into a local directory of your computer (for instance, {\f1\fs20 D:\\Dev\\mORMot}).
|%70
@@ -16429,11 +16443,12 @@ But since the FPC trunk may be unstable, we will propose to put in place a stabl
For this task, don't download an existing binary release of FPC / Lazarus, but use the {\i @**fpcupdeluxe@} tool, as published at @http://wiki.freepascal.org/fpcupdeluxe - it will allow to build your environment directly from the sources, and install it in a dedicated folder. Several FPC / Lazarus installations, with dedicated revision numbers, may coexist on the same computer: just ensure you run Lazarus from the shortcut created by {\i fpcupdeluxe}.
- Download the latest release of the tool from @https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases
- Unpack it in a dedicated folder, and run its executable.
- On the main screen, locate on the left the two versions listboxes. Select "fixes" for both {\i FPC version} and {\i Lazarus version}.
- On the main screen, locate on the left the two versions listboxes. Select "{\f1\fs20 3.2}" for {\i FPC version} and "{\f1\fs20 2.1.0}" for {\i Lazarus version}.
- Important note: if you want to cross-compile from Windows to other systems, e.g. install a Linux cross-compiler on Windows, ensure you installed the {\i Win32} FPC compiler and Lazarus, {\i not the Win64} version, which is known to have troubles with {\f1\fs20 currency} support;
- Then build the FPC and Lazarus binaries directly from the latest sources, by clicking on "Install/update FPC+Laz".
Those "fixes" branches are currently used for building our production projects, so are expected to be properly tested and supported. \line At the time of the writing of this documentation, our Lazarus IDE (on Linux) reports using:
- FPC fixes SVN 45428 (3.2.0)
- Lazarus fixes SVN 63179 (2.0.9).
Those branches are currently used for building our production projects, so are expected to be properly tested and supported. \line At the time of the writing of this documentation, our Lazarus IDE (on Linux) reports using:
- FPC SVN 45643 (3.2.0)
- Lazarus SVN 64940 (2.1.0).
One big advantage of {\i fpcupdeluxe} is that you can very easily install cross-compilers for the CPU / OS combinations enumerated at @202@.\line Just go to the "Cross" tab, then select the target systems, and click on "Install compiler".\line It may be needed to download the cross-compiler binaries (once): just select "Yes" when prompted.
You could install {\i mORMot} using {\i fpcupdeluxe}, but we recommend you clone our @https://github.com/synopse/mORMot repository, and setup the expected project paths, as detailed above at @113@.
If you don't want to define a given version, the current {\i trunk} should/could work, if it didn't include any regression at the time you get it - this is why we provide "supported" branches.\line If you want to use the {\i FPC trunk}, please modify line #262 in {\f1\fs20 Synopse.inc} to enable the {\f1\fs20 FPC_PROVIDE_ATTR_TABLE} conditional and support the latest trunk RTTI changes:
@@ -16839,7 +16854,7 @@ The {\i Office UI licensing program} was designed by {\i Microsoft} for software
If you want to design your user interface using a Office 2007/2010 ribbon look, please take a look at those official guidelines: @http://msdn.microsoft.com/en-us/library/cc872782.aspx
Here is the screen content, using the TMS components:
%synfiletms.png
And here is the same application compiled using only VCL components, available from {\i Delphi} 6 up to {\i Delphi 10.3 Rio}:
And here is the same application compiled using only VCL components, available from {\i Delphi} 6 up to the latest {\i Delphi} version:
%synfilevcl.png
We did not use yet the Ribbon component as was introduced in {\i Delphi} 2009. Its action-driven design won't make it easy to interface with the event-driven design of our User Interface handling, and we have to confess that this component has rather bad reputation (at least in the {\i Delphi} 2009 version). Feel free to adapt our Open Source code to use it - we'll be very pleased to release a new version supporting it, but we don't have time nor necessity to do it by ourself.
: Enumeration types
@@ -18465,7 +18480,7 @@ But please do not forget to put somewhere in your credit window or documentation
For instance, if you select the MPL license, here are the requirements:
- You accept the license terms with no restriction - see @http://www.mozilla.org/MPL/2.0/FAQ.html for additional information;
- You have to publish any modified unit (e.g. {\f1\fs20 SynTaskDialog.pas}) in a public web site (e.g. {\f1\fs20 http://SoftwareCompany.com/MPL}), with a description of applied modifications, and no removal of the original license header in source code;
- You make appear some notice available in the program (About box, documentation, online help), stating e.g.\line {\i This software uses some third-party code of the Synopse mORMot framework (C) 2020 Arnaud Bouchez - {\f1\fs20 https://synopse.info} - under Mozilla Public License 1.1; modified source code is available at {\f1\fs20 http://SoftwareCompany.com/MPL}.}
- You make appear some notice available in the program (About box, documentation, online help), stating e.g.\line {\i This software uses some third-party code of the Synopse mORMot framework (C) 2022 Arnaud Bouchez - {\f1\fs20 https://synopse.info} - under Mozilla Public License 1.1; modified source code is available at {\f1\fs20 http://SoftwareCompany.com/MPL}.}
: Derivate Open Source works
If you want to include part of the framework source code in your own open-source project, you may publish it with a comment similar to this one (as included in the great {\i DelphiWebScript} project by Eric Grange - @http://code.google.com/p/dwscript ):
${
@@ -18478,7 +18493,7 @@ $
$ Sample based on official mORMot's sample
$ "SQLite3\Samples\09 - HttpApi web server\HttpApiServer.dpr"
$
$ Synopse mORMot framework. Copyright (C) 2020 Arnaud Bouchez
$ Synopse mORMot framework. Copyright (C) 2022 Arnaud Bouchez
$ Synopse Informatique - https://synopse.info
$
$ Original tri-license: MPL 1.1/GPL 2.0/LGPL 2.1