Some regression has been reported with Delphi 10.4.1 and SynPDF. From the Github issue description: Generating a PDF via VLCCanvas and TPdfDocumentGDI causes access violation when compiled with Delphi 10.4.1 with record field alignment compiler option set to "byte" or "off". When […]
Tag - record
2018-11-12
EKON 22 Slides and Code
2018-11-12. Pascal Programming
I've uploaded two sets of slides from my presentations at EKON 22 : Object Pascal Clean Code Guidelines Proposal High Performance Object Pascal Code on Servers with the associated source code The WorkShop about "Getting REST with mORMot" has a corresponding new Samples folder in our […]
2014-08-11
Cross-Platform mORMot Clients - Smart Mobile Studio
2014-08-11. Open Source › mORMot Framework
Current version of the main framework units target only Win32 and Win64 systems.
It allows to make easy self-hosting of mORMot servers for local
business applications in any corporation, or pay cheap hosting in the Cloud,
since mORMot CPU and RAM expectations are much lower than a regular
IIS-WCF-MSSQL-.Net
stack.
But in a Service-Oriented Architecture (SOA), you would probably need
to create clients for platforms outside the Windows world, especially
mobile devices.
A set of cross-platform client units is therefore available in the
CrossPlatform
sub-folder of the source code repository. It allows
writing any client in modern object pascal language, for:
- Any version of Delphi, on any platform (Mac OSX, or any mobile supported devices);
- FreePascal Compiler 2.7.1;
- Smart Mobile Studio 2.1, to create AJAX or mobile applications (via PhoneGap, if needed).
This series of articles will introduce you to mORMot's Cross-Platform abilities:
- Units and platforms;
- Generating the client code wrappers;
- Delphi / FreePascal clients;
- Smart Mobile Studio clients.
Any feedback is welcome in our forum, as usual!
Cross-Platform mORMot Clients - Delphi / FreePascal
2014-08-11. Open Source › mORMot Framework
Current version of the main framework units target only Win32 and Win64 systems.
It allows to make easy self-hosting of mORMot servers for local
business applications in any corporation, or pay cheap hosting in the Cloud,
since mORMot CPU and RAM expectations are much lower than a regular
IIS-WCF-MSSQL-.Net
stack.
But in a Service-Oriented Architecture (SOA), you would probably need
to create clients for platforms outside the Windows world, especially
mobile devices.
A set of cross-platform client units is therefore available in the
CrossPlatform
sub-folder of the source code repository. It allows
writing any client in modern object pascal language, for:
- Any version of Delphi, on any platform (Mac OSX, or any mobile supported devices);
- FreePascal Compiler 2.7.1;
- Smart Mobile Studio 2.1, to create AJAX or mobile applications (via PhoneGap, if needed).
This series of articles will introduce you to mORMot's Cross-Platform abilities:
- Units and platforms;
- Generating the client code wrappers;
- Delphi / FreePascal clients;
- Smart Mobile Studio clients.
Any feedback is welcome in our forum, as usual!
Cross-Platform mORMot Clients - Generating Code Wrappers
2014-08-11. Open Source › mORMot Framework
Current version of the main framework units target only Win32 and Win64 systems.
It allows to make easy self-hosting of mORMot servers for local
business applications in any corporation, or pay cheap hosting in the Cloud,
since mORMot CPU and RAM expectations are much lower than a regular
IIS-WCF-MSSQL-.Net
stack.
But in a Service-Oriented Architecture (SOA), you would probably need
to create clients for platforms outside the Windows world, especially
mobile devices.
A set of cross-platform client units is therefore available in the
CrossPlatform
sub-folder of the source code repository. It allows
writing any client in modern object pascal language, for:
- Any version of Delphi, on any platform (Mac OSX, or any mobile supported devices);
- FreePascal Compiler 2.7.1;
- Smart Mobile Studio 2.1, to create AJAX or mobile applications (via PhoneGap, if needed).
This series of articles will introduce you to mORMot's Cross-Platform abilities:
- Units and platforms;
- Generating the client code wrappers;
- Delphi / FreePascal clients;
- Smart Mobile Studio clients.
Any feedback is welcome in our forum, as usual!
Cross-Platform mORMot Clients - Units and Platforms
2014-08-11. Open Source › mORMot Framework
Current version of the main framework units target only Win32 and Win64 systems.
It allows to make easy self-hosting of mORMot servers for local
business applications in any corporation, or pay cheap hosting in the Cloud,
since mORMot CPU and RAM expectations are much lower than a regular
IIS-WCF-MSSQL-.Net
stack.
But in a Service-Oriented Architecture (SOA), you would probably need
to create clients for platforms outside the Windows world, especially
mobile devices.
A set of cross-platform client units is therefore available in the
CrossPlatform
sub-folder of the source code repository. It allows
writing any client in modern object pascal language, for:
- Any version of Delphi, on any platform (Mac OSX, or any mobile supported devices);
- FreePascal Compiler 2.7.1;
- Smart Mobile Studio 2.1, to create AJAX or mobile applications (via PhoneGap, if needed).
This series of articles will introduce you to mORMot's Cross-Platform abilities:
- Units and platforms;
- Generating the client code wrappers;
- Delphi / FreePascal clients;
- Smart Mobile Studio clients.
Any feedback is welcome in our forum, as usual!
2014-05-18
Automatic JSON serialization of record or dynamic arrays via Enhanced RTTI
2014-05-18. Open Source › mORMot Framework
Since Delphi 2010, the compiler generates additional RTTI at compilation, so
that all record
fields are described, and available at
runtime.
By the way, this enhanced RTTI is one of the reasons why executables did grow
so much in newer versions of the compiler.
Our SynCommons.pas
unit is now able to use this enhanced
information, and let any record
be serialized via
RecordLoad()
and RecordSave()
functions, and all
internal JSON marshalling process.
In short, you have nothing to do.
Just use your record
as parameters, and, with Delphi 2010 and up,
they will be serialized as valid JSON objects.
Of course, text-based
definition or callback-based registration are still at hand, and will be
used with older versions of Delphi.
But you could be used to by-pass or extend the enhanced-RTTI serialization,
even on newer versions of the compiler.
New sample for JSON performance: mORMot vs SuperObject/XSuperObject/dwsJSON/DBXJSON
2014-05-18. Open Source › mORMot Framework
We have just added a new "25 - JSON performance" sample to benchmark JSON process, using well most known Delphi libraries...
A new fight
featuring
mORMot vs SuperObject/XSuperObject/dwsJSON/DBXJSON
On mORMot side, it covers TDocVariant
, late binding,
TSQLTable
, ORM, record access, BSON...
We tried to face several scenarios:
- parse/access/write iteration over a small JSON document,
- read of deeply nested 680 KB JSON (here mORMot is slower than SO/dwsJSON),
- read of one 180 MB JSON file (with on-the-fly adaptation to fit a record layout),
- named access to all rows and columns of a 1 MB JSON table, extracted from a SQL request (with comparison with our ORM performance).
On average and in details, mORMot is the fastest in almost all scenarios (with an amazing performance for table/ORM processing), dwsJSON performs very well (better than SuperObject), and DBXJSON is the slowest (by far, but XE6 version is faster than XE4).
2014-02-25
TDocVariant custom variant type
2014-02-25. Open Source › mORMot Framework
With revision 1.18 of the framework, we just introduced two new custom types
of variant
s:
TDocVariant
kind ofvariant
;TBSONVariant
kind ofvariant
.
The second custom type (which handles MongoDB-specific extensions -
like ObjectID
or other specific types like dates or binary) will
be presented later, when dealing with MongoDB support in
mORMot, together with the BSON kind of content. BSON /
MongoDB support is implemented in the SynMongoDB.pas
unit.
We will now focus on TDocVariant
itself, which is a generic
container of JSON-like objects or arrays.
This custom variant type is implemented in SynCommons.pas
unit, so
is ready to be used everywhere in your code, even without any link to the
mORMot ORM kernel, or MongoDB.
TDocVariant documents
TDocVariant
implements a custom variant type which can be used
to store any JSON/BSON document-based content, i.e. either:
- Name/value pairs, for object-oriented documents;
- An array of values (including nested documents), for array-oriented documents;
- Any combination of the two, by nesting
TDocVariant
instances.
Here are the main features of this custom variant type:
- DOM approach of any object or array documents;
- Perfect storage for dynamic value-objects content, with a schema-less approach (as you may be used to in scripting languages like Python or JavaScript);
- Allow nested documents, with no depth limitation but the available memory;
- Assignment can be either per-value (default, safest but slower when containing a lot of nested data), or per-reference (immediate reference-counted assignment);
- Very fast JSON serialization / un-serialization with support of MongoDB-like extended syntax;
- Access to properties in code, via late-binding (including almost no speed penalty due to our VCL hack as already detailed);
- Direct access to the internal variant names and values
arrays from code, by trans-typing into a
TDocVariantData record
; - Instance life-time is managed by the compiler (like any other
variant
type), without the need to useinterfaces
or explicittry..finally
blocks; - Optimized to use as little memory and CPU resource as possible (in contrast
to most other libraries, it does not allocate one
class
instance per node, but rely on pre-allocated arrays); - Opened to extension of any content storage - for instance, it will perfectly integrate with BSON serialization and custom MongoDB types (ObjectID, RegEx...), to be used in conjunction with MongoDB servers;
- Perfectly integrated with our Dynamic
array wrapper and its JSON serialization as with the
record
serialization; - Designed to work with our mORMot ORM: any
TSQLRecord
instance containing suchvariant
custom types as published properties will be recognized by the ORM core, and work as expected with any database back-end (storing the content as JSON in a TEXT column); - Designed to work with our mORMot SOA: any
interface
-based service is able to consume or publish such kind of content, asvariant
kind of parameters; - Fully integrated with the Delphi IDE: any
variant
instance will be displayed as JSON in the IDE debugger, making it very convenient to work with.
To create instances of such variant
, you can use some
easy-to-remember functions:
_Obj() _ObjFast()
global functions to create avariant
object document;_Arr() _ArrFast()
global functions to create avariant
array document;_Json() _JsonFast() _JsonFmt() _JsonFastFmt()
global functions to create anyvariant
object or array document from JSON, supplied either with standard or MongoDB-extended syntax.
2013-12-10
JSON record serialization
2013-12-10. Open Source › mORMot Framework
In Delphi, the record
has some nice advantages:
record
are value objects, i.e. accessed by value, not by reference - this can be very convenient, e.g. when defining a Domain-Driven Design;record
can contain any otherrecord
or dynamic array, so are very convenient to work with (no need to define sub-classes or lists);record
variables can be allocated on stack, so won't solicit the global heap;record
instances automatically freed by the compiler when they come out of scope, so you won't need to write anytry..finally Free; end
block.
Serialization of record
values are therefore a must-have for a
framework like mORMot.
In recent commits, this JSON serialization of record
has been
enhanced.
In particular, we introduced JSON serialization via a new text-based
record
definition.
2013-10-09
Good old object is not to be deprecated - it is the future
2013-10-09. Pascal Programming
Yes, I know this article title is a huge moment of trolling for most Delphi
developer.
But object
could be legend... - wait for it - ... dary!
You perhaps already noticed by several blog posts
here that I still like the good old (and deprecated) object
type, in addition to the common heap-allocated class
type.
Plain record
with methods does not match the object-oriented
approach of object
, since it does not feature inheritance.
When you take a look at modern strongly-typed languages, targeting concurrent programming (you know, multi-thread/multi-core execution), you will see that the objects may be allocated in several ways, to facilitate execution flow.
The Rust language for instance is pretty interesting. It has optional task-local Garbage Collection and safe pointer types with region analysis.
To some extent, it is very similar to what object
allows in the
Delphi world, and why I'm still using/loving it!
2012-12-31
Enhance existing projects with mORMot
2012-12-31. Open Source › mORMot Framework
Even if mORMot will be more easily used in a project designed from scratch, it fits very well the purpose of evolving any existing Delphi project, or even creating the server side part of an AJAX application.
One benefit of such a framework is to facilitate the transition from a Client-Server architecture to a N-Tier layered pattern.
2012-05-03
Custom JSON serialization of records
2012-05-03. Open Source › mORMot Framework
By default, during interface-based service call,
any record
parameter or function result will be serialized with
our proprietary binary (and optimized layout) - i.e. RecordLoad
and RecordSave
functions - then encoded in Base-64, to be
stored as plain text within the JSON stream.
But custom record JSON serialization can be defined, as with any
class
- see this article - or
dynamic array - see this
article.
2012-04-12
Custom JSON serialization of any dynamic array content
2012-04-12. Open Source › mORMot Framework
One nice feature of the TDynArray
wrapper and its associated
methods, as defined and used in our framework, is the ability to serialize
any dynamic array as JSON content.
By default, only "standard" dynamic arrays (like
TIntegerDynArray
) are serialized as true JSON array: other not
known kind of arrays are serialized as binary content, within a Base64
encoding.
This is a very efficient solution for a pure Delphi application, since it will be fast and always works, but won't be easy to deal with from an AJAX client.
Applications can now supply a custom JSON serialization for any other
dynamic array, via the TTextWriter.RegisterCustomJSONSerializer()
class method.
Two callbacks are to be supplied for a dynamic array type information, in order
to handle proper serialization and un-serialization of the JSON array.
2012-04-10
How function results are allocated
2012-04-10. Pascal Programming
One potential issue with Delphi coding, is about how the result of a functions are implemented.
If you forget to set a result
value to a function, you'll
get a compiler warning.
Never underestimate such warning: IMHO this is not a warning, but an error.
And you should better be aware of the handling of reference-counted types
(e.g. string
) in a function results: those are passed the stack as
var
parameters, so the result of a function may be set
even if an exception is raised during function execution!
2011-12-08
Avoiding Garbage Collector: Delphi and Apple side by side
2011-12-08. Pascal Programming
Among all trolling subject in forums, you'll find out the great Garbage Collection theme.
Fashion languages rely on it. At the core of the .Net and Java framework, and all scripting languages (like JavaScript, Perl, Python or Ruby), you'll find a Garbage Collector. New developers, just released from schools, do learn about handling memory only in theory, and just can't understand how is memory allocated - we all have seen such rookies involved in Delphi code maintenance, leaking memory as much as they type. In fact, most of them did not understood how a computer works. I warned you this will be a trolling subject.
And, in Delphi, there is no such collector. We handle memory in several ways:
- Creating static variables - e.g. on the stack, inside a
class
or globally; - Creating objects with
class
instances allocated on heap - in at least three ways: with atry..finally Free
block, with aTComponent
ownership model in the VCL, or by using aninterface
(which creates an hiddentry..finally Free
block); - Creating reference-counted variables, i.e.
string
,array of
,interface
orvariant
kind of variables.
It is a bit complex, but it is also deadly powerful. You have several memory allocation models at hand, which can be very handy if you want to tune your performance and let program scale. Just like manual recycling at home will save the planet. Some programmers will tell you that it's a waste of cell brain, typing and time. Linux kernel gurus would not say so, I'm afraid.
Then came the big Apple company, which presented its new ARC model (introduced in Mac OS X 10.7 Lion) as a huge benefit for Objective-C in comparison with the Garbage Collection model. And let's face it: this ARC just sounds like the Delphi memory model.
2011-05-24
How to implement RESTful authentication
2011-05-24. Open Source › mORMot Framework
Commonly, it can be achieved, in the SOA over HTTP world via:
- HTTP basic auth over HTTPS;
- Cookies and session management;
- Query Authentication with additional signature parameters.
We'll have to adapt, or even better mix those techniques, to match our framework architecture at best.
Each authentication scheme has its own PROs and CONs, depending on the purpose of your security policy and software architecture.
2011-05-20
How to write fast multi-thread Delphi applications
2011-05-20. Pascal Programming
How to make your software run fast, especially in a multi-threaded architecture?
We tried to remove the Memory Manager scaling problems in our SynScaleMM. It worked as expected in a multi-threaded server environment. Scaling is much better than FastMM4, for some critical tests. But it's not ready for production yet...
To be honest, the Memory Manager is perhaps not the bigger bottleneck in Multi-Threaded applications.
Here are some (not dogmatic, just from experiment and knowledge of low-level Delphi RTL) advice if you want to write FAST multi-threaded application in Delphi.
2011-05-14
Virtual Tables in the SQLite3 framework
2011-05-14. Open Source › mORMot Framework
The SQlite3 engine has ability to create Virtual Tables from code. From the perspective of an SQL statement, the virtual table object looks like any other table or view. But behind the scenes, queries from and updates to a virtual table invoke callback methods on the virtual table object instead of reading and writing to the database file.
The virtual table mechanism allows an application to publish interfaces that
are accessible from SQL statements as if they were tables. SQL statements can
in general do anything to a virtual table that they can do to a real table,
with the following exceptions:
- One cannot create a trigger on a virtual table.
- One cannot create additional indices on a virtual table. (Virtual tables can
have indices but that must be built into the virtual table implementation.
Indices cannot be added separately using CREATE INDEX
statements.)
- One cannot run ALTER TABLE ... ADD COLUMN
commands against a
virtual table.
- Particular virtual table implementations might impose additional constraints.
For example, some virtual implementations might provide read-only tables. Or
some virtual table implementations might allow INSERT
or
DELETE
but not UPDATE
. Or some virtual table
implementations might limit the kinds of UPDATE
s that can be
made.
Example of virtual tables, already included in the SQLite3 engine,
are FTS or
RTREE tables. A
custom virtual table might represent in-memory data structures (like
TSQLVirtualTableJSON, TSQLVirtualTableBinary
). Or it might
represent a view of data on disk that is not in the SQLite3 format
(e.g. TSQLVirtualTableLog
). Or the application might compute the
content of the virtual table on demand.
Thanks to the generic implementation of Virtual Table in SQLite3,
you can use such tables in your SQL statement, and even safely execute a
SELECT
statement with JOIN
or custom functions,
mixing normal SQLite3 tables and any other Virtual Table.
A dedicated mechanism has been added to the framework, beginning with revision 1.13, in order to easily add such virtual tables with pure Delphi code, just by inheriting some classes.
2011-03-12
TDynArray and Record compare/load/save using fast RTTI
2011-03-12. Pascal Programming
The SynCommons unit has been enhanced:
- new BinToBase64
and Base64ToBin
conversion
functions;
- new low-level RTTI functions for handling record types: RecordEquals,
RecordSave, RecordSaveLength, RecordLoad
;
- new TDynArray
object, which is a wrapper around any dynamic
array.
With TDynArray
, you can access any dynamic array (like
TIntegerDynArray = array of integer
) using TList
-like
properties and methods, e.g. Count, Add, Insert, Delete, Clear, IndexOf,
Find, Sort
and some new methods like LoadFromStream, SaveToStream,
LoadFrom
and SaveTo
which allow fast binary serialization
of any dynamic array, even containing strings or records - a
CreateOrderedIndex
method is also available to create individual
index according to the dynamic array content. You can also serialize the array
content into JSON, if you wish.
What I like with dynamic arrays is that they are reference-counted, don't
need any Create/try..finally...Free
code, and are well handled by
the Delphi compiler.
They are no replacement to a TCollection
nor a
TList
(which are the standard and efficient way of storing
class instances), but they are very handy way of having a list of content or a
dictionary at hand, with no class nor properties definition.
You can look at them like Python's list, tuples (via records handling) and
dictionaries (via Find
method), in pure Delphi. Our new methods
(about searching and serialization) allow most usage of those script-level
structures in your Delphi code.