<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.synopse.info/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Synopse</title>
  <link>http://blog.synopse.info/</link>
  <atom:link href="http://blog.synopse.info:82/feed/rss2" rel="self" type="application/rss+xml"/>
  <description>&quot;Synopse Informatique&quot; Software solutions, and associated open source database and low level components.</description>
  <language>en</language>
  <pubDate>Tue, 07 Feb 2012 08:10:51 +0100</pubDate>
  <copyright>©2011 Synopse Informatique</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Modification of TSQLRestServerCallBack method prototype (bis)</title>
    <link>http://blog.synopse.info/post/2012/02/06/Modification-of-TSQLRestServerCallBack-method-prototype-%28bis%29</link>
    <guid isPermaLink="false">urn:md5:10f254201cab56ddc873b659a9dcca06</guid>
    <pubDate>Mon, 06 Feb 2012 22:05:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>authentication</category><category>Delphi</category><category>Documentation</category><category>JSON</category><category>mORMot</category><category>Rest</category><category>security</category><category>session</category><category>SOA</category>    
    <description>In order to implement some RESTful Services, a &lt;a href=&quot;http://blog.synopse.info/post/2010/07/18/DataSnap-like-Client-Server-JSON-RESTful-Services-in-Delphi-7-2010&quot;&gt;
callback has to be defined on the server side&lt;/a&gt;.
&lt;p&gt;The prototype of these methods has been modified one more time, to supply an
unique parameter:&lt;br /&gt;
&lt;strong&gt;This is a CODE BREAK change and you shall refresh ALL your server-side
code to match the new signature&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This unique parameter will let the signature remain untouched in your code
implementation, even if the framework evolves (like adding a new
parameter).&lt;/p&gt;    &lt;p&gt;Here is the updated declaration of the class:&lt;/p&gt;
&lt;pre&gt;
TSQLRestServerTest = &lt;strong&gt;class&lt;/strong&gt;(TSQLRestServerDB)
  &lt;strong&gt;published&lt;/strong&gt;
    &lt;strong&gt;function&lt;/strong&gt; Sum(&lt;strong&gt;var&lt;/strong&gt; aParams: TSQLRestServerCallBackParams): Integer;
  &lt;strong&gt;end&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;This method name will be used for the URL encoding, and will be called here
with &lt;em&gt;ModelRoot/Sum&lt;/em&gt; URL. The &lt;em&gt;ModelRoot&lt;/em&gt; is the one defined in
the &lt;code&gt;Root&lt;/code&gt; parameter of the &lt;em&gt;model&lt;/em&gt; used by the
application.&lt;/p&gt;
&lt;p&gt;This method, like all Server-side methods, MUST have all parameters of the
&lt;code&gt;TSQLRestServerCallBack&lt;/code&gt; prototype:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;type&lt;/strong&gt;
  TSQLRestServerCallBack = &lt;strong&gt;function&lt;/strong&gt;(&lt;strong&gt;var&lt;/strong&gt; aParams: TSQLRestServerCallBackParams): Integer &lt;strong&gt;of object&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;Then we implement this method:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;function&lt;/strong&gt; TSQLRestServerTest.Sum(&lt;strong&gt;var&lt;/strong&gt; aParams: TSQLRestServerCallBackParams): Integer;
&lt;strong&gt;var&lt;/strong&gt; a,b: Extended;
&lt;strong&gt;begin&lt;/strong&gt;
  &lt;strong&gt;if not&lt;/strong&gt; UrlDecodeNeedParameters(aParams.Parameters,'A,B') &lt;strong&gt;then&lt;/strong&gt;
  &lt;strong&gt;begin&lt;/strong&gt;
    result := 404; &lt;em&gt;// invalid Request&lt;/em&gt;
    exit;
  &lt;strong&gt;end&lt;/strong&gt;;
  &lt;strong&gt;while&lt;/strong&gt; aParameters&amp;lt;&amp;gt;&lt;strong&gt;nil do&lt;/strong&gt;
  &lt;strong&gt;begin&lt;/strong&gt;
    UrlDecodeExtended(aParams.Parameters,'A=',a);
    UrlDecodeExtended(aParams.Parameters,'B=',b,@aParams.Parameters);
  &lt;strong&gt;end&lt;/strong&gt;;
  aParams.Resp := JSONEncodeResult([a+b]);
  &lt;em&gt;// same as : aResp := JSONEncode(['result',a+b],TempMemoryStream);&lt;/em&gt;
  result := 200; &lt;em&gt;// success&lt;/em&gt;
&lt;strong&gt;end&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;On the Server side, you can use the &lt;code&gt;UrlDecodeNeedParameters&lt;/code&gt;
function to check that an expected parameters were supplied by the caller, then
call &lt;code&gt;UrlDecodeInteger / UrlDecodeInt64 / UrlDecodeExtended /
UrlDecodeValue&lt;/code&gt; functions (all defined in &lt;code&gt;SynCommons.pas&lt;/code&gt;) to
retrieve each individual parameter as standard JSON content. The powerful
&lt;code&gt;UrlDecodeObject&lt;/code&gt; function (defined in
&lt;code&gt;SQLite3Commons.pas&lt;/code&gt;) can be used to unserialize most class instance
from its textual JSON representation. Note that due to this implementation
pattern, the mORMot service implementation is very fast, and not sensitive to
the &amp;quot;Hash collision attack&amp;quot; security issue, as reported with &lt;em&gt;Apache&lt;/em&gt; -
see &lt;a href=&quot;http://blog.synopse.info/post/2011/12/30/Hash-collision-attack&quot;&gt;this blog
entry&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;aParams.Session&lt;/code&gt; parameter may contain at calling time the
current session identifier. If authentication is not used, this parameter is
meaningless. Server-side implementation can use the
&lt;code&gt;TSQLRestServer.SessionGetUser&lt;/code&gt; method to retrieve the corresponding
user details (the returned &lt;code&gt;TSQLAuthUser&lt;/code&gt; instance is a local
thread-safe copy which shall be freed when done).&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;aParams.Head&lt;/code&gt; parameter may be overridden on the server side
to set a custom header which will be provided to the client - it may be useful
for instance to specify another mime-type than the default constant
&lt;code&gt;JSON_CONTENT_TYPE&lt;/code&gt;, i.e. &lt;code&gt;'application/json;
charset=UTF-8'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=3468#p3468&quot;&gt;use
the forum to ask additional questions&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Microsoft states: OleDB out - enjoy ODBC!</title>
    <link>http://blog.synopse.info/post/2012/02/29/Microsoft-states%3A-OleDB-out-enjoy-ODBC%21</link>
    <guid isPermaLink="false">urn:md5:5afe9bc5b7c254bbfaae69595eaa579a</guid>
    <pubDate>Sun, 29 Jan 2012 14:30:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>blog</category><category>CrossPlatform</category><category>Database</category><category>Delphi</category><category>mORMot</category><category>MSSQL</category><category>ODBC</category><category>OleDB</category><category>Oracle</category><category>ORM</category><category>SQL</category><category>SQLite3</category>    
    <description>&lt;p&gt;For our native connection to any DB, we &lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;developed a set of
classes and several units&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We implemented at first &lt;a href=&quot;http://blog.synopse.info/post/2011/06/27/SynOleDB%3A-OpenSource-Unit-for-direct-access-to-any-database-via-OleDB&quot;&gt;
OleDB&lt;/a&gt;, then native &lt;a href=&quot;http://blog.synopse.info/post/2011/07/09/SynDBOracle%3A-Open-Source-native-Oracle-access&quot;&gt;Oracle
direct access&lt;/a&gt; and &lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;SQlite3 static&lt;/a&gt;
engine.&lt;/p&gt;
&lt;p&gt;Now, Microsoft is officially deprecating &lt;em&gt;OleDB&lt;/em&gt;, and urge
all developers to switch to the open and cross-platform &lt;em&gt;ODBC
API &lt;/em&gt;for native connection.&lt;/p&gt;    &lt;p&gt;It is worth reading &lt;a href=&quot;http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx&quot;&gt;
the official announcement from Microsoft&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Microsoft is Aligning with ODBC for Native Relational Data
Access&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;We encourage you to adopt ODBC in the development of your new and future
versions of your application. You don’t need to change your existing
applications using OLE DB, as they will continue to be supported on Denali
throughout its lifecycle. While this gives you a large window of opportunity
for changing your applications before the deprecation goes into effect, you may
want to consider migrating those applications to ODBC as a part of your future
roadmap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They created OLE DB to make a &amp;quot;pure Windows&amp;quot; concurrent of ODBC.&lt;br /&gt;
We were told that OLE DB was much better than ODBC, by Micro$oft
evangelists.&lt;/p&gt;
&lt;p&gt;Now they are going back to ODBC because Cross-Platform is now mandatory.
This is all marketing and money here. This won't be the first abandoned
technology from Microsoft (or any other company).&lt;/p&gt;
&lt;p&gt;Open source is another world, even if money is still within, you can always
fork a dead project to continue supporting it.&lt;/p&gt;
&lt;p&gt;In fact, OleDB was mostly about using MS SQL under Windows.&lt;br /&gt;
Oracle provider is buggy - no cry for me...&lt;/p&gt;
&lt;p&gt;I'm working on adding ODBC support for our SynDB classes.&lt;br /&gt;
This will be necessary for (Linux and) Mac OS support of DBs other than Oracle
or SQLite3.&lt;br /&gt;
Follow the evolution of the new &lt;a href=&quot;http://synopse.info/fossil/finfo?name=SynDBODBC.pas&quot;&gt;SynDBODBC.pas
unit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Feel free to &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=3432#p3432&quot;&gt;discuss about it in
our forum&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>SynDBExplorer fast direct export</title>
    <link>http://blog.synopse.info/post/2012/01/17/SynDBExplorer-fast-direct-export</link>
    <guid isPermaLink="false">urn:md5:9759c7b020a82bba71af8bc8827dde7b</guid>
    <pubDate>Tue, 17 Jan 2012 23:02:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Open Source libraries</category>
        <category>blog</category><category>Database</category><category>Delphi</category><category>OleDB</category><category>Oracle</category><category>performance</category><category>Source</category><category>SQL</category><category>SQLite3</category>    
    <description>&lt;p style=&quot;margin-top: 0;&quot;&gt;The Open Source &lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;SynDBExplorer&lt;/a&gt; tool
has been enhanced these days.&lt;/p&gt;
&lt;p&gt;Main new features are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Execution of the current selected text (if any) instead of the whole memo
content;&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;em&gt;Exec &amp;amp; Export&lt;/em&gt;&amp;quot; new button, for direct export to file.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;I really like the &lt;em&gt;selection execution&lt;/em&gt; feature - this speed up SQL
process a lot, and allow to switch from one statement to another.&lt;br /&gt;
And the new exporting features are opening new possibilities.&lt;/div&gt;    &lt;p&gt;In particular, the &amp;quot;&lt;em&gt;Exec &amp;amp; Export&lt;/em&gt;&amp;quot; new button is able to
export any SQL statement result into:&lt;/p&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Regular CSV file (ready to be imported in Excel);&lt;/li&gt;
&lt;li&gt;Regular TXT file (columns are separated with a tab character);&lt;/li&gt;
&lt;li&gt;Standard JSON content (ready for any AJAX application);&lt;/li&gt;
&lt;li&gt;Our more compact JSON format (column names are not duplicated on each
row);&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Synopse BigTable&lt;/em&gt; records (with fixed sized records for integers
columns);&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Synopse BigTable&lt;/em&gt; records (with variable-length records for
integers columns);&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;SQLite3&lt;/em&gt; database file (creating a table with all necessary
columns).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This direct export feature won't use a temporary memory buffer, just with
the regular &amp;quot;&lt;em&gt;Export&lt;/em&gt;&amp;quot; button, which exports the grid on screen.&lt;br /&gt;
Therefore, it will be faster, and will be able to handle any amount of data.
You can export gigabytes of data directly from the tool, then consume it
offline as regular &lt;em&gt;SQLite3&lt;/em&gt; tables or very efficient &lt;a href=&quot;http://blog.synopse.info/post/2011/01/22/Synopse-Big-Table-1.12a&quot;&gt;&lt;em&gt;Synopse
BigTable&lt;/em&gt; records&lt;/a&gt;. With a map &amp;amp; reduce architecture, it can be
very handy to process huge amount of data. Or it can be used to convert an
existing database layout into a &lt;em&gt;SQLite3&lt;/em&gt; database&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Thanks to these enhancements, this little tool begins to be a very nice SQL
and database management tool.&lt;/p&gt;
&lt;p&gt;All this is made possible due to the unique architecture of our
&lt;em&gt;SynDB&lt;/em&gt; classes. Their design appears to be powerful and open, at the
same time: it allows &lt;a href=&quot;http://synopse.info/fossil/fdiff?v1=63e5ce5a727fb868&amp;amp;v2=c7d227d26119b35a&quot;&gt;easy
mix of very diverse data structures like &lt;em&gt;BigTable&lt;/em&gt; or
&lt;em&gt;SQLite3&lt;/em&gt;&lt;/a&gt;, far away from the RAD layout.&lt;/p&gt;
&lt;p&gt;A visual &lt;em&gt;Query Designer&lt;/em&gt; is also in alpha stage (select several
tables, then right click on your mouse), and will become a powerful entry point
for the &lt;a href=&quot;http://blog.synopse.info/post/2011/06/09/Close-future-of-the-framework%3A-database-agnosticism&quot;&gt;database
reverse engineering&lt;/a&gt; of our &lt;em&gt;mORMot&lt;/em&gt; framework (i.e. the upcoming
&lt;code&gt;TSQLRecordMapped*&lt;/code&gt; classes). Up to now, you can JOIN visualy your
tables with this right-click approach. But it will shortly become a powerful
way of managing any RDBMS as objects.&lt;/p&gt;
&lt;p&gt;Feedback and comments are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=585&quot;&gt;welcome in our forum&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Hash collision attack</title>
    <link>http://blog.synopse.info/post/2011/12/30/Hash-collision-attack</link>
    <guid isPermaLink="false">urn:md5:a504832ce9ecf7a9a7cdff231fd3f96a</guid>
    <pubDate>Fri, 30 Dec 2011 10:49:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>authentication</category><category>blog</category><category>Delphi</category><category>GoodPractice</category><category>HTTP</category><category>mORMot</category><category>security</category>    
    <description>&lt;p&gt;A variety of programming languages suffer from a denial-of-service (DoS)
condition against storage functions of key/value pairs in hash data structures,
the condition can be leveraged by exploiting predictable collisions in the
underlying hashing algorithms.&lt;/p&gt;
&lt;p&gt;The issue finds particular exposure in web server applications and/or
frameworks. In particular, the lack of sufficient limits for the number of
parameters in POST requests in conjunction with the predictable collision
properties in the hashing functions of the underlying languages can render web
applications vulnerable to the DoS condition. The attacker, using specially
crafted HTTP requests, can lead to a 100% of CPU usage which can last up to
several hours depending on the targeted application and server performance, the
amplification effect is considerable and requires little bandwidth and time on
the attacker side.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: &lt;a href=&quot;http://www.ocert.org/advisories/ocert-2011-003.html&quot;&gt;#2011-003 multiple
implementations denial-of-service via hash algorithm collision&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;How will our &lt;em&gt;mORMot&lt;/em&gt; framework handle such DOS attacks?&lt;/p&gt;
&lt;p&gt;The current implementation of parameters parsing is not using a hash table,
nor using any storage list.&lt;/p&gt;
&lt;p&gt;The parameters are parsed and checked only once. No global list is created,
just to avoid such DOS problems.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Strong-typing just rocks</title>
    <link>http://blog.synopse.info/post/2011/12/11/Strong-typing-just-rocks</link>
    <guid isPermaLink="false">urn:md5:1facd1367516300e60f8bc76b83b72c3</guid>
    <pubDate>Sun, 11 Dec 2011 09:59:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>Delphi</category><category>dynamic array</category><category>GoodPractice</category><category>mORMot</category><category>Source</category><category>Unicode</category><category>UserInterface</category>    
    <description>&lt;p&gt;To my understanding, the so-called &amp;quot;strong-typing&amp;quot; feature is one big
benefit of the Delphi object pascal language.&lt;/p&gt;
&lt;p&gt;As stated by &lt;a href=&quot;http://en.wikipedia.org/wiki/Strong_typing&quot;&gt;wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Most generally, &amp;quot;strong typing&amp;quot; implies that the programming language places
severe restrictions on the intermixing that is permitted to occur, preventing
the compiling or running of source code which uses data in what is considered
to be an invalid way. For instance, an addition operation may not be used with
an integer and string values; a procedure which operates upon linked lists may
not be used upon numbers. However, the nature and strength of these
restrictions is highly variable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some Delphi users may find this is a limitation of the language, in
comparison with other &amp;quot;fashionable&amp;quot; script idioms (like Python, Javascript of
Ruby). For me, runtime strong typing (alla Python or Ruby) is not true strong
typing. &lt;a href=&quot;http://www.simonjstuart.com/2011/12/10/lksl-smart-types/&quot;&gt;Simon Stuart just
proposed&lt;/a&gt; a &lt;code&gt;smartstring&lt;/code&gt; kind of string, which is in fact a
&lt;code&gt;weakstring&lt;/code&gt; type. As far as I understood his point, he wanted to
get rid of all the warnings emitted by Unicode-version of the Delphi compiler,
about explicit &lt;code&gt;string&lt;/code&gt; conversion.&lt;/p&gt;
&lt;p&gt;In fact, I use to go in the opposite direction. For wide projects,
strong-typing is one of the big benefit of using Delphi (like other main
&amp;quot;serious&amp;quot; languages like Java, C, C++, Ada or C#).&lt;/p&gt;    &lt;p&gt;Our &lt;em&gt;SQLite3/mORMot&lt;/em&gt; Framework has 100% UNICODE compatibility, that
is compilation under Delphi 2009/2010/XE/XE2. The code has been deeply
rewritten and tested, in order to provide compatibility with the
&lt;code&gt;String=UnicodeString&lt;/code&gt; paradigm of these compilers. But the code
will also handle safely Unicode for older version, i.e. from Delphi 6 up to
Delphi 2007.&lt;/p&gt;
&lt;p&gt;Since our framework is natively UTF-8 (this is the better character encoding
for fast text - JSON - streaming/parsing and it is natively supported by the
&lt;em&gt;SQLite3&lt;/em&gt; engine), we had to establish a secure way our framework used
strings, in order to handle all versions of Delphi (even pre-Unicode versions,
especially the Delphi 7 version we like so much), and provide compatibility
with the Free Pascal Compiler.&lt;/p&gt;
&lt;p&gt;Some string types have been defined, and used in the code for best
cross-compiler efficiency (avoiding most conversion between formats):&lt;br /&gt;
- &lt;code&gt;RawUTF8&lt;/code&gt; is used for every internal data usage, since both
&lt;em&gt;SQLite3&lt;/em&gt; and JSON do expect UTF-8 encoding;&lt;br /&gt;
- &lt;code&gt;WinAnsiString&lt;/code&gt; where &lt;em&gt;WinAnsi&lt;/em&gt;-encoded
&lt;code&gt;AnsiString&lt;/code&gt; (code page 1252) are needed;&lt;br /&gt;
- Generic &lt;code&gt;string&lt;/code&gt; for &lt;em&gt;i18n&lt;/em&gt; (e.g. in unit
&lt;code&gt;SQLite3i18n&lt;/code&gt;), i.e. text ready to be used within the VCL, as either
&lt;code&gt;AnsiString&lt;/code&gt; (for Delphi 2 to 2007) or &lt;code&gt;UnicodeString&lt;/code&gt;
(for Delphi 2009/2010/XE/XE2);&lt;br /&gt;
- &lt;code&gt;RawUnicode&lt;/code&gt; in some technical places (e.g. direct Win32 *W() API
call in Delphi 7) - note: this type is NOT compatible with Delphi
2009/2010/XE/XE2 &lt;code&gt;UnicodeString&lt;/code&gt;;&lt;br /&gt;
- &lt;code&gt;RawByteString&lt;/code&gt; for byte storage (e.g. for
&lt;code&gt;FileFromString()&lt;/code&gt; function);&lt;br /&gt;
- &lt;code&gt;SynUnicode&lt;/code&gt; is the fastest available Unicode &lt;em&gt;native&lt;/em&gt;
string type, depending on the compiler used (i.e. &lt;code&gt;WideString&lt;/code&gt;
before Delphi 2009, and &lt;code&gt;UnicodeString&lt;/code&gt; since);&lt;br /&gt;
- Some special conversion functions to be used for Delphi 2009/2010/XE/XE2
&lt;code&gt;UnicodeString&lt;/code&gt; (defined inside &lt;code&gt;$ifdef UNICODE...$endif&lt;/code&gt;
blocks);&lt;br /&gt;
- Never use &lt;code&gt;AnsiString&lt;/code&gt; directly, but one of the types above.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;RawUTF8&lt;/code&gt; is the preferred &lt;code&gt;string&lt;/code&gt; type to
be used in our framework when defining textual properties in a
&lt;code&gt;TSQLRecord&lt;/code&gt; and for all internal data processing. It's only when
you're reaching the User Interface layer that you may convert explicitly the
&lt;code&gt;RawUTF8&lt;/code&gt; content into the generic VCL &lt;code&gt;string&lt;/code&gt; type,
using either the &lt;code&gt;Language. UTF8ToString&lt;/code&gt; method (from
&lt;code&gt;SQLite3i18n.pas&lt;/code&gt; unit) or the following function from
&lt;code&gt;SynCommons.pas&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
&lt;em&gt;/// convert any UTF-8 encoded String into a generic VCL Text
// - it's prefered to use TLanguageFile.UTF8ToString() in SQLite3i18n,
// which will handle full i18n of your application
// - it will work as is with Delphi 2009/2010/XE/XE2 (direct unicode conversion)
// - under older version of Delphi (no unicode), it will use the
// current RTL codepage, as with WideString conversion (but without slow
// WideString usage)&lt;/em&gt;
&lt;strong&gt;function&lt;/strong&gt; UTF8ToString(&lt;strong&gt;const&lt;/strong&gt; Text: RawUTF8): &lt;strong&gt;string&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;Of course, the &lt;code&gt;StringToUTF8&lt;/code&gt; method or function are available to
send back some text to the ORM layer.&lt;br /&gt;
A lot of dedicated conversion functions (including to/from numerical values)
are included in &lt;code&gt;SynCommons.pas&lt;/code&gt;. Those were optimized for speed and
multi-thread capabilities, and to avoid implicit conversions involving a
temporary &lt;code&gt;string&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;In fact, this enforce the &lt;a href=&quot;http://blog.synopse.info/post/2010/08/19/How-to-implement-multi-tier-architecture-in-our-SQLite3-Framework&quot;&gt;
n-tier layered architecture&lt;/a&gt; of the project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RawUTF8&lt;/code&gt; is to be used at &lt;em&gt;Storage&lt;/em&gt; and &lt;em&gt;Business
layers&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt; type for the &lt;em&gt;User Interface&lt;/em&gt; (at the VCL
level). &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Warnings during the compilation process are not allowed, especially under
Unicode version of Delphi (e.g. Delphi 2010): all string conversion from the
types above are made explicitly in the framework's code, to avoid any
unattended data loss.&lt;/p&gt;
&lt;p&gt;With such an implementation pattern, we keep all our code benefit from the
strong typing feature of Delphi, whereas we can handle safely Unicode content
even with older &lt;em&gt;Ansi&lt;/em&gt; versions of Delphi.&lt;/p&gt;
&lt;p&gt;Comments are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=545&quot;&gt;welcome on our forum&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Avoiding Garbage Collector: Delphi and Apple side by side</title>
    <link>http://blog.synopse.info/post/2011/12/08/Avoiding-Garbage-Collector%3A-Delphi-and-Apple-on-the-same-side</link>
    <guid isPermaLink="false">urn:md5:32169692ebe86876ffc1bee02c4bc4a6</guid>
    <pubDate>Thu, 08 Dec 2011 10:09:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>Delphi</category><category>dynamic array</category><category>GarbageCollector</category><category>GoodPractice</category><category>interface</category><category>object</category><category>performance</category><category>record</category><category>Source</category><category>SynScaleMM</category><category>TDynArray</category><category>VMT</category>    
    <description>&lt;p&gt;Among all &lt;em&gt;trolling&lt;/em&gt; subject in forums, you'll find out the
great &lt;em&gt;Garbage Collection&lt;/em&gt; theme.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;And, in &lt;em&gt;Delphi&lt;/em&gt;, there is no such collector. We handle memory in
several ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating static variables - e.g. on the stack, inside a &lt;code&gt;class&lt;/code&gt;
or globally;&lt;/li&gt;
&lt;li&gt;Creating objects with &lt;code&gt;class&lt;/code&gt; instances allocated on heap - in
at least three ways: with a &lt;code&gt;try..finally Free&lt;/code&gt; block, with a
&lt;code&gt;TComponent&lt;/code&gt; ownership model in the VCL, or by using
an &lt;code&gt;interface&lt;/code&gt; (which creates an hidden &lt;code&gt;try..finally
Free&lt;/code&gt; block);&lt;/li&gt;
&lt;li&gt;Creating reference-counted variables, i.e. &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;array
of&lt;/code&gt;, &lt;code&gt;interface&lt;/code&gt; or &lt;code&gt;variant&lt;/code&gt; kind of
variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Then came the big &lt;em&gt;Apple&lt;/em&gt; company, which presented its new ARC model
(introduced in Mac OS X 10.7 Lion) as a huge benefit for
&lt;em&gt;Objective-C&lt;/em&gt; in comparison with the Garbage Collection model. And
let's face it: this ARC just sounds like the &lt;em&gt;Delphi&lt;/em&gt; memory model.&lt;/p&gt;    &lt;h3&gt;What is this ARC model?&lt;/h3&gt;
&lt;p&gt;No, ARC is not only an old packer format, nor the company responsible of
&lt;a href=&quot;http://www.arcdisposal.com/&quot;&gt;solid waste removal and recycling
services for Chicago and suburbs&lt;/a&gt; - this acronym stands for &lt;em&gt;Automatic
Reference Counting&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Formerly, class instances used to be manually handled in &lt;em&gt;Objective
C&lt;/em&gt; code. You had to call explicitly the &lt;code&gt;Release&lt;/code&gt; method
to decrement its reference count. When an object's reference count is
zero, it is deallocated.&lt;/p&gt;
&lt;p&gt;This sounds just like our well known reference-counting mechanism included
in &lt;em&gt;Delphi&lt;/em&gt;, for &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;array of&lt;/code&gt;,
&lt;code&gt;interface&lt;/code&gt; or &lt;code&gt;variant&lt;/code&gt;. What is new with ARC is that,
as with these &lt;em&gt;Delphi&lt;/em&gt; types, the compiler will generate the
&lt;em&gt;release&lt;/em&gt; code. And all those kind of variable instanced are filled with
zero (this is not the same as the famous &lt;a href=&quot;http://lists.apple.com/archives/objc-language/2011/Jun/msg00013.html&quot;&gt;Zeroing
Weak pointers&lt;/a&gt; feature) - which is implemented by
&lt;code&gt;_InitializeRecord()&lt;/code&gt; and &lt;code&gt;_FinalizeRecord()&lt;/code&gt; in
low-level &lt;code&gt;System.pas&lt;/code&gt; unit. Of course, the ARC implementation is
certainly more sophisticated than the basic implementation in the
&lt;em&gt;Delphi&lt;/em&gt; compiler: it is told (at least from the marketing paper point
of view) to use some deep knowledge of the software architecture to provide an
accurate access to all instances. Whereas the Delphi compiler just relies on a
&lt;em&gt;out-of-scope&lt;/em&gt; pattern.&lt;/p&gt;
&lt;p&gt;There is a very interesting analysis of the ARC design available on &lt;a href=&quot;http://arstechnica.com/apple/reviews/2011/07/mac-os-x-10-7.ars/11&quot;&gt;Ars
Technica&lt;/a&gt;, which is worth reading. Especially on modest hardware (I do not
know if it is honest when this concept is applied to modern smartphones,
which are much more powerful than the PCs on which the first Delphi version was
running on), Apple's experts say it does make a difference, in term of memory
use and program latency - the UI won't glitch during background garbage
recycling.&lt;/p&gt;
&lt;h3&gt;So what about the issues?&lt;/h3&gt;
&lt;p&gt;This just sounds too much perfect. And there is no perfection on earth, nor
in computing.&lt;/p&gt;
&lt;p&gt;One common problem with reference counting is the
potential &lt;em&gt;circular reference&lt;/em&gt; issue.&lt;/p&gt;
&lt;p&gt;This occurs when one object has a strong pointer to another, but the target
object has a strong pointer back to the original. Even when all other
references to these objects are removed, they still will hold on to one another
and will not be released. This can also happen indirectly, by a chain of
objects that might have the last one in the chain referring back to an earlier
object.&lt;/p&gt;
&lt;p&gt;This is where the ARC's &lt;em&gt;Zeroing Weak pointers&lt;/em&gt; comes to mind. When
you read the &lt;a href=&quot;http://clang.llvm.org/docs/AutomaticReferenceCounting.html&quot;&gt;official reference
material at llvm.org&lt;/a&gt;, there are also some other potential issues, but the
&lt;code&gt;__weak&lt;/code&gt; ownership qualifier is the main point of this document.&lt;/p&gt;
&lt;p&gt;The implementation pattern is a bit more complex that the one used for
&lt;em&gt;Delphi&lt;/em&gt;'s &lt;code&gt;interface&lt;/code&gt; (taken from &lt;em&gt;Ars
Technica&lt;/em&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &amp;quot;zeroing&amp;quot; part means that weak references will be set to nil when the
object they reference is deallocated. (Under ARC, all object pointers are
initially set to zero.) Under normal circumstances, an object shouldn't be
deallocated if there are still outstanding references to it. But since weak
references don't contribute to an object's reference count, an object can be
deallocated when there are outstanding weak references to it. When this
happens, the automatic zeroing of the outstanding weak references prevents them
from becoming dangling pointers. (In Objective-C, sending a message to nil is a
no-op.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As far as I understood the problem, simple types like our reference-counted
&lt;em&gt;Delphi&lt;/em&gt; variables solve the circular reference issue by providing a
copy-on-write behavior. But the &lt;code&gt;interface&lt;/code&gt; kind of variable, in its
current state, may suffer from this issue.&lt;/p&gt;
&lt;p&gt;Since I want to use &lt;code&gt;interface&lt;/code&gt; everywhere in our &lt;a href=&quot;http://synopse.info/fossil/wiki?name=RoadMap&quot;&gt;next version of mORMot&lt;/a&gt; (to
implement a true &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-driven_design&quot;&gt;Domain-Driven&lt;/a&gt; architecture
- including &lt;a href=&quot;http://blog.synopse.info/post/2011/11/27/SOLID-design-principles&quot;&gt;SOLID&lt;/a&gt;
principles), some strict rules may be defined in its usage, not to suffer from
similar issues. To my understanding, as soon as you use interfaces in the
internal scope of methods (i.e. stack-allocated), you may never suffer for
circular reference.&lt;/p&gt;
&lt;p&gt;Additional investigation is certainly needed.&lt;br /&gt;
Your feedback is warmly &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=543&quot;&gt;welcome on our forum&lt;/a&gt;!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Automatic JOIN query</title>
    <link>http://blog.synopse.info/post/2011/12/06/Automatic-JOIN-query</link>
    <guid isPermaLink="false">urn:md5:291676f0945a0ca1c826eb12a7671b84</guid>
    <pubDate>Tue, 06 Dec 2011 22:08:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>Database</category><category>Delphi</category><category>hasmany</category><category>mORMot</category><category>object</category><category>ORM</category><category>Parsing</category><category>Source</category><category>SQL</category><category>SQLite3</category>    
    <description>&lt;p&gt;In &lt;em&gt;mORMot&lt;/em&gt;, all the methods available to handle &lt;a href=&quot;http://blog.synopse.info/post/2010/10/28/%22has-many%22-and-%22has-many-through%22-relationships&quot;&gt;many-to-many
relationship&lt;/a&gt; (&lt;code&gt;ManySelect, DestGetJoined...&lt;/code&gt;) are used to
retrieve the relations between tables from the pivot table point of view. This
saves bandwidth, and can be used in most simple cases, but it is not the only
way to perform requests on many-to-many relationships. And you may have several
&lt;code&gt;TSQLRecordMany&lt;/code&gt; instances in the same main record - in this case,
those methods won't help you.&lt;/p&gt;
&lt;p&gt;It is very common, in the SQL world, to create a JOINed request at the main
&amp;quot;&lt;em&gt;Source&lt;/em&gt;&amp;quot; table level, and combine records from two or more tables in a
database. It creates a set that can be saved as a table or used as is. A JOIN
is a means for combining fields from two or more tables by using values common
to each. Writing such JOINed statements is not so easy by hand, especially
because you'll have to work with several tables, and have to specify the exact
fields to be retrieved; if you have several pivot tables, it may start to be a
nightmare.&lt;/p&gt;
&lt;p&gt;Let's see how our ORM will handle it.&lt;/p&gt;    &lt;p&gt;A dedicated &lt;code&gt;FillPrepareMany&lt;/code&gt; method has been added to the
&lt;code&gt;TSQLRecord&lt;/code&gt; class, in conjunction with a new
&lt;code&gt;constructor&lt;/code&gt; named &lt;code&gt;CreateAndFillPrepareMany&lt;/code&gt;. This
particular method will:&lt;br /&gt;
- Instantiate all &lt;code&gt;Dest&lt;/code&gt; properties of each
&lt;code&gt;TSQLRecordMany&lt;/code&gt; instances - so that the JOINed request will be able
to populate directly those values;&lt;br /&gt;
- Create the appropriate &lt;code&gt;SELECT&lt;/code&gt; statement, with an optional WHERE
clause.&lt;/p&gt;
&lt;p&gt;Here is the corresponding test included in our regression suite:&lt;/p&gt;
&lt;pre&gt;
Check(MS.FillPrepareMany(aClient,
  'DestList.Dest.SignatureTime&amp;lt;&amp;gt;% and id&amp;gt;=? and DestList.AssociationTime&amp;lt;&amp;gt;0 '+
  'and SignatureTime=DestList.Dest.SignatureTime '+
  'and DestList.Dest.Signature&amp;lt;&amp;gt;&amp;quot;DestList.AssociationTime&amp;quot;',[0],[sID[1]]));
&lt;/pre&gt;
&lt;p&gt;Of course, the only useful parameter here is &lt;code&gt;id&amp;gt;=?&lt;/code&gt; which is
used to retrieve the just added relationships in the pivot table. All other
conditions will always be true, but it will help testing the generated SQL.&lt;/p&gt;
&lt;p&gt;Our &lt;em&gt;mORMot&lt;/em&gt; will generate the following SQL statement:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;select&lt;/strong&gt; A.ID AID,A.SignatureTime A00,A.Signature A01,
  B.ID BID,B.AssociationTime B02,
  C.ID CID,C.SignatureTime C00,C.Signature C01
&lt;strong&gt;from &lt;/strong&gt;ASource A,ADests B,ADest C
&lt;strong&gt;where &lt;/strong&gt;B.Source=A.ID &lt;strong&gt;and &lt;/strong&gt;B.Dest=C.ID
  &lt;strong&gt;and&lt;/strong&gt; (C.SignatureTime&amp;lt;&amp;gt;0 &lt;strong&gt;and&lt;/strong&gt; A.id&amp;gt;=:(1): &lt;strong&gt;and&lt;/strong&gt; B.AssociationTime&amp;lt;&amp;gt;0
  &lt;strong&gt;and&lt;/strong&gt; A.SignatureTime=C.SignatureTime &lt;strong&gt;and&lt;/strong&gt; C.Signature&amp;lt;&amp;gt;&amp;quot;DestList.AssociationTime&amp;quot;)
&lt;/pre&gt;
&lt;p&gt;You can notice the following:&lt;br /&gt;
- All declared &lt;code&gt;TSQLRecordMany&lt;/code&gt; instances (only one, renamed
&lt;code&gt;B&lt;/code&gt; in our case) are included in the statement, with all
corresponding &lt;code&gt;Dest&lt;/code&gt; instances (renamed as &lt;code&gt;C&lt;/code&gt;);&lt;br /&gt;
- Fields are aliased with short unique identifiers (&lt;code&gt;AID, A01, BID,
B02...&lt;/code&gt;), for all &lt;em&gt;simple&lt;/em&gt; properties of every classes;&lt;br /&gt;
- The JOIN clause is created (&lt;code&gt;B.Source=A.ID and
B.Dest=C.ID&lt;/code&gt;);&lt;br /&gt;
- Our manual WHERE clause has been translated into proper SQL, including the
table internal aliases (&lt;code&gt;A,B,C&lt;/code&gt;) - in fact,
&lt;code&gt;DestList.Dest&lt;/code&gt; has been replaced by &lt;code&gt;C&lt;/code&gt;, the main
&lt;code&gt;ID&lt;/code&gt; property has been declared properly as &lt;code&gt;A.ID&lt;/code&gt;, and
the &lt;code&gt;&amp;quot;DestList.AssociationTime&amp;quot;&lt;/code&gt; text remained untouched, because it
was bounded with quotes.&lt;/p&gt;
&lt;p&gt;That is, our ORM did make all the dirty work for you! You can use
Delphi-level conditions in your query, and the engine will transparently
convert them into a valid SQL statement. Benefit of this will become clear in
case of multiple pivot tables, which are likely to occur in real-world
applications.&lt;/p&gt;
&lt;p&gt;After the statement has been prepared, you can use the standard
&lt;code&gt;FillOne&lt;/code&gt; method to loop through all returned rows of data, and
access to the JOINed columns within the Delphi objects instances:&lt;/p&gt;
&lt;pre&gt;
  Check(MS.FillTable.RowCount=length(sID));
  &lt;strong&gt;for&lt;/strong&gt; i := 1 &lt;strong&gt;to&lt;/strong&gt; high(sID) &lt;strong&gt;do begin&lt;/strong&gt;
   &lt;span style=&quot;background-color:yellow;&quot;&gt;MS.FillOne;&lt;/span&gt;
    Check(MS.fID=sID[i]);
    Check(MS.SignatureTime=MD.fSignatureTime);
    Check(MS.DestList.AssociationTime=i);
    Check(MS.DestList.Dest.fID=dID[i]);
    Check(MS.DestList.Dest.SignatureTime=MD.fSignatureTime);
    Check(MS.DestList.Dest.Signature=FormatUTF8('% %',[aClient.ClassName,i]));
  &lt;strong&gt;end&lt;/strong&gt;;
  &lt;span style=&quot;background-color:yellow;&quot;&gt;MS.FillClose;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Note that in our case, an explicit call to &lt;code&gt;FillClose&lt;/code&gt; has been
added in order to release all &lt;code&gt;Dest&lt;/code&gt; instances created in
&lt;code&gt;FillPrepareMany&lt;/code&gt;. This call is not mandatory if you call
&lt;code&gt;MS.Free&lt;/code&gt; directly, but it is required if the same &lt;code&gt;MS&lt;/code&gt;
instance is about to use some regular many-to-many methods, like
&lt;code&gt;MS.DestList.ManySelect()&lt;/code&gt; - it will prevent any GPF exception
to occur with code expecting the &lt;code&gt;Dest&lt;/code&gt; property not to be an
instance, but a &lt;code&gt;pointer(DestID)&lt;/code&gt; value.&lt;/p&gt;
&lt;p&gt;Feedback and comments are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=3185#p3185&quot;&gt;welcome in our
forum&lt;/a&gt; - this thread also contains the customer request for this nice
feature.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Total Commander 64 bit is using... Lazarus and FPC</title>
    <link>http://blog.synopse.info/post/2011/12/04/Total-Commander-64-bit-is-using...-Lazarus-and-FPC</link>
    <guid isPermaLink="false">urn:md5:f39ee053de633706054ccca38fe38a2f</guid>
    <pubDate>Sun, 04 Dec 2011 09:46:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>64bit</category><category>blog</category><category>Delphi</category><category>FreePascal</category><category>TotalCommander</category><category>zip</category>    
    <description>&lt;p&gt;I'm a long-time registered user of &lt;a href=&quot;http://ghisler.com&quot;&gt;Total
Commander&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This tool is my daily file manager. I never use &lt;em&gt;Windows Explorer&lt;/em&gt;,
since &lt;em&gt;Total Commander&lt;/em&gt; is just faster, more easy to use (especially
with the keyboard), has a lot of plug-ins. I even created my own plug-ins to
access some custom file formats, and navigate into them just like with any
folder. And it includes a lot of well written commands for FTP access or file
comparison, which made other tools (like &lt;em&gt;WinMerge&lt;/em&gt;) unnecessary.&lt;/p&gt;
&lt;p&gt;There is a new &lt;em&gt;beta&lt;/em&gt; version of Total Commander available,
which targets Windows 64 bit. I just thought: 'Whoo, this is a real-world
Delphi XE2 64 application'. I downloaded and tried it. Worked as expected, and
integrates seamlessly with Windows Seven (for the shell extensions).
Then I took a look at the executable... and discovered it was not compiled with
Delphi XE2... but with FPC !&lt;/p&gt;    &lt;p&gt;The 32 bit version appears to be compiled with Delphi 2 - yes, this is an
OLD version (the first 32 bit version) - but this is &lt;a href=&quot;http://www.ghisler.ch/board/viewtopic.php?t=23548&quot;&gt;what the TC author himself
states&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As a result, the 32 bit version executable is small and efficient. And,
honestly, you can write a nice Unicode software without using generics and all
the new Delphi features...&lt;/p&gt;
&lt;p&gt;When looking at the 64 bit supplied version, it was obvious to me that even
if the tool was behaving the same as the 32 bit version (fast and native user
interface), the gears were not the same. It seems to have been compiled with
the great Open Source &lt;a href=&quot;http://freepascal.org/&quot;&gt;Free Pascal
Compiler&lt;/a&gt; - using not the VCL, but the cross-platform &lt;a href=&quot;http://www.lazarus.freepascal.org/&quot;&gt;Lazarus project&lt;/a&gt;. I do not know if the
LCL components where used, or some &lt;em&gt;Total Commander&lt;/em&gt;-custom components
(which I think is more than probable, knowing Ghisler's skill and hand-tuning
abilities).&lt;/p&gt;
&lt;p&gt;It is even clear if you look &lt;a href=&quot;http://www.ghisler.com/history.txt&quot;&gt;at
the application history&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;
14.07.10 Added: Start work on conversion to Lazarus/Free Pascal in preparation for 64-bit version
&lt;/pre&gt;
As I wrote &lt;a href=&quot;http://blog.synopse.info/post/2010/08/14/FPC-and-Delphi%3A-toward-a-%22fratricidal-war%22&quot;&gt;some time
ago in this blog&lt;/a&gt;, FPC team published a 64 bit compiler using the
Delphi/object pascal language in 2006. Whereas the &amp;quot;official&amp;quot; Win64 support
just appeared this year, with Delphi XE2.
&lt;p&gt;Christian Ghisler is working with FPC for a lot of time for the PocketPC
(... and now &lt;a href=&quot;http://ghisler.com/android.htm&quot;&gt;Android&lt;/a&gt;!) freeware
versions of his tool.&lt;/p&gt;
&lt;p&gt;I'm very happy to see such a world-wide spread application using FPC and
Lazarus tandem. There are open source alternatives to FireMonkey and Delphi
XE2. Not a feature-like, but with another architecture, another rendering,
another coding spirit, another cross-platform abilities, another
mind openness... Even Delphi is using FPC as compiler &lt;a href=&quot;http://blog.synopse.info/post/2011/08/08/Our-mORMot-won-t-hibernate-this-winter%2C-thanks-to-FireMonkey&quot;&gt;
when targeting iOS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Feedback and comments are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=535&quot;&gt;welcome on our forum&lt;/a&gt;!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>AJAX authentication</title>
    <link>http://blog.synopse.info/post/2011/11/30/AJAX-authentication</link>
    <guid isPermaLink="false">urn:md5:edb991b981039294b2bbbf87507e8dfb</guid>
    <pubDate>Wed, 30 Nov 2011 06:36:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>AJAX</category><category>authentication</category><category>Database</category><category>Delphi</category><category>mORMot</category><category>security</category><category>session</category><category>SOA</category><category>Synopse</category>    
    <description>&lt;p&gt;A nice framework user, named &lt;em&gt;esmondb&lt;/em&gt;, did write and publish some
&lt;em&gt;JavaScript&lt;/em&gt; code to handle our &lt;a href=&quot;http://blog.synopse.info/post/2011/05/24/How-to-implement-RESTful-authentication&quot;&gt;RESTful
authentication&lt;/a&gt; mechanism.&lt;/p&gt;
&lt;p&gt;It seems to work well, and implements all secure hashing and
challenging.&lt;br /&gt;
Our authentication mechanism is much more advanced than the one used by
&lt;em&gt;DataSnap&lt;/em&gt; - which is a basic HTTP authentication with the password
transmitted in clear (this is the reason why it shall better be used over
HTTPS, whereas &lt;em&gt;mORMot&lt;/em&gt; can be used over plain HTTP).&lt;br /&gt;
Resulting &lt;em&gt;JavaScript&lt;/em&gt; code seems not difficult to follow, even for a no
JS expert like me.&lt;/p&gt;    &lt;p&gt;The full JavaScript code is available in &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=490&quot;&gt;this forum post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I've modified the &lt;em&gt;Delphi&lt;/em&gt; framework code (in the current
&lt;em&gt;trunk&lt;/em&gt; version) to match the authentication JavaScript code.&lt;br /&gt;
In fact, the server response is now a true JSON result object. I've modified
the &lt;code&gt;TSQLRestURI.SetUser&lt;/code&gt; code to let pure Delphi client code work
as expected.&lt;/p&gt;
&lt;p&gt;In the same discussion, another user involved in developing AJAX
applications with &lt;em&gt;mORMot&lt;/em&gt;, named &lt;em&gt;RangerX&lt;/em&gt;, made a nice
proposal: add a generic JSON error message mechanisms in the framework.&lt;br /&gt;
I've added this to the project &lt;a href=&quot;http://synopse.info/fossil/wiki?name=RoadMap&quot;&gt;to-do list&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>SOLID design principles</title>
    <link>http://blog.synopse.info/post/2011/11/27/SOLID-design-principles</link>
    <guid isPermaLink="false">urn:md5:bde7fd7d2119527368d952311959199d</guid>
    <pubDate>Sun, 27 Nov 2011 23:39:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>Delphi</category><category>GoodPractice</category><category>object</category><category>Rest</category>    
    <description>&lt;p&gt;Delphi is sometimes assimilated to a RAD product - and this is a marketing
label - but IMHO Delphi is much more than RAD.&lt;br /&gt;
With Delphi, you can make very serious and clean programming.&lt;/p&gt;
&lt;p&gt;Including SOLID style of coding.&lt;/p&gt;
&lt;p&gt;The acronym SOLID is derived from the following OOP principles (quoted from
the corresponding &lt;a href=&quot;http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=solid%20wikipedia&amp;amp;source=web&amp;amp;cd=2&amp;amp;sqi=2&amp;amp;ved=0CDAQFjAB&amp;amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FSOLID_(object-oriented_design)&amp;amp;ei=yLbTTruoFoOcsAbJwsjYBA&amp;amp;usg=AFQjCNHMwHjI1CzjM0208uMB6OSA3S4jug&amp;amp;sig2=Pre1__KEvg1re1sHF7Fkjg&quot;&gt;
&lt;em&gt;Wikipedia&lt;/em&gt; article&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Single responsibility principle&lt;/em&gt;: the notion that an object should
have only a single responsibility;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Open/closed principle&lt;/em&gt;: the notion that “software entities ...
should be open for extension, but closed for modification”;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Liskov substitution principle&lt;/em&gt;: the notion that “objects in a
program should be replaceable with instances of their subtypes without altering
the correctness of that program” - also named as &amp;quot;&lt;em&gt;design by
contract&lt;/em&gt;&amp;quot;;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface segregation principle&lt;/em&gt;: the notion that “many client
specific interfaces are better than one general purpose interface.”;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Dependency inversion principle&lt;/em&gt;: the notion that one should “Depend
upon Abstractions. Do not depend upon concretions.”. &lt;em&gt;Dependency
injection&lt;/em&gt; is one method of following this principle.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have some programming skills, those principles are general statements
you may already found out by yourself. If you start doing serious
object-oriented coding, those principles are best-practice guidelines you would
gain following.&lt;/p&gt;
&lt;p&gt;They certainly help to fight the three main code weaknesses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Rigidity&lt;/em&gt; – Hard to change something because every change affects
too many other parts of the system;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Fragility&lt;/em&gt; – When you make a change, unexpected parts of the system
break;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Immobility&lt;/em&gt; – Hard to reuse in another application because it
cannot be disentangled from the current application.&lt;/li&gt;
&lt;/ul&gt;    &lt;h3&gt;Single responsibility principle&lt;/h3&gt;
&lt;p&gt;When you define a class, it shall be designed to implement only one feature.
The so-called feature can be seen as an &amp;quot;&lt;em&gt;axis of change&lt;/em&gt;&amp;quot; or a &amp;quot;&lt;em&gt;a
reason for change&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;Therefore:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One class shall have only one reason that justifies changing its
implementation;&lt;/li&gt;
&lt;li&gt;Classes shall have few dependencies on other classes;&lt;/li&gt;
&lt;li&gt;Classes shall be abstract from the particular layer they are running.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance, a &lt;code&gt;TRectangle&lt;/code&gt; object should not have both
&lt;code&gt;ComputeArea&lt;/code&gt; and &lt;code&gt;Draw&lt;/code&gt; methods defined at once - they
would define two responsibilities or axis of change: the first responsibility
is to provide a mathematical model of a rectangle, and the second is to render
it on GUI.&lt;/p&gt;
&lt;p&gt;When you define an ORM object, do not put GUI methods within. In fact, the
fact that our &lt;code&gt;TSQLRecord&lt;/code&gt; class definitions are common to both
Client and Server sides makes this principle mandatory. You won't have any GUI
related method on the Server side, and the Client side could use the objects
instances with several GUI implementations (Delphi Client, AJAX Client...).&lt;/p&gt;
&lt;p&gt;Therefore, if you want to change the GUI, you won't have to recompile the
&lt;code&gt;TSQLRecord&lt;/code&gt; class and the associated database model.&lt;/p&gt;
&lt;p&gt;Another example is how our database classes are defined in
&lt;code&gt;SynDB.pas&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;connection properties&lt;/em&gt; feature is handled by
&lt;code&gt;TSQLDBConnectionProperties&lt;/code&gt; classes;&lt;/li&gt;
&lt;li&gt;The actual &lt;em&gt;living connection&lt;/em&gt; feature is handled by
&lt;code&gt;TSQLDBConnection&lt;/code&gt; classes;&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;database requests&lt;/em&gt; feature is handled by
&lt;code&gt;TSQLDBStatement&lt;/code&gt; instances using dedicated
&lt;code&gt;NewConnection&lt;/code&gt; / &lt;code&gt;ThreadSafeConnection&lt;/code&gt; /
&lt;code&gt;NewStatement&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore, you may change how a database connection is defined (e.g. add a
property to a &lt;code&gt;TSQLDBConnectionProperties&lt;/code&gt; child), and you won't
have to change the statement implementation itself.&lt;/p&gt;
&lt;p&gt;Following this &lt;em&gt;Single responsibility principle&lt;/em&gt; may sound simple and
easy, but in fact, it is one of the hardest principles to get right. Naturally,
we tend to join responsibilities in our class definitions. Our ORM architecture
will enforce you, by its Client-Server nature, to follow this principle, but it
is always up to the end coder to design properly his/her interfaces.&lt;/p&gt;
&lt;h3&gt;Open/closed principle&lt;/h3&gt;
&lt;p&gt;When you define a class or a unit, at the same time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They shall be &lt;em&gt;open for extension&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;But &lt;em&gt;closed for modification&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When designing our ORM, we tried to follow this principle. In fact, you
should not have to modify its implementation. You should define your own units
and classes, without the need to &lt;em&gt;hack&lt;/em&gt; the framework source code.&lt;/p&gt;
&lt;p&gt;Even if &lt;em&gt;Open Source&lt;/em&gt; paradigm allows you to modify the supplied
code, this shall not be done unless you are either fixing a bug or adding a new
common feature. This is in fact the purpose of our &lt;a href=&quot;http://synopse.info&quot;&gt;http://synopse.info&lt;/a&gt; web site, and most of the
framework enhancements have come from user requests.&lt;/p&gt;
&lt;p&gt;The framework Open Source license may encourage user contributions in order
to fulfill the Open/closed design principle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your application code extends the &lt;em&gt;Synopse SQLite3/mORMot Framework&lt;/em&gt;
by defining your own classes or event handlers - this is how it is &lt;em&gt;open for
extension&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;The main framework units shall remain inviolate, and common to all users -
this illustrates the &lt;em&gt;closed for modification&lt;/em&gt; design.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, this principle will ensure your code to be ready to follow the
main framework updates (which are quite regular). When a new version is
available, you would be able to retrieve it for free from our web site, replace
your files locally, then build a new enhanced version of your application. Even
the source code repository is available - at &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;http://synopse.info/fossil&lt;/a&gt; - and allows you to
follow the current step of evolvment of the framework.&lt;/p&gt;
&lt;p&gt;In short, abstraction is the key. All your code shall not depend on a
particular implementation.&lt;/p&gt;
&lt;p&gt;In order to implement this principle, several conventions could be
envisaged:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You shall better define some abstract classes, then use specific overridden
classes for each and every implementation: this is for instance how
Client-Server classes were implemented;&lt;/li&gt;
&lt;li&gt;All object members shall be declared &lt;code&gt;private&lt;/code&gt; or
&lt;code&gt;protected&lt;/code&gt; - this is a good idea to use an
Service-Oriented-Architecture for defining server-side process, and/or make the
&lt;code&gt;TSQLRecord&lt;/code&gt; published properties read-only and using some
client-side &lt;code&gt;constructor&lt;/code&gt; with parameters;&lt;/li&gt;
&lt;li&gt;No singleton nor global variable - &lt;em&gt;ever&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;RTTI is dangerous - that is, let our framework use RTTI functions for its
own cooking, but do not use it in your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some other guidelines may be added, but you got the main idea. Conformance
to this open/closed principle is what yields the greatest benefit of OOP,
i.e.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code re-usability;&lt;/li&gt;
&lt;li&gt;Code maintainability;&lt;/li&gt;
&lt;li&gt;Code extendibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Following this principle will make your code far away from a regular RAD
style. But benefits will be huge.&lt;/p&gt;
&lt;h3&gt;Liskov substitution principle&lt;/h3&gt;
&lt;p&gt;Even if her name is barely unmemorable, &lt;em&gt;Barbara Liskov&lt;/em&gt; is a great
computer scientist, we should better learn from.&lt;/p&gt;
&lt;p&gt;Her &amp;quot;substitution principle&amp;quot; states that, if &lt;code&gt;TChild&lt;/code&gt; is a
subtype of &lt;code&gt;TParent&lt;/code&gt;, then objects of type &lt;code&gt;TParent&lt;/code&gt; may
be replaced with objects of type &lt;code&gt;TChild&lt;/code&gt; (i.e., objects of type
&lt;code&gt;TChild&lt;/code&gt; may be substitutes for objects of type
&lt;code&gt;TParent&lt;/code&gt;) without altering any of the desirable properties of that
program (correctness, task performed, etc.).&lt;/p&gt;
&lt;p&gt;For our framework, it would signify that &lt;code&gt;TSQLRestServer&lt;/code&gt; or
&lt;code&gt;TSQLRestClient&lt;/code&gt; instances can be substituted to a
&lt;code&gt;TSQLRest&lt;/code&gt; object. Most ORM methods expect a &lt;code&gt;TSQLRest&lt;/code&gt;
parameter to be supplied.&lt;/p&gt;
&lt;p&gt;Your code shall refer to abstractions, not to implementations. By using only
methods and properties available at classes parent level, your code won't need
to change because of a specific implementation.&lt;/p&gt;
&lt;p&gt;The main advantages of this coding pattern are the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thanks to this principle, you will be for instance able to &lt;em&gt;stub&lt;/em&gt; or
&lt;em&gt;mock&lt;/em&gt; an interface or a class - this principle is therefore mandatory
for implementing unitary testing to your project;&lt;/li&gt;
&lt;li&gt;Furthermore, testing would be available not only at isolation level
(testing each child class), but also at abstracted level, i.e. from the client
point of view - you can have implementation which behave correctly when tested
individually, but which failed when tested at higher level if the Liskov
principle was broken;&lt;/li&gt;
&lt;li&gt;If this principle is violated, the open/close principle will be - the
parent class would need to be modified whenever a new derivative of the base
class is defined;&lt;/li&gt;
&lt;li&gt;Code re-usability is enhanced by method re-usability: a method defined at a
parent level does not require to be implemented for each child.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some patterns which shall not appear in your code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Statements like &lt;code&gt;if aObject is TAClass then begin .... end else if
aObject is TAnotherClass then ...&lt;/code&gt; in a parent method;&lt;/li&gt;
&lt;li&gt;Use an enumerated item and a &lt;code&gt;case ... of&lt;/code&gt; or nested &lt;code&gt;if
... then&lt;/code&gt; to change a method behavior (this will also probably break the
single responsibility principle: each enumeration shall be defined as a
class);&lt;/li&gt;
&lt;li&gt;Define a method which will stay &lt;code&gt;abstract&lt;/code&gt; for some
children;&lt;/li&gt;
&lt;li&gt;Need to explicitly add all child classes units to the parent class unit
&lt;code&gt;uses&lt;/code&gt; clause.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In order to fulfill this principle, you should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the &amp;quot;behavior&amp;quot; design pattern, when defining your objects hierarchy -
for instance, if a square may be a rectangle, a &lt;code&gt;TSquare&lt;/code&gt; object is
definitively &lt;em&gt;not&lt;/em&gt; a &lt;code&gt;TRectangle&lt;/code&gt; object, since the behavior
of a &lt;code&gt;TSquare&lt;/code&gt; object is not consistent with the behavior of a
&lt;code&gt;TRectangle&lt;/code&gt; object (square width always equals its height, whereas
it is not the case for most rectangles);&lt;/li&gt;
&lt;li&gt;Write your tests using abstract local variables (and this will allow test
code reuse for all children classes);&lt;/li&gt;
&lt;li&gt;Follow the concept of &lt;em&gt;Design by Contract&lt;/em&gt;, i.e. the Meyer's rule
defined as &amp;quot;&lt;em&gt;when redefining a routine [in a derivative], you may only
replace its precondition by a weaker one, and its postcondition by a stronger
one&lt;/em&gt;&amp;quot; - use of preconditions and postconditions also enforce testing
model;&lt;/li&gt;
&lt;li&gt;Separate your classes hierarchy: typically, you may consider using
separated object types for implementing persistence and object creation (this
is the common separation between &lt;em&gt;Factory&lt;/em&gt; and
&lt;em&gt;Repository&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The SOA and ORM concepts as used by our framework are compatible with the
Liskov substitution principle. Future versions shall enforce this, by providing
some direct &lt;em&gt;Design by Contract&lt;/em&gt; methods (involving a more wide usage of
&lt;code&gt;interfaces&lt;/code&gt;).&lt;/p&gt;
&lt;h3&gt;Interface segregation principle&lt;/h3&gt;
&lt;p&gt;This principle states that once an interface has become too 'fat' it shall
be split into smaller and more specific interfaces so that any clients of the
interface will only know about the methods that pertain to them. In a nutshell,
no client should be forced to depend on methods it does not use.&lt;/p&gt;
&lt;p&gt;As a result, it will help a system stay decoupled and thus easier to
re-factor, change, and redeploy.&lt;/p&gt;
&lt;p&gt;In its current state, our framework does not make direct use of
&lt;code&gt;interfaces&lt;/code&gt;. But its Client-Server SOA architecture helps
decoupling all services to individual small methods. And its stateless design
will also reduce the use of 'fat' session-related processes.&lt;/p&gt;
&lt;h3&gt;Dependency Inversion Principle&lt;/h3&gt;
&lt;p&gt;Another form of decoupling is to invert the dependency between high and low
level of a software design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High-level modules should not depend on low-level modules. Both should
depend on abstractions;&lt;/li&gt;
&lt;li&gt;Abstractions should not depend upon details. Details should depend upon
abstractions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In conventional application architecture, lower-level components are
designed to be consumed by higher-level components which enable increasingly
complex systems to be built. This design limits the reuse opportunities of the
higher-level components, and certainly breaks the Liskov's substitution
principle.&lt;/p&gt;
&lt;p&gt;The goal of the &lt;em&gt;dependency inversion principle&lt;/em&gt; is to decouple
high-level components from low-level components such that reuse with different
low-level component implementations becomes possible. A simple implementation
pattern could be to use only interfaces owned by, and existing only with the
high-level component package.&lt;/p&gt;
&lt;p&gt;In other languages (like Java or .Net), various patterns such as
&lt;em&gt;Plug-in, Service Locator&lt;/em&gt;, or &lt;em&gt;Dependency Injection&lt;/em&gt; are then
employed to facilitate the run-time provisioning of the chosen low-level
component implementation to the high-level component.&lt;/p&gt;
&lt;p&gt;Our Client-Server architecture facilitated this decoupling pattern, even if
no &lt;code&gt;interface&lt;/code&gt; is used by default in the framework yet.&lt;br /&gt;
But such a WCF-like or SOAP/Datasnap &lt;code&gt;interface&lt;/code&gt;-based service
definition is on the top of my &lt;em&gt;to-do&lt;/em&gt; list. &lt;img src=&quot;/themes/default/smilies/smile.png&quot; alt=&quot;:)&quot; class=&quot;smiley&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
Comments and feedback are welcome &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=526&quot;&gt;on our forum&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Modification of TSQLRestServerCallBack method prototype</title>
    <link>http://blog.synopse.info/post/2011/11/27/Modification-of-TSQLRestServerCallBack-method-prototype</link>
    <guid isPermaLink="false">urn:md5:32de95a4edb8fb52870435d04a90718e</guid>
    <pubDate>Sun, 27 Nov 2011 07:21:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>Delphi</category><category>mORMot</category><category>Rest</category><category>SOA</category><category>Source</category><category>SQLite3</category>    
    <description>In order to implement some RESTful Services, a &lt;a href=&quot;http://blog.synopse.info/post/2010/07/18/DataSnap-like-Client-Server-JSON-RESTful-Services-in-Delphi-7-2010&quot;&gt;
callback has to be defined on the server side&lt;/a&gt;.
&lt;p&gt;The prototype of these method has been modified, to supply an additional
&lt;code&gt;aSession: cardinal&lt;/code&gt; parameter: this is a CODE BREAK change and you
shall refresh ALL your server-side code to match the new signature.&lt;/p&gt;    &lt;p&gt;This new &lt;code&gt;aSession&lt;/code&gt; parameter will identify the authentication
session of the remote client, or 1 (if authentication mode is not set), or 0
(if the session not started yet).&lt;br /&gt;
Service implementation code may then use the new &lt;code&gt;SessionGetUser()&lt;/code&gt;
protected method to retrieve the session details, e.g. the user logon name and
display name, or the associated BLOB data.&lt;/p&gt;
&lt;p&gt;This is a code break of existing implementation, but it will provide
mandatory additional information for a true Client-Server design.&lt;br /&gt;
Next step is to implement a true &lt;em&gt;Interface&lt;/em&gt;-based service feature,
similar to WCF or SOAP/DataSnap (in my &lt;em&gt;to-do&lt;/em&gt; list).&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;http://synopse.info/fossil/info/e04dbb13d0&quot;&gt;this link for the
corresponding commit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For instance, &lt;a href=&quot;http://synopse.info/fossil/fdiff?v1=943b4fe02c4ff5cd&amp;amp;v2=76b0351e0617c3b5&quot;&gt;here
is the difference&lt;/a&gt; applied on the corresponding sample folder:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;TServiceServer = class(TSQLRestServer)&lt;br /&gt;
published&lt;br /&gt;
- function Sum(aRecord: TSQLRecord; aParameters: PUTF8Char;&lt;br /&gt;
- const aSentData: RawUTF8; var aResp, aHead: RawUTF8): Integer;&lt;br /&gt;
+ function Sum(aSession: Cardinal; aRecord: TSQLRecord; aParameters:
PUTF8Char;&lt;br /&gt;
+ const aSentData: RawUTF8; out aResp, aHead: RawUTF8): Integer;&lt;br /&gt;
end;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note that &lt;a href=&quot;http://blog.synopse.info/post/2012/02/06/Modification-of-TSQLRestServerCallBack-method-prototype-%28bis%29&quot;&gt;
the callback prototype changed again&lt;/a&gt;, for simplicity and to avoid most
further change.&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Does speed matters?</title>
    <link>http://blog.synopse.info/post/2011/11/23/Does-speed-matters</link>
    <guid isPermaLink="false">urn:md5:1bc9e3da76f8e4673f14b81c4aee0daf</guid>
    <pubDate>Wed, 23 Nov 2011 08:37:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>Delphi</category><category>performance</category><category>SQL</category>    
    <description>&lt;p&gt;Luigi Sandon wrote &lt;a href=&quot;https://forums.embarcadero.com/thread.jspa?messageID=414108#414108&quot;&gt;on
Embarcadero's forum&lt;/a&gt;: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And then you ask yourself: &amp;quot;why use a native compiler if its code may be
even slower than jitted one?&amp;quot;. Hope the new developers will also develop better
and faster code - and not viceversa.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Embarcadero is just following the Wirth's law slower than others:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Software is getting slower more rapidly than hardware becomes faster&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Speed is only a matter of compiler for mathematical computing intensive
tasks.&lt;br /&gt;
Most of the time, in real apps (like business apps), the main speed issue is
more the framework size (and the number of dll invoked), memory consumption,
and general design (e.g. how caching and SQL are written).&lt;/p&gt;
&lt;p&gt;Delphi, Java or .Net can do slow apps.&lt;br /&gt;
Delphi, Java or .Net can do fast apps.&lt;/p&gt;
&lt;p&gt;You can do small and fast stand-alone apps with Delphi, running from Windows
2000 to Windows 8.&lt;br /&gt;
It is not possible with Java nor .Net.&lt;/p&gt;
&lt;p&gt;This is the main difference IMHO with native code and JIT - about memory
use, ease of distribution and no need of an external runtime framework.&lt;/p&gt;    &lt;p&gt;For instance, most of our tools (like &lt;a href=&quot;http://blog.synopse.info/post/2011/02/13/SynProject-1.12-released&quot;&gt;SynProject&lt;/a&gt; documentation or
&lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;SynDBExplorer&lt;/a&gt;
tool) are stand-alone, but powerful.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;SynDBExplorer&lt;/em&gt; is able to connect to databases with no installation:
the same tool written in .Net would make a smaller executable in size, but will
be slower (even unworkable with huge amount of data - millions of rows), need
additional requirements for database access (e.g. native Oracle), and will
consume much more memory.&lt;/p&gt;
&lt;p&gt;Of course, there are plenty of great libraries in .Net, a lot of books to be
read... Nice features I miss with Delphi.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Currency is your friend</title>
    <link>http://blog.synopse.info/post/2011/11/08/Currency-is-your-friend</link>
    <guid isPermaLink="false">urn:md5:c2c0c89077446833b52f4068bfad5d7b</guid>
    <pubDate>Tue, 08 Nov 2011 21:51:00 +0100</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>64bit</category><category>asm</category><category>blog</category><category>CrossPlatform</category><category>Database</category><category>Delphi</category><category>dynamic array</category><category>performance</category><category>RTTI</category><category>Source</category><category>SQL</category><category>SQLite3</category>    
    <description>&lt;p&gt;The &lt;code&gt;currency&lt;/code&gt; type is the standard Delphi type to be used when
storing and handling monetary values. It will avoid any rounding problems, with
4 decimals precision. It is able to safely store numbers in the range
-922337203685477.5808 .. 922337203685477.5807. Should be enough for your pocket
change.&lt;/p&gt;
&lt;p&gt;As stated by the official Delphi documentation:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Currency is a fixed-point data type that minimizes rounding errors in
monetary calculations. On the Win32 platform, it is stored as a scaled 64-bit
integer with the four least significant digits implicitly representing decimal
places. When mixed with other real types in assignments and expressions,
Currency values are automatically divided or multiplied by 10000.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In fact, this type matches the corresponding &lt;code&gt;OLE&lt;/code&gt; and
&lt;code&gt;.Net&lt;/code&gt; implementation of &lt;code&gt;currency&lt;/code&gt;, and the one used by
most database providers (when it comes to money, a dedicated type is worth the
cost in a &amp;quot;rich man's world&amp;quot;). It is still implemented the same in the
&lt;em&gt;Win64&lt;/em&gt; platform (since XE 2). The &lt;code&gt;Int64&lt;/code&gt; binary
representation of the &lt;code&gt;currency&lt;/code&gt; type (i.e. &lt;code&gt;value*10000&lt;/code&gt;
as accessible via &lt;code&gt;PInt64(aCurrencyValue)^&lt;/code&gt;) is a safe and fast
implementation pattern.&lt;/p&gt;
&lt;p&gt;In our framework, we tried to avoid any unnecessary conversion to float
values when dealing with &lt;code&gt;currency&lt;/code&gt; values. Some dedicated functions
have been implemented for fast and secure access to &lt;code&gt;currency&lt;/code&gt;
published properties via RTTI, especially when converting values to or from
JSON text. Using the &lt;code&gt;Int64&lt;/code&gt; binary representation can be not only
faster, but also safer: you will avoid any rounding problem which may be
introduced by the conversion to a float type. Rounding issues are a nightmare
to track - it sounds safe to have a framework handling natively a
&lt;code&gt;currency&lt;/code&gt; type from the ground up.&lt;/p&gt;    &lt;p&gt;Faster and safer way of comparing two &lt;code&gt;currency&lt;/code&gt; values is
certainly to map the variables to their internal &lt;code&gt;Int64&lt;/code&gt; binary
representation, as such:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;function&lt;/strong&gt; CompCurrency(&lt;strong&gt;var&lt;/strong&gt; A,B: currency): Int64;
&lt;strong&gt;var&lt;/strong&gt; A64: Int64 &lt;strong&gt;absolute&lt;/strong&gt; A;
    B64: Int64 &lt;strong&gt;absolute&lt;/strong&gt; B;
&lt;strong&gt;begin&lt;/strong&gt;
  result := A64-B64;
&lt;strong&gt;end&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;This will avoid any rounding error during comparison (working with *10000
integer values), and will be faster than the default implementation, which uses
the FPU (or SSE2 under &lt;em&gt;x64&lt;/em&gt; architecture) instructions.&lt;/p&gt;
&lt;p&gt;In &lt;em&gt;&lt;a href=&quot;http://synopse.info/fossil/finfo?name=SynCommons.pas&quot;&gt;SynCommons.pas&lt;/a&gt;&lt;/em&gt;,
there are some functions using the &lt;code&gt;Int64&lt;/code&gt; binary representation
(accessible either as &lt;code&gt;PInt64(aCurrencyVar)^&lt;/code&gt; or the
&lt;code&gt;absolute&lt;/code&gt; syntax).&lt;br /&gt;
They will by-pass the FPU/SSE2 use, and are therefore both fast and safe at the
same time:&lt;/p&gt;
&lt;p&gt;- &lt;code&gt;function Curr64ToString(Value: Int64): string;&lt;/code&gt;&lt;br /&gt;
- &lt;code&gt;function StrToCurr64(P: PUTF8Char): Int64;&lt;/code&gt;&lt;br /&gt;
- &lt;code&gt;function Curr64ToStr(Value: Int64): RawUTF8;&lt;/code&gt;&lt;br /&gt;
- &lt;code&gt;function Curr64ToPChar(Value: Int64; Dest: PUTF8Char):
PtrInt;&lt;/code&gt;&lt;br /&gt;
- &lt;code&gt;function StrCurr64(P: PAnsiChar; const Value: Int64):
PAnsiChar;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Using those functions can be &lt;em&gt;much&lt;/em&gt; faster for textual conversion
than using the standard &lt;code&gt;FloatToText()&lt;/code&gt; implementation. They are
validated with provided regression tests.&lt;/p&gt;
&lt;p&gt;Of course, in normal code, it is certainly not worth using the
&lt;code&gt;Int64&lt;/code&gt; binary representation of &lt;code&gt;currency&lt;/code&gt;, but rely on
the default compiler/RTL implementation. In all cases, having optimized
functions was a need for both speed and accuracy of our ORM data processing,
and also for external database handling.&lt;/p&gt;
&lt;p&gt;Comments and feedback are welcome &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=500&quot;&gt;on our forum&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Yes we can... fight bugs</title>
    <link>http://blog.synopse.info/post/2011/10/27/Yes-we-can...-fight-bugs</link>
    <guid isPermaLink="false">urn:md5:da28244488692674f8d779c78ce14fc2</guid>
    <pubDate>Thu, 27 Oct 2011 05:17:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>Delphi</category><category>exception</category><category>log</category><category>Testing</category>    
    <description>&lt;p&gt;From a &lt;a href=&quot;http://stackoverflow.com/questions/7907805#7912224&quot;&gt;StackOverflow
question&lt;/a&gt; about a freezing Delphi application, I posted some
experiment-based debugging tricks.&lt;/p&gt;
&lt;p&gt;May help any developer in his/her fight against random bugs...&lt;/p&gt;    &lt;p&gt;Some (general-purpose) suggestions may be the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If your application is not multi-threaded, do the process in background
threads, then leave the main thread ready to process GDI messages;&lt;/li&gt;
&lt;li&gt;If your application is multi-threaded, take care that all VCL accesses from
background threads are made via a &lt;code&gt;Synchronize&lt;/code&gt; call;&lt;/li&gt;
&lt;li&gt;If your application is multi-threaded or use timers, take care that no
method is re-entrant (in some circonstances, you may come into a &lt;a href=&quot;http://en.wikipedia.org/wiki/Race_condition&quot;&gt;race condition&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Hunt any memory leak;&lt;/li&gt;
&lt;li&gt;Use a detailed logging of the program execution, &lt;a href=&quot;http://blog.synopse.info/post/2011/04/14/Enhanced-logging-in-SynCommons&quot;&gt;logging
all exceptions&lt;/a&gt; risen, to guess the context of the program hang (it may be
used on the customer side also to hunt race conditions);&lt;/li&gt;
&lt;li&gt;Download the great free tool named &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb896653&quot;&gt;ProcessExplorer&lt;/a&gt;
(now hosted by Microsoft), and check out the state of your frozen program: you
will see detailed information about threads, CPU use, memory, network,
libraries, handles - this is a must have for any serious debugging - track
especially the &lt;em&gt;GDI handles&lt;/em&gt; leaks (number of those should remain
stable);&lt;/li&gt;
&lt;li&gt;If you did not check it already, take a look at the global Windows system
event log: there may be some information here;&lt;/li&gt;
&lt;li&gt;Perhaps a third party component or library is responsible of the process
hang: try to isolate the part of your code which may be responsible of this
hang.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I've Delphi application running for months without any problem. Issue is
definitively in application code, not in the Delphi architecture (its RTL and
VCL are very stable).&lt;/p&gt;
&lt;p&gt;Feedback and comments are welcome &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=2874&quot;&gt;on our forum&lt;/a&gt;!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse SQLite3/mORMot framework 1.15</title>
    <link>http://blog.synopse.info/post/2011/09/26/Synopse-SQLite3/mORMot-framework-1.15</link>
    <guid isPermaLink="false">urn:md5:f60edbfb1421843b43d9a0e9ec86eaef</guid>
    <pubDate>Sun, 25 Sep 2011 21:46:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>Database</category><category>Delphi</category><category>mORMot</category><category>OleDB</category><category>Oracle</category><category>ORM</category><category>SQLite3</category>    
    <description>&lt;p&gt;Our Client-Server ORM framework is now available in revision 1.15.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.synopse.info/public/mORMot.png&quot;&gt;&lt;img src=&quot;http://blog.synopse.info/public/.mORMot_m.jpg&quot; alt=&quot;&quot; title=&quot;mORMot, août 2011&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a major upgrade of the framework:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is now called &lt;a href=&quot;http://blog.synopse.info/post/2011/08/10/Framework-documentation-updated-to-revision-1.15&quot;&gt;mORMot&lt;/a&gt; -
so please update your T-Shirts or coffee cups &lt;img src=&quot;/themes/default/smilies/wink.png&quot; alt=&quot;;)&quot; class=&quot;smiley&quot; /&gt;&lt;/li&gt;
&lt;li&gt;It is able to use &lt;a href=&quot;http://blog.synopse.info/post/2011/06/09/Close-future-of-the-framework%3A-database-agnosticism&quot;&gt;any
Database engine&lt;/a&gt; back-end - in fact, it is &lt;a href=&quot;http://blog.synopse.info/post/2011/08/07/SQLite3-powered%2C-not-SQLite3-limited&quot;&gt;SQLite3 powered, not
SQLite3 limited&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;In particular, &lt;a href=&quot;http://blog.synopse.info/post/2011/06/27/SynOleDB%3A-OpenSource-Unit-for-direct-access-to-any-database-via-OleDB&quot;&gt;
direct OleDB&lt;/a&gt; and &lt;a href=&quot;http://blog.synopse.info/post/2011/07/09/SynDBOracle%3A-Open-Source-native-Oracle-access&quot;&gt;native
Oracle&lt;/a&gt; have been implemented;&lt;/li&gt;
&lt;li&gt;It makes use of the genuine &lt;a href=&quot;http://blog.synopse.info/post/2011/05/14/Virtual-Tables-in-the-SQLite3-framework&quot;&gt;SQlite3 Virtual
Table mechanism&lt;/a&gt; everywhere to allow mixed access to any database
engine;&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;TModTime / TCreateTime&lt;/code&gt; kind of fields;&lt;/li&gt;
&lt;li&gt;Enhanced stability, &lt;a href=&quot;http://blog.synopse.info/post/2011/07/01/Faster-variant-late-binding&quot;&gt;speed&lt;/a&gt; and multi-thread
implementation;&lt;/li&gt;
&lt;li&gt;Methods and functions have been enhanced, according to user feedback
(thanks you all for your interest and forum posts!);&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.synopse.info/post/2011/08/10/Framework-documentation-updated-to-revision-1.15&quot;&gt;Extended
documentation&lt;/a&gt; (more than 700 pdf pages), with new diagrams and a lot
of new content;&lt;/li&gt;
&lt;li&gt;New associated tools, like &lt;a href=&quot;http://blog.synopse.info/post/2011/08/20/Enhanced-Log-viewer&quot;&gt;LogViewer&lt;/a&gt; or &lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;SynDBExplorer&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;http://blog.synopse.info/post/2011/07/22/SynDBSQLite3%3A-SQLite3-direct-access&quot;&gt;SQLite3 core&lt;/a&gt; can
now be used without our ORM - it has been updated to the latest 3.7.8
version;&lt;/li&gt;
&lt;li&gt;Open Source (under GPL/LGPL/MPL license), running from Delphi 6 up to
XE2.&lt;/li&gt;
&lt;/ul&gt;    &lt;p&gt;As you can see, if we step into the implementation details, there is a huge
list of enhancements and new features.&lt;/p&gt;
&lt;p&gt;Let's face each unit modification list:&lt;/p&gt;
&lt;h3&gt;SynCommons&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;li&gt;TSynLog now writes the elapsed time (in us) for Enter/Leave events, and
will flush the log content to disk on any exception (for safety)&lt;/li&gt;
&lt;li&gt;new sllTrace and sllWarning levels for TSynLog class&lt;/li&gt;
&lt;li&gt;new TSynLog.DefaultExtension property (set to '.log' by default)&lt;/li&gt;
&lt;li&gt;new TSynLogFile.LogProc[] property for customer-side method profiling, with
LogProcSort method available for sorting the resulting array, and LogProcMerged
property to merge the location name timing&lt;/li&gt;
&lt;li&gt;new TSynMapFile.FindLocation method for high-level .map symbol access&lt;/li&gt;
&lt;li&gt;TSynMapFile now handles huge .map file (bigger default in-memory
buffer)&lt;/li&gt;
&lt;li&gt;fix potential GPF issue in code using ConvertHexToBin[]&lt;/li&gt;
&lt;li&gt;new TSynLog.EventCount method&lt;/li&gt;
&lt;li&gt;new TMemoryMapText.LineContains method for fast case-insensitive
search&lt;/li&gt;
&lt;li&gt;TSynTests now writes the elapsed time in each test in the final report&lt;/li&gt;
&lt;li&gt;faster late binding process for our variants custom types (i.e.
TSynTableVariantType and TSQLDBRowVariantType): you can call
SynRegisterCustomVariantType() function to register any other custom variant
type, and enhance GetProperty/SetProperty process speed&lt;/li&gt;
&lt;li&gt;includes our optimized RecordCopy procedure in replacement to the slower
default System.@CopyRecord internal RTL function&lt;/li&gt;
&lt;li&gt;our optimized Move() and FillChar() will replac the default System RTL
function, for Delphi versions prior to 2007 (which didn't contain those)&lt;/li&gt;
&lt;li&gt;new AnsiCharToUTF8(), StringToWinAnsi(), WideStringToWinAnsi(),
WideStringToUTF8(), CSVOfValue(), IdemPCharArray(), FindUnicode(),
UpperCaseUnicode(), LowerCaseUnicode() and Split() functions&lt;/li&gt;
&lt;li&gt;faster GetInt64() function&lt;/li&gt;
&lt;li&gt;Iso8601ToSecondsPUTF8Char() now returns 0 in case of unexpected format&lt;/li&gt;
&lt;li&gt;fixed issue in StrCurr64() low-level conversion routine&lt;/li&gt;
&lt;li&gt;fixed issue in Utf8DecodeToRawUnicodeUI() function&lt;/li&gt;
&lt;li&gt;new TSynTableFieldProperties.OrderedIndexRefresh method, to allow access on
OrderedIndex[] even if the index needs to be refreshed&lt;/li&gt;
&lt;li&gt;new TDynArrayHashed.AddAndMakeUniqueName() method and Hash[] property&lt;/li&gt;
&lt;li&gt;new TRawByteStringStream class (a TStream using a RawByteString as internal
storage), especially useful since Delphi 2009&lt;/li&gt;
&lt;li&gt;new TSynNameValue object, to efficiently handle Name/Value RawUTF8
pairs&lt;/li&gt;
&lt;li&gt;TTextWriter.CreateOwnedStream now create an internal TRawByteStringStream
instance for faster process and direct retrieval in the Text method&lt;/li&gt;
&lt;li&gt;JSONEncode*() global functions will use an internal TRawByteStringStream
instead of a supplied TMemoryStream&lt;/li&gt;
&lt;li&gt;new FormatUTF8() overloaded function, handling both '%' and '?' parameters
(inserting '?' as inlined :(...): parameters, with proper string quote) - with
associated regression tests&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SQLite3Commons&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;li&gt;new sftModTime / TModTime published field type in TSQLRecord, which will be
set to the current server time stamp before update/adding&lt;/li&gt;
&lt;li&gt;new sftCreateTime / TCreateTime published field type in TSQLRecord, which
will be set to the current server time stamp at record creation&lt;/li&gt;
&lt;li&gt;new TSQLRest.ServerTimeStamp property, which will return the current server
time as TTimeLog/Int64 value (will use the new /TimeStamp RESTful service to
retrieve the exact server time)&lt;/li&gt;
&lt;li&gt;TSQLRestServerStaticInMemory uses a per-Table Critical Section to have its
EngineList, EngineRetrieve, EngineAdd, EngineUpdate, EngineDelete,
EngineRetrieveBlob, EngineUpdateBlob methods begin thread-safe&lt;/li&gt;
&lt;li&gt;enhanced TSQLRestServer.URI thread-safety (e.g. Sessions access)&lt;/li&gt;
&lt;li&gt;TSQLTable.InitFieldTypes will now also use column type retrieved during
JSON parsing&lt;/li&gt;
&lt;li&gt;new TSQLTable.GetCSVValues method&lt;/li&gt;
&lt;li&gt;GetJSONValues() is now using an internal TRawByteStringStream when the
expected result is a RawUTF8 (avoid copying content twice, and is perfectly
thread-safe)&lt;/li&gt;
&lt;li&gt;the shared fTempMemoryStream is not available any more (not
thread-safe)&lt;/li&gt;
&lt;li&gt;new TSQLRest.AcquireWrite/ReleaseWrite protected methods, used by
TSQLRestServer.URI to safely write to the DB (e.g. for POST/PUT/DELETE...) with
TSQLRest.AcquireWriteTimeOut, both thread-safe and transaction-safe&lt;/li&gt;
&lt;li&gt;TSQLRest.TransactionBegin / Commit / RollBack methods now expect a
SessionID parameter in order to allow safe concurent access: writing to the
database is queued within a single client session&lt;/li&gt;
&lt;li&gt;CreateSQLMultiIndex and CreateSQLIndex methods now working on external DB
virtual tables (using SynDB.TSQLDBConnectionProperties.SQLAddIndex)&lt;/li&gt;
&lt;li&gt;new TSQLRecordProperties.ExternalTableName and ExternalDatabase fields used
by SQLite3DB to handle external SynDB-based database access&lt;/li&gt;
&lt;li&gt;code refactoring to make TSQLRestServerStatic more generic (for
SQLite3DB)&lt;/li&gt;
&lt;li&gt;TSQLRestServer.UpdateField now accepts to search by ID or by value (used
e.g. by rewritten TSQLRestServer.AfterDeleteForceCoherency method)&lt;/li&gt;
&lt;li&gt;introducing TSQLRecordExternal kind of record, able to use any SynDB
external database engine (e.g. OleDB/MSSQL/Oracle/SQLite3)&lt;/li&gt;
&lt;li&gt;new ExtractInlineParameters procedure to handle :(1234): SQL
statements&lt;/li&gt;
&lt;li&gt;new MakePrivateCopy property in TSQLTableJSON.Create, which will avoid
creating a private copy of the JSON (used e.g. in SynDBExplorer to handle very
large result sets, with half the memory)&lt;/li&gt;
&lt;li&gt;new TSQLRecordProperties.SQLUpdateSet, SQLInsertSet and AppendFieldName
properties/method (used for external DB handling)&lt;/li&gt;
&lt;li&gt;new TSQLRecord.Create, TSQLRecord.FillPrepare,
TSQLRecord.CreateAndFillPrepare, TSQLRest.OneFieldValue,
TSQLRest.MultiFieldValues, TSQLRestClient.EngineExecuteFmt and
TSQLRestClient.ListFmt overloaded methods, accepting both '%' and '?'
characters in the SQL WHERE format text, inlining '?' parameters with :(...):
and auto-quoting strings&lt;/li&gt;
&lt;li&gt;new UnicodeComparison parameter in TSQLTable.SearchValue to handle property
non WinAnsi (code page 1252) characters&lt;/li&gt;
&lt;li&gt;fixed issue in TPropInfo.GetBinary method with dynamic arrays (used e.g. by
TSQLRestServerStaticInMemory.SaveToBinary)&lt;/li&gt;
&lt;li&gt;fixed issue with TAuthSession.IDCardinal=0 after 76 connections&lt;/li&gt;
&lt;li&gt;fixed issue in SetInt64Prop() with a setter method&lt;/li&gt;
&lt;li&gt;fixed potential issue in TSQLTable.SearchValue in case of invalid Client
supplied parameter (now checks TSQLRest class type)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SQLite3&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;updated SQLite3 engine to version 3.7.8&lt;/li&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;li&gt;transactions now following a safe concurent access (both thread-safe and
client/connection-safe) - but authentication should be enabled&lt;/li&gt;
&lt;li&gt;the SQLite3 wrapper is now located in a separate SynSQLite3 unit: this will
allow to use it as a separate database engine, e.g. using SynDB classes without
the overhead/features of our mORMot framework&lt;/li&gt;
&lt;li&gt;statement cache is now shared with SynDBSQLite3, via the new
TSQLStatementCached object as defined in SynSQLite3.pas&lt;/li&gt;
&lt;li&gt;now TSQLRestServerDB will unregister any TSQLVirtualTableModuleServerDB to
avoid random GPF in TSQLVirtualTable.Destroy&lt;/li&gt;
&lt;li&gt;TSQLRestClientDB and TSQLRestServerDB constructors now accept an optional
Password parameter, associated to the supplied file name, in order to use
database encryption&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynSQLite3&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;first public release, corresponding to mORMot Framework 1.15&lt;/li&gt;
&lt;li&gt;new unit extracting the SQLite3 wrapper from the previous SQLite3 unit:
this unit can therefore be used with our SynDB classes (via SynDBSQLite3),
without SQLite3Commons overhead (and features)&lt;/li&gt;
&lt;li&gt;added TSQLRequest.BindNull method and associated sqlite3_bind_null
function&lt;/li&gt;
&lt;li&gt;fixed issue with TSQLDataBase with UseCache=false&lt;/li&gt;
&lt;li&gt;new TSQLStatementCached object, for caching of prepared SQLite3
statements&lt;/li&gt;
&lt;li&gt;TSQLDatabase constructors now accepts an optional Password parameter,
associated to the supplied file name, in order to use database encryption (not
finished nor fully tested feature)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynPDF&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynGdiPlus&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;li&gt;handle TIFF saving with diverse compression methods&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynBigTable&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynZip&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynCrypto&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynCrtSock&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;unit now tested with Delphi XE2 (32 Bit)&lt;/li&gt;
&lt;li&gt;fixed issue in HTTP_RESPONSE.SetHeaders&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SQLite3DB&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;first public release, corresponding to mORMot Framework 1.15&lt;/li&gt;
&lt;li&gt;new unit handling Virtual tables for DB direct access classes for the
mORMot framework&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynDB&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SynDB unit extracted from previous SynOleDB.pas&lt;/li&gt;
&lt;li&gt;TQueryValue.As* methods now handle NULL column as 0 or ''&lt;/li&gt;
&lt;li&gt;added new TSQLDBRowVariantType custom variant type, allowing late binding
access to row columns (not for Delphi 5) - see RowData method&lt;/li&gt;
&lt;li&gt;fixed transaction handling in a safe abstract manner&lt;/li&gt;
&lt;li&gt;TSQLDBStatement class now expects a prepared statement behavior, therefore
TSQLDBStatementPrepared class has been merged into its parent class, and
inherited classes have been renamed TSQLDBStatementWithParams[AndColumns]&lt;/li&gt;
&lt;li&gt;new TSQLDBStatement.FetchAllAsJSON method for JSON retrieval as
RawUTF8&lt;/li&gt;
&lt;li&gt;exposed FetchAllAsJSON method for ISQLDBRows interface&lt;/li&gt;
&lt;li&gt;made the code compatible with Delphi 5&lt;/li&gt;
&lt;li&gt;new TSQLDBConnectionProperties.SQLIso8601ToDate virtual method&lt;/li&gt;
&lt;li&gt;code refactoring for better metadata (database and table schemas) handling,
including GetTableNames, GetFields, GetFieldDefinitions and GetForeignKey
methods - will work with OleDB metadata and direct Oracle sys.all_* tables&lt;/li&gt;
&lt;li&gt;new TSQLDBConnectionProperties.SQLCreate/SQLAddColumn/SQLAddIndex virtual
methods (SQLCreate and SQLAddColumn will use the new protected SQLFieldCreate
virtual method to retrieve the SQL field definition from protected
fSQLCreateField[Max] properties) - as a result, SQL statement generation as
requested for mORMot is now much more generic than previously&lt;/li&gt;
&lt;li&gt;new overloaded TSQLDBStatement.Execute() method, able to mix % and ?
parameters in the SQL statement&lt;/li&gt;
&lt;li&gt;new TSQLDBStatement.BindNull() method&lt;/li&gt;
&lt;li&gt;new TSQLDBConnectionProperties.NewThreadSafeStatementPrepared and
TSQLDBConnection.NewStatementPrepared methods, able to be overriden to
implement a SQL statement caching (used e.g. for SynDBSQLite3)&lt;/li&gt;
&lt;li&gt;new TSQLDBConnection.ServerTimeStamp property, which will return the
external database Server current date and time as TTimeLog/Int64 value (current
implementation handle Oracle, MSSQL and MySQL database engines - with SQLite3,
this will be the local PC time, just as for other DB engines)&lt;/li&gt;
&lt;li&gt;new overloaded TSQLDBStatement.Bind() method, which can bind an array of
const (i.e. an open list of Delphi arguments) to a statement&lt;/li&gt;
&lt;li&gt;new overloaded TSQLDBStatement.Bind() and ColumnToVarData() methods, able
to bind or retrieve values from a TVarData/TVarDataDynArray (used e.g. for
direct access to/from SQLite3 virtual table in the SQLite3DB unit)&lt;/li&gt;
&lt;li&gt;new ColumnTimeStamp method for TSQLDBStatement/ISQLDBRows, returning a
TTimeLog/Int64 value for a date/time column&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynOleDB&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;SynDB unit extracted from previous SynOleDB.pas&lt;/li&gt;
&lt;li&gt;several fixes and speed enhancements&lt;/li&gt;
&lt;li&gt;made the code compatible with Delphi 5&lt;/li&gt;
&lt;li&gt;TOleDBStatement class now follows the prepared statement pattern introduced
with its parent TSQLDBStatement&lt;/li&gt;
&lt;li&gt;now able to retrieve table names and column information from OleDB metadata
including GetTableNames, GetFields, GetFieldDefinitions and GetForeignKey
methods - able to use faster direct SQL retrieval (e.g. for Oracle / MS
SQL)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynDBOracle&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;first public release, corresponding to mORMot Framework 1.15&lt;/li&gt;
&lt;li&gt;new unit implementing fast Oracle DB direct access classes (via OCI)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;SynDBSQLite3&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;first public release, corresponding to mORMot Framework 1.15&lt;/li&gt;
&lt;li&gt;new unit implementing SQLite3 direct access classes to be used with our
SynDB architecture&lt;/li&gt;
&lt;li&gt;use the SQLite3 engine, as wrapped via the new separated SynSQLite3
unit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;
To get it, go to &lt;a href=&quot;http://synopse.info/fossil/wiki?name=Downloads&quot;&gt;this
download page&lt;/a&gt;, or &lt;a href=&quot;http://synopse.info/fossil&quot;&gt;use the
source&lt;/a&gt;...&lt;/p&gt;
&lt;p&gt;Feedback and questions are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=449&quot;&gt;welcome in our forum&lt;/a&gt;, just
as usual.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Some thoughts about OSX integration in XE2</title>
    <link>http://blog.synopse.info/post/2011/09/25/Some-thoughts-about-OSX-integration-in-XE2</link>
    <guid isPermaLink="false">urn:md5:5a4debe4971f26a476b8402349374d0c</guid>
    <pubDate>Sun, 25 Sep 2011 19:54:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>blog</category><category>CrossPlatform</category><category>Delphi</category><category>FireMonkey</category><category>Kylix</category><category>Linux</category><category>MaxOSX</category>    
    <description>&lt;p&gt;You know all that one of the most exciting features of Delphi XE2 is the
MaxOSX Cross-Platform feature.&lt;br /&gt;
You've got the UI part, &lt;a href=&quot;http://blog.synopse.info/post/2011/08/08/Our-mORMot-won-t-hibernate-this-winter%2C-thanks-to-FireMonkey&quot;&gt;
that is FireMonkey,&lt;/a&gt; but underneath, you did have some RTL modifications in
order to let our Windows-centric solutions be OSX ready.&lt;/p&gt;
&lt;p&gt;The first main step was to make our code speak with the &amp;quot;Objective-C&amp;quot; way of
coding.&lt;/p&gt;
&lt;p&gt;Objective-C is the primary language used for Apple's Cocoa API, and it was
originally the main language on NeXT's NeXTSTEP OS. It's some object-oriented C
variant, but something other than C++ or Java. In fact, Objective-C sounds more
like a SmallTalk variance of C than another  C++/Java/C# flavor. For
instance, the Objective-C model of object-oriented programming is based on
message passing to object instances: this is just another way of doing it. It
has some advantages, and disadvantages (I don't want to troll here) - but it is
definitively nice. And the memory model is just something else, more close to
our reference-counting way (as in Delphi &lt;em&gt;interface&lt;/em&gt; implementation)
than a garbage collector.&lt;/p&gt;    &lt;p&gt;About Objective-C, it sounds like if Embarcadero did make its own
Delphi-based wrapper around the OOP layout of this technology. In short,
messages were encapsulated inside methods, and exposed as
interfaces. Embarcadero RTL team used the new RTTI and generics language
features to expose the Objective-C API into standard Delphi interfaces.&lt;/p&gt;
&lt;p&gt;FPC did extend the compiler so that Objective-C style of coding appeared in
the code: this is the so-called &amp;quot;Objective Pascal&amp;quot; mode, which handle both its
message and memory model as native features, at the compiler level.&lt;/p&gt;
&lt;p&gt;I don't have any preference. Both have pros and cons. The FPC solution
sounds lighter and automated (the OSX APIs are created using an automated
process). The EMB solution sounds more &amp;quot;pascalish&amp;quot;, since the language was not
modified, but some wrappers were designed over the OSX APIs.&lt;/p&gt;
&lt;p&gt;What is nice in both case is that we are not stick into the flat Carbon API,
which is 32 bit only. Calling directly the Cocoa APIs will release the full
power of Mac OSX, and allow to write 64 bit applications (already for FPC, in
the future for Delphi).&lt;/p&gt;
&lt;p&gt;The new &amp;quot;unit scope names&amp;quot; introduced in Delphi XE2 for handling several
platforms (Windows/Posix or VCL/FireMonkey) do make sense to me. By the way, it
seems definitively better than the previous LibC huge unit, as used for Kylix.
And perhaps more rigid than the FPC library.&lt;br /&gt;
In practice, I had to modify our framework source code for all VCL-refering
unit names. But nothing difficult - just one step &lt;a href=&quot;http://blog.synopse.info/post/2011/08/08/Our-mORMot-won-t-hibernate-this-winter%2C-thanks-to-FireMonkey&quot;&gt;
preparing for FireMonkey&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In all cases, this is a quite interesting step into cross-platform.&lt;/p&gt;
&lt;p&gt;Nice talking about it &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?pid=2683#p2683&quot;&gt;on our forum&lt;/a&gt;, if
you wish.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse SQLite3 framework is now mORMot</title>
    <link>http://blog.synopse.info/post/2011/09/25/Synopse-SQLite3-framework-is-now-mORMot</link>
    <guid isPermaLink="false">urn:md5:90e4910fba876295cf3453145e71a570</guid>
    <pubDate>Sun, 25 Sep 2011 13:59:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>SQLite3 Framework</category>
        <category>Database</category><category>Delphi</category><category>Documentation</category><category>mORMot</category><category>ORM</category><category>Rest</category><category>SQL</category><category>SQLite3</category><category>Synopse</category>    
    <description>    &lt;p&gt;&lt;img src=&quot;http://blog.synopse.info/public/.mORMot_m.jpg&quot; alt=&quot;&quot; title=&quot;mORMot, août 2011&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In case you were redirected from the previous &amp;quot;&lt;em&gt;Synopse SQLite3
framework&lt;/em&gt;&amp;quot; category link, here is the new thread to be used instead:&lt;br /&gt;
&lt;a href=&quot;http://blog.synopse.info/category/Open-Source-Projects/mORMot-Framework&quot;&gt;http://blog.synopse.info/category/Open-Source-Projects/mORMot-Framework&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since revision 1.15 of the framework, it is able to connect to any database
engine (therefore is &lt;a href=&quot;http://blog.synopse.info/post/2011/08/07/SQLite3-powered%2C-not-SQLite3-limited&quot;&gt;not limited to
&lt;em&gt;SQLite3&lt;/em&gt;&lt;/a&gt;&lt;em&gt;)&lt;/em&gt;, and is now called &lt;em&gt;mORMot&lt;/em&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Synopse PDF Engine 1.15</title>
    <link>http://blog.synopse.info/post/2011/09/25/Synopse-PDF-Engine-1.15</link>
    <guid isPermaLink="false">urn:md5:dca85db4391bd10063c469482f16c5f0</guid>
    <pubDate>Sun, 25 Sep 2011 10:49:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Synopse PDF engine</category>
        <category>Delphi</category><category>PDF</category><category>Source</category><category>Unicode</category>    
    <description>&lt;p&gt;For our PDF generation Open-Source library, this is a small fix update.&lt;/p&gt;
&lt;p&gt;It can now be compiled under Delphi XE2.&lt;br /&gt;
But it's still working from all previous IDE versions, starting with Delphi 5,
and still 100% free - released under GPL/LGPL/MPL license, choice is yours.&lt;/p&gt;    Source code is to be downloaded &lt;a href=&quot;http://synopse.info/fossil/wiki?name=Downloads&quot;&gt;from this page&lt;/a&gt;.
&lt;p&gt;Feedback and questions are welcome on our forum, just as usual.&lt;br /&gt;
See &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=447&quot;&gt;http://synopse.info/forum/viewtopic.php?id=447&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>L10n and i18n in our framework</title>
    <link>http://blog.synopse.info/post/2011/09/14/L10n-and-i18n-in-our-framework</link>
    <guid isPermaLink="false">urn:md5:05f7c21c254d60a186e581564cf311d2</guid>
    <pubDate>Wed, 14 Sep 2011 20:31:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>mORMot Framework</category>
        <category>Delphi</category><category>i18n</category><category>mORMot</category><category>Unicode</category><category>UserInterface</category>    
    <description>&lt;p&gt;In computing, internationalization and localization (also spelled
internationalisation and localisation) are means of adapting computer software
to different languages, regional differences and technical requirements of a
target market:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Internationalization&lt;/em&gt; (i18n) is the process of designing a software
application so that it can be adapted to various languages; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Localization&lt;/em&gt; (L10n) is the process of adapting internationalized
software for a specific region or language by adding locale-specific components
and translating text, e.g. for dates display.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our framework handle both features, via the &lt;code&gt;SQLite3i18n.pas&lt;/code&gt;
unit. For instance, &lt;code&gt;resourcestring&lt;/code&gt; defined in the source code are
retrieved from the executable and can be translated on the fly. The unit
extends this to visual forms, and even captions generated from RTTI.&lt;/p&gt;
&lt;p&gt;In short, making your software open to any language is handled by the
framework, from the bottom-up.&lt;/p&gt;    &lt;h3&gt;Application i18n and L10n&lt;/h3&gt;
&lt;p&gt;The unit expects all textual content (both &lt;code&gt;resourcestring&lt;/code&gt; and
RTTI derived captions) to be correct English text. A list of all used textual
elements will be retrieved then hashed into an unique numerical value. When a
specific locale is set for the application, the unit will search for a
&lt;code&gt;.msg&lt;/code&gt; text file in the executable folder matching the expected
locale definition. For instance, it will search for &lt;code&gt;FR.msg&lt;/code&gt; for
translation into French.&lt;/p&gt;
&lt;p&gt;In order to translate all the user interface, a corresponding
&lt;code&gt;.msg&lt;/code&gt; file is to be supplied in the executable folder. Neither the
source code, nor the executable is to be rebuild to add a new language. And
since this file is indeed a plain textual file, even a non developer (e.g. an
end-user) is able to add a new language, starting from another
&lt;code&gt;.msg&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Creating the reference file&lt;/h3&gt;
&lt;p&gt;In order to begin a translation task, the &lt;code&gt;SQlite3i18n.pas&lt;/code&gt; unit
is able to extract all textual resource from the executable, and create a
reference text file, containing all English sentences and words to be
translated, associated with their numerical hash value.&lt;/p&gt;
&lt;p&gt;It will in fact:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Extract all &lt;code&gt;resourcestring&lt;/code&gt; text; &lt;/li&gt;
&lt;li&gt;Extract all captions generated from RTTI (e.g. from enumerations or class
properties names); &lt;/li&gt;
&lt;li&gt;Extract all embedded &lt;code&gt;dfm&lt;/code&gt; resources, and create per-form
sections, allowing a custom translation of displayed captions or hints.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This creation step needs a compilation of the executable with the
&lt;code&gt;EXTRACTALLRESOURCES&lt;/code&gt; conditional defined, &lt;em&gt;globally&lt;/em&gt; to the
whole application (a full &lt;em&gt;rebuild&lt;/em&gt; is necessary after having added or
suppressed this conditional from the &lt;em&gt;Project / Options /
Folders-Conditionals&lt;/em&gt; IDE field).&lt;/p&gt;
&lt;p&gt;Then the &lt;code&gt;ExtractAllResources&lt;/code&gt; global procedure is to be called
somewhere in the code.&lt;/p&gt;
&lt;p&gt;For instance, here is how this is implemented in
!TMainForm.FormShow!LibMainDemoFileMain.pas, for the framework main demo:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;procedure&lt;/strong&gt; TMainForm.FormShow(Sender: TObject);
&lt;strong&gt;begin&lt;/strong&gt;
&lt;span style=&quot;background-color:yellow;&quot;&gt;&lt;em&gt;{$ifdef EXTRACTALLRESOURCES}&lt;/em&gt;&lt;/span&gt;
  &lt;span style=&quot;background-color:yellow;&quot;&gt;ExtractAllResources(&lt;/span&gt;
    &lt;em&gt;// first, all enumerations to be translated&lt;/em&gt;
    &lt;span style=&quot;background-color:yellow;&quot;&gt;[TypeInfo(TFileEvent),TypeInfo(TFileAction),TypeInfo(TPreviewAction)],&lt;/span&gt;
    &lt;em&gt;// then some class instances (including the TSQLModel will handle all TSQLRecord)&lt;/em&gt;
    &lt;span style=&quot;background-color:yellow;&quot;&gt;[Client.Model],&lt;/span&gt;
    &lt;em&gt;// some custom classes or captions&lt;/em&gt;
    [],[]);
  &lt;span style=&quot;background-color:yellow;&quot;&gt;Close;&lt;/span&gt;
&lt;em&gt;{$else}&lt;/em&gt;
  &lt;em&gt;//i18nLanguageToRegistry(lngFrench);
{$endif}&lt;/em&gt;
  Ribbon.ToolBar.ActivePageIndex := 1;
&lt;strong&gt;end&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;TFileEvent&lt;/code&gt; and &lt;code&gt;TFileAction&lt;/code&gt; enumerations RTTI
information is supplied, together with the current &lt;code&gt;TSQLModel&lt;/code&gt;
instance. All &lt;code&gt;TSQLRecord&lt;/code&gt; classes (and therefore properties) will
be scanned, and all needed English caption text will be extracted.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Close&lt;/code&gt; method is then called, since we don't want to use the
application itself, but only extract all resources from the executable.&lt;/p&gt;
&lt;p&gt;Running once the executable will create a &lt;code&gt;SynFile.messages&lt;/code&gt; text
file in the &lt;code&gt;SynFile.exe&lt;/code&gt; folder, containing all English text:&lt;/p&gt;
&lt;pre&gt;
[TEditForm]
Name.EditLabel.Caption=_2817614158   Name
KeyWords.EditLabel.Caption=_3731019706   KeyWords
&lt;br /&gt;[TLoginForm]
Label1.Caption=_1741937413   &amp;amp;User name:
Label2.Caption=_4235002365   &amp;amp;Password:
&lt;br /&gt;[TMainForm]
Caption=_16479868    Synopse SQLite3 Framework demo - SynFile
&lt;br /&gt;[Messages]
2784453965=Memo
2751226180=Data
744738530=Safe memo
895337940=Safe data
2817614158=Name
1741937413=&amp;amp;User name:
4235002365=&amp;amp;Password:
16479868= Synopse SQLite3 Framework demo - SynFile
940170664=Content
3153227598=None
3708724895=Page %d / %d
2767358349=Size: %s
4281038646=Content Type: %s
2584741026=This memo is password protected.|Please click on the &amp;quot;Edit&amp;quot; button to show its content.
3011148197=Please click on the &amp;quot;Extract&amp;quot; button to get its content.
388288630=Signed,By %s on %s
(...)
&lt;/pre&gt;
&lt;p&gt;The main section of this text file is named &lt;code&gt;[Messages]&lt;/code&gt;. In
fact, it contains all English extracted texts, as
&lt;code&gt;NumericalKey=EnglishText&lt;/code&gt; pairs. Note this will reflect the exact
content of &lt;code&gt;resourcestring&lt;/code&gt; or RTTI captions, including formating
characters (like &lt;code&gt;%d&lt;/code&gt;), and replacing line feeds (&lt;code&gt;#13&lt;/code&gt;)
by the special character (a line feed is not expected on a one-line-per-pair
file layout). Some other text lines are separated by a comma. This is usual for
instance for hint values, as expected by the code.&lt;/p&gt;
&lt;p&gt;As requested, each application form has its own section (e.g.
&lt;code&gt;[TEditForm]&lt;/code&gt;, &lt;code&gt;[TMainForm]&lt;/code&gt;), proposing some default
translation, specified by a numerical key (for instance
&lt;code&gt;Label1.Caption&lt;/code&gt; will use the text identified by 1741937413 in the
&lt;code&gt;[Messages]&lt;/code&gt; section). The underline character before the numerical
key is used to refers to this value. Note that if no &lt;code&gt;_NumericalKey&lt;/code&gt;
is specified, a plain text can be specified, in order to reflect a specific use
of the generic text on the screen.&lt;/p&gt;
&lt;h3&gt;Adding a new language&lt;/h3&gt;
&lt;p&gt;In order to translate the whole application into French, the following
&lt;code&gt;SynFile.FR&lt;/code&gt; file could be made available in the
&lt;code&gt;SynFile.exe&lt;/code&gt; folder:&lt;/p&gt;
&lt;pre&gt;
[Messages]
2784453965=Texte
2751226180=Données
744738530=Texte sécurisé
895337940=Données sécurisées
2817614158=Nom
1741937413=&amp;amp;Nom utilisateur:
4235002365=&amp;amp;Mot de passe:
16479868= Synopse mORMot Framework demo - SynFile
940170664=Contenu
3153227598=Vide
3708724895=Page %d / %d
2767358349=Taille: %s                                                        4281038646=Type de contenu: %s                                               2584741026=Le contenu de ce memo est protégé par un mot de passe.|Choisissez &amp;quot;Editer&amp;quot; pour le visualiser.
3011148197=Choisissez &amp;quot;Extraire&amp;quot; pour enregistrer le contenu.
388288630=Signé,Par %s le %s
(....)
&lt;/pre&gt;
&lt;p&gt;Since no form-level custom captions have been defined in this
&lt;code&gt;SynFile.FR&lt;/code&gt; file, the default numerical values will be used. In our
case, &lt;code&gt;Name.EditLabel.Caption&lt;/code&gt; will be displayed using the text
specified by 2817614158, i.e. &lt;code&gt;'Nom'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that the special characters &lt;code&gt;%s %d ,&lt;/code&gt; markup was preserved:
only the plain English text has been translated to the corresponding
French.&lt;/p&gt;
&lt;h3&gt;Language selection&lt;/h3&gt;
&lt;p&gt;User Interface language can be specified at execution.&lt;/p&gt;
&lt;p&gt;By default, it will use the registry to set the language. It will need an
application restart, but it will also allow easier translation of all forms,
using a low-level hook of the &lt;code&gt;TForm.Create&lt;/code&gt; constructor.&lt;/p&gt;
&lt;p&gt;For instance, if you set in &lt;em&gt;FileMain.pas&lt;/em&gt;, for the framework main
demo:&lt;/p&gt;
&lt;pre&gt;
&lt;strong&gt;procedure&lt;/strong&gt; TMainForm.FormShow(Sender: TObject);
&lt;strong&gt;begin&lt;/strong&gt;
  (...)
  &lt;span style=&quot;background-color:yellow;&quot;&gt;i18nLanguageToRegistry(lngFrench);&lt;/span&gt;
  Ribbon.ToolBar.ActivePageIndex := 1;
&lt;strong&gt;end&lt;/strong&gt;;
&lt;/pre&gt;
&lt;p&gt;Above code will set the main application language as French. At next
startup, the content of a supplied &lt;code&gt;SynFileFR.msg&lt;/code&gt; file will be used
to translate all screen layout, including all RTTI-generated captions.&lt;/p&gt;
&lt;p&gt;Of course, for a final application, you'll need to change the language by a
common setting. See &lt;code&gt;i18nAddLanguageItems, i18nAddLanguageMenu&lt;/code&gt; and
&lt;code&gt;i18nAddLanguageCombo&lt;/code&gt; functions and procedures to create your own
language selection dialog, using a menu or a combo box, for instance.&lt;/p&gt;
&lt;h3&gt;Localization&lt;/h3&gt;
&lt;p&gt;Take a look at the &lt;code&gt;TLanguageFile&lt;/code&gt; class. After the main language
has been set, you can use the global &lt;code&gt;Language&lt;/code&gt; instance in order to
localize your application layout.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;SQlite3i18n&lt;/code&gt; unit will register itself to some methods of
&lt;code&gt;SQlite3Commons.pas&lt;/code&gt;, in order to translate the RTTI-level text into
the current selected language. See for instance &lt;code&gt;i18nDateText&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
As usual, feedbacks and comments are &lt;a href=&quot;http://synopse.info/forum/viewtopic.php?id=434&quot;&gt;welcome on our forum!&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Using Extended in Delphi XE2 64 bit</title>
    <link>http://blog.synopse.info/post/2011/09/13/Using-Extended-in-Delphi-XE2-64-bit</link>
    <guid isPermaLink="false">urn:md5:4d03506eec8984e34b8aee217ac30ad1</guid>
    <pubDate>Mon, 12 Sep 2011 23:13:00 +0200</pubDate>
    <dc:creator>A.Bouchez</dc:creator>
        <category>Pascal Programing</category>
        <category>64bit</category><category>asm</category><category>blog</category>    
    <description>&lt;p&gt;Unfortunately, Delphi's 64-bit compiler (dcc64) and RTL do not support
80-bit &lt;code&gt;extended&lt;/code&gt; floating point values on Win64, but silently alias
&lt;code&gt;Extended = Double&lt;/code&gt; on Win64.&lt;/p&gt;
&lt;p&gt;There are situations, however, where this is clearly undesirable, e.g. if
the additional precision gained from &lt;code&gt;Extended&lt;/code&gt; is required.&lt;/p&gt;
&lt;p&gt;The Open-source &lt;code&gt;uTExtendedX87&lt;/code&gt; unit provides a
replacement FPU-backed 80-bit Extended floating point type
(&lt;code&gt;TExtendedX87&lt;/code&gt;) for Win64.&lt;/p&gt;    &lt;p&gt;Quoted from the unit presentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The aim of this unit is to provide basic 80-bit extended capabilities for
Delphi x64 by providing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A dedicated FPU-backed TExtendedX87 type that behaves as an 80-bit extended
value both on 32-bit and 64-bit platforms&lt;/li&gt;
&lt;li&gt;Re-implementing basic routines from the System unit for this type on 32-bit
and 64-bit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Users should be able to either re-declare their variables explictly as
&lt;code&gt;TExtendedX87&lt;/code&gt; or redeclare the type &lt;code&gt;extended&lt;/code&gt; as&lt;br /&gt;
&lt;code&gt;Extended = TExtendedX87;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Freely downloaded from Embarcadero's &lt;a href=&quot;http://cc.embarcadero.com/Item/28488&quot;&gt;Code Central&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This unit is very well written. It uses x87 assembly code and operator
overloading to provide 80 bit fast computation under Delphi XE2 64 bit
compiler.&lt;br /&gt;
Most of existing code base on the &lt;code&gt;Extended&lt;/code&gt; type can be reused
directly, or shared among both 32 bit and 64 bit versions.&lt;/p&gt;
&lt;p&gt;Just &lt;a href=&quot;http://blog.synopse.info/post/2011/05/27/Calling-a-64-bit-library-from-a-Delphi-32-bit-process&quot;&gt;another
gem&lt;/a&gt; of Philipp M. Schlüter.&lt;br /&gt;
Open Source and Delphi rock!&lt;/p&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>
