Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
mORMot & Friends
Arnaud Bouchez
Opinions
Ahead
Great times for us
Great times for us
Delphi is Hype
Delphi + Pascal > Ruby
If you say Delphi is dead,
YOU are dead!
Two Languages In One
Application Language
like Java C# Ruby Python
System Language
like C C++
Dual Memory Management
Automatic Memory Management
COW and refcount
Manual Memory Management
Uses much less CPU/RAM
Server...
Dual Memory Management
Automatic Memory Management
COW and refcount
Manual Memory Management
Uses much less CPU/RAM
Server...
New opportunities
New platforms
New compilers
Great communities
Third parties
Open Source
Unleash your power
Decades of experience
Business knowledge
Productive tools
Unleash your power
Decades of experience
Business knowledge
Productive tools
Innovative concepts
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
Open Source
Started in 2008
5769 checkins since 2010
77 COCOMO years
Open Source
Started in 2008
6215 checkins since 2010
86 COCOMO years
($ 4,746,754)
http://synopse.info/fossil
http://githu...
LOC
Code 324,415
Comments 75,913
Blanks 34,197
Total 434,525
http://synopse.info/fossil
http://github.com/synopse/mORMot
h...
Doc as Specs
Exhaustive
Maintained
Open Source
http://synopse.info/files/html
2100 pages of pdf
SynProject powered
Test Driven
27,019,014 tests
Write the test
Fail the test
Write the implementation
Pass the test
Test Driven
27,019,014 tests
Regression
Performance
Thread safety
Cross platform – Cross compiler
Test Driven
27,019,014
http://synopse.info/forum
Feedback and support
Topics 3,603
Posts 22,112
Registered users 1,662
Hall of fame
Alexander (sha)
Alexander (volax)
AlexPirate
Alfred Glaenzer (alf)
Arnaud Bouchez
Aweste
Bas Schouten
BigStar...
Hall of fame
Alexander (sha)
Alexander (volax)
AlexPirate
Alfred Glaenzer (alf)
Arnaud Bouchez
Aweste
Bas Schouten
BigStar...
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
Architecture Switch
BBM → Clean
nTier → SOA
SOAP → REST
RAD → MVC/MVVM
SQL → ORM
NoSQL → ODM
OOP → SOLID
Architecture Switch
### → ###
… see corresponding
set of Slides
Design with Interfaces
What, not how
A type that comprises
abstract virtual methods
Rely on abstraction
rather than implem...
Design with Interfaces
Abstraction is your health
Publish classes as services
Test, mock
Write SOLID code
Design with Interfaces
Abstraction is your health
Publish classes as services
Test, mock
Write SOLID code
and manage memor...
Design with Interfaces
Abstraction is your health
Publish classes as services
Test, mock
Write SOLID code
and manage memor...
SOLID Principles
Single responsibility
Open/closed
Liskov substitution
Interface segregation
Dependency inversion
.. unlea...
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
Cross Cutting Features
UTF-8 JSON
TDynArray
TDocVariant
Logging
Testing
Compression
Crypto ECC
PDF
Mustache
SpiderMonkey
U...
SynCommons
UTF-8 JSON
From the ground up
With objects, records,
dynamic arrays, variants, any value
Performance and integr...
SynCommons
TDynArray
Wrapper to an existing dynamic array
TList<> on steroids
e.g. sorting, search,
binary or JSON seriali...
SynCommons
TDynArray
In conjunction with records and variants:
value objects
data transfer objects (DTO)
SynCommons
TDocVariant
Stores documents
objects, arrays, variants
with low overhead
natively JSON
with late-binding support
SynCommons
TDocVariant
var V: variant; // stored as any variant
...
TDocVariant.New(V);
// or slightly slower V := TDocVar...
SynCommons
TDocVariant
V.name := 'Mark'; // overwrite a property value
writeln(V.name); // will write 'Mark'
V.age := 12; ...
SynCommons
TDocVariant + mORMot.pas
TSQLRecordData = class(TSQLRecord)
private
fName: RawUTF8;
fData: variant;
public
publ...
TDocVariant + mORMot.pas
property Data: variant read fData write fData;
We store a TDocVariant in Data
to mutate a SQL dat...
TDocVariant + mORMot.pas
property Data: variant read fData write fData;
We store a TDocVariant in Data
to mutate a SQL dat...
TDocVariant + mORMot.pas
var aRec: TSQLRecordData;
aID: integer;
begin
// initialization of one record
aRec := TSQLRecordD...
TDocVariant + mORMot.pas
// now we can play with the data, e.g. via late-binding:
writeln(aRec.Name); // will write 'Joe'
...
TDocVariant + mORMot.pas
property Data: variant read fData write fData;
Data will be stored as TEXT
in the underlying RDBMS
TDocVariant + mORMot.pas
property Data: variant read fData write fData;
Data will be stored as TEXT
in the underlying RDBM...
SynCommons
Logging
Low overhead
Local or remote
Fast viewer tool
Exception catch, stack trace
Used by the whole framework
SynCommons
Testing
Light and cross-platform
Convention over configuration
Stubs and mocks
Compression
SynZip
faster unzip
SynLZO
SynLZ
speed symmetric
SynCrtSock
Cross-platform Network library
Socket WinHTTP WinINet clients
Optimized HTTP server
IOCP driven
http.sys kernel...
SynCrypto
SHA 1 – 256
MD5 – RC4
AES 128 – 192 – 256
ECB – CBC – OFB – CTR
HMAC - PBKDF2
PRNG
Pascal and/or optimized asm
(...
SynECC
Certificate-based
public-key cryptography
using cutting edge ECC-secp256r1
For data signature,
content encryption
a...
SynPDF
From TCanvas to PDF
Unicode
Font embedding
Encryption
SynPDF
From TCanvas to PDF
Unicode
Font embedding
Encryption
Code-based report engine
SynMustache
Mustache template system
Data context as TDocVariant
UTF-8 JSON
With extensions
SynMustache
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green",...
SynMustache
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li...
SynMustache
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">b...
SynMustache
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green",...
SynMustache
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li...
SynMustache
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">b...
SynMustache
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green",...
SynMustache
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li...
SynMustache
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">b...
SynMustache
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green",...
SynMustache
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li...
SynMustache
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">b...
SynSM/SyNode
Latest Spidermonkey
Javascript JIT engine
Call JS from Delphi
TSMVariant for late binding
SynSM/SyNode
Latest Spidermonkey
Javascript JIT engine
Call JS from Delphi
TSMVariant for late binding
SynSM + mORMot = mu...
Sample 23
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
DB Layer
SynMongoDB
NoSQL
SynDB
SQL
Uncoupled features: could be used
without the ORM/SOA/MVC framework
SynMongoDB
MongoDB native access
BSON types - TBSONVariant
TDocVariant
Extended JSON
Sample 24
SynDB
Direct RDBMS access layer
Not linked to DB.pas
Multi providers
UTF-8 JSON
Interface based
Knows SQL dialects
SynDBEx...
SynDB
Not linked to DB.pas
Enter the 21th century
Less data types
By-pass slow TDataSet
Unicode even before Delphi 2009
Ar...
SynDB
Providers
SynDB
Connect to a DB
var Props: TSQLDBConnectionProperties;
...
Props := TOleDBMSSQLConnectionProperties.Create(
'.SQLEXP...
SynDB
Execute statements
procedure UseProps(Props: TSQLDBConnectionProperties);
var I: ISQLDBRows;
begin
I := Props.Execut...
SynDB
Late-binding
procedure UseProps(Props: TSQLDBConnectionProperties);
var Row: Variant;
begin
with Props.Execute(
'sel...
SynDB
TQuery emulation
Q := TQuery.Create(aSQLDBConnection);
try
Q.SQL.Clear; // optional
Q.SQL.Add('select * from DOMAIN....
SynDB
Fast read/only TDataSet
ds1.DataSet := ToDataSet(ds1,
aProps.Execute('select * from people',[]));
Read/write TClient...
SynDB
Remote access via HTTP
SynDB
Remote access via HTTP
http.sys based server
SynLZ compression
Digital signature
Authentication
SynDB
Remote access via HTTP
Mutate SQLite3 into a
high performance Client-Server RDBMS
No library to deploy on Client sid...
SynDB
Remote access via HTTP
Mutate SQLite3 into a
high performance Client-Server RDBMS
No library to deploy on Client sid...
SynDBExplorer
Manage and request your DBs
Any supported database
High performance grid
Export to CSV or SQLite3
SQLite3 in...
SynDBExplorer
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
ORM/ODM/SOA/MVC
ORM/ODM/SOA/MVC
RESTful
ORM/ODM
SOA
Real Time
MVC
RESTful ORM
Not an ORM
with a transmission layer
But a RESTful ORM
from the ground up
TSQLRest
RESTful access
Convention over configuration
CRUD methods - Cache
Authentication – Authorization
Services
On Clie...
TSQLRest
TSQLRest
TSQLRest
TSQLRest
TSQLRestServer
Server Storage
In-memory
SQLite3 local
External SQL
External NoSQL
Redirected
TSQLRestServer
TSQLRestServer
Per table redirection
TSQLRestClient
Client Access
In process
Library
HTTP
Named pipes
Windows messages
TSQLRest Cache
TSQLRecord
Convention over configuration
TSQLSampleRecord = class(TSQLRecord)
private
fQuestion: string;
fName: string;
fT...
TSQLRecord
Convention over configuration
TSQLSampleRecord = class(TSQLRecord)
private
fQuestion: RawUTF8;
fName: RawUTF8;
...
TSQLModel
Define your data model
function CreateSampleModel: TSQLModel;
begin
result := TSQLModel.Create([TSQLSampleRecord...
Database: TSQLRest
CRUD Operations
procedure TForm1.FindButtonClick(Sender: TObject);
var Rec: TSQLSampleRecord;
begin
Rec...
Database: TSQLRest
CRUD Operations
procedure TForm1.AddButtonClick(Sender: TObject);
var Rec: TSQLSampleRecord;
begin
Rec ...
TSQLRestServer
var Model: TSQLModel;
Database: TSQLRestServerDB;
HTTPServer: TSQLHttpServer;
…
Model := CreateSampleModel;...
TSQLRestClient
var Model: TSQLModel;
Database: TSQLRest;
…
Model := CreateSampleModel;
Database := TSQLHttpClient.Create(S...
Sample 04
Sample 04
http://localhost:8080/root
http://localhost:8080/root/samplerecord
disable authentication…
http://localhost:8080...
SynFile
TSQLRestServer
External SQL
var Model: TSQLModel;
Props: TSQLDBConnectionProperties;
Database: TSQLRestServerDB;
HTTPServe...
Sample 28
TSQLRecord
Mapping by Convention
TSQLRecordPeopleExt = class(TSQLRecord)
..
published
property FirstName: RawUTF8 index 40...
TSQLRecord
Mapping by configuration
Model := TSQLModel.Create([TSQLRecordPeopleExt],'root');
VirtualTableExternalRegister(...
TSQLRecord
Mapping by configuration
Model := TSQLModel.Create([TSQLRecordPeopleExt],'root');
VirtualTableExternalRegister(...
TSQLRecord Change Tracking
Objects Time Machine
Database.TrackChanges([TSQLInvoice]);
TSQLRecord Change Tracking
Objects Time Machine
Database.TrackChanges([TSQLInvoice]);
aInvoice := TSQLInvoice.Create;
aHis...
BATCH
Send all modifications at once
“Unit of Work” pattern
Array Binding or Multiple INSERT
Huge performance boost
Sample 15
SOA
Interface-based services
Design by contract
Factories
Instances live mode
REST UTF-8 JSON Security
Thread safety
SOA
Define the contract
type
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
/// add two si...
SOA
Implement the contract
type
TServiceCalculator = class(TInterfacedObject, ICalculator)
public
function Add(n1,n2: inte...
SOA
Publish the contract on the Server Side
RestServer.ServiceRegister(
TServiceCalculator,[TypeInfo(ICalculator)],sicShar...
SOA
Use the service
var I: ICalculator;
begin
I := Rest.Services<ICalculator>;
if I<>nil then
result := I.Add(10,20);
end;...
Sample 14
Real Time Features
Real Time Notifications
Via WebSockets
Real Time Features
Real Time Notifications
Via WebSockets
Data Replication
Master / Slave
Event-Driven
Asynchronous callba...
Data Replication
On Demand Master / Slave
Master
Slave
MasterServer
(MasterModel)
master.db3
MasterClient
(MasterModel)
HT...
Data Replication
Real Time Master / Slave
Master
Slave
MasterServer
(MasterModel)
master.db3
MasterClient
(MasterModel)
We...
Data Replication
Multi Offices Synch
Main Office
Office A Office B
Main
Server
External DB
Local
Server A
HTTP
Local
Serve...
Data Replication
Multi Offices Synch
Main Office
Office A Office B
Main
Server
Local Data A
Reference
Read Only
Local Data...
Real Time Features
Event-Driven
Asynchronous callbacks
Interface-based services callbacks
Bi-directional connection via We...
Event-Driven
Asynchronous callbacks
Interface-based services callbacks
ILongWorkCallback = interface(IInvokable)
['{425BF1...
Event-Driven
Asynchronous callbacks
Interface-based services callbacks
Publisher
Subscriber 1
Event
Subscriber 2
Event
Sub...
Sample 31
MVC/MVVM
Auto Generated UI
Dynamic Web Sites
Web Apps
Classic MVC
Web Apps
Model
View
Controller
ORM
Mustache
IMVCApplication
Classic MVC
Web Apps
Model
View
Controller
MVCModel.pas
*.html
MVCViewModel.pas
Blog MVC Sample
Web Apps
Implement a Controller
method name → page name
var const params → URI params
var out params → Mustache context
Web Apps
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Article...
Web Apps
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Article...
Web Apps
/blog/AuthorView?ID=123
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articl...
Web Apps
Mustache Data Context
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles...
Sample 30
Web Apps
Sample 30
http://localhost:8092/blog/default
http://localhost:8092/blog/mvc-info
http://localhost:8092/blog/artic...
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
Server
Delphi
Win32 Win64
10.2 10.1 XE8 XE7 XE6 XE5 XE4 XE3
XE2 XE 2010 2009 2007 2005 7 6
FPC
Win32 Linux-x86 Linux-ARM
3...
Clients
Delphi
Win32 Win64 OSX Android iOS
10.2 10.1 XE8 XE7 XE6 XE5 XE4 XE3
XE2 XE 2010 2009 2007 2005 7 6 5
FPC
All plat...
Clients
Smart Mobile Studio 2.2
HTML5
Mobile / PhoneGap
any REST JSON Client
AJAX C# Java Python…
Sample 27
Sample 27
Project14ServerHttpWrapper
http://localhost:888/root/wrapper/
+ SMS Project14Client
RegressionTests + LogView se...
mORMot & Friends
Open Source
Architecture & Design
Cross-Cutting features
DB Layer
ORM/ODM/SOA/MVC
Cross platform
Q&A
2016 mORMot
Upcoming SlideShare
Loading in …5
×

2016 mORMot

819 views

Published on

Some slides, as presented during EKON20 conferences, about the mORMot Open Source project, a Delphi/FPC professional framework featuring highly integrated SOA, MVC, ORM, SOLID over SQL and NoSQL databases.

Published in: Software
  • Be the first to comment

  • Be the first to like this

2016 mORMot

  1. 1. mORMot & Friends Arnaud Bouchez
  2. 2. Opinions Ahead
  3. 3. Great times for us
  4. 4. Great times for us Delphi is Hype Delphi + Pascal > Ruby If you say Delphi is dead, YOU are dead!
  5. 5. Two Languages In One Application Language like Java C# Ruby Python System Language like C C++
  6. 6. Dual Memory Management Automatic Memory Management COW and refcount Manual Memory Management Uses much less CPU/RAM Server stability
  7. 7. Dual Memory Management Automatic Memory Management COW and refcount Manual Memory Management Uses much less CPU/RAM Server stability ARC
  8. 8. New opportunities New platforms New compilers Great communities Third parties Open Source
  9. 9. Unleash your power Decades of experience Business knowledge Productive tools
  10. 10. Unleash your power Decades of experience Business knowledge Productive tools Innovative concepts
  11. 11. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  12. 12. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  13. 13. Open Source Started in 2008 5769 checkins since 2010 77 COCOMO years
  14. 14. Open Source Started in 2008 6215 checkins since 2010 86 COCOMO years ($ 4,746,754) http://synopse.info/fossil http://github.com/synopse/mORMot http://openhub.net/p/mormot
  15. 15. LOC Code 324,415 Comments 75,913 Blanks 34,197 Total 434,525 http://synopse.info/fossil http://github.com/synopse/mORMot http://openhub.net/p/mormot
  16. 16. Doc as Specs Exhaustive Maintained Open Source http://synopse.info/files/html 2100 pages of pdf SynProject powered
  17. 17. Test Driven 27,019,014 tests Write the test Fail the test Write the implementation Pass the test
  18. 18. Test Driven 27,019,014 tests Regression Performance Thread safety Cross platform – Cross compiler
  19. 19. Test Driven 27,019,014
  20. 20. http://synopse.info/forum Feedback and support Topics 3,603 Posts 22,112 Registered users 1,662
  21. 21. Hall of fame Alexander (sha) Alexander (volax) AlexPirate Alfred Glaenzer (alf) Arnaud Bouchez Aweste Bas Schouten BigStar Cheemeng CoMPi Damien (ddemars) Daniel Kuettner David Mead (MDW) Delphinium (louisyeow) DigDiver EgorovAlex Emanuele (lele9) Eric Grange Esmond Esteban Martin (EMartin) EvaF Goran Despalatovic (gigo) Joe (jokusoft) Jordi Tudela Leon Oosthuizen Maciej Izak (hnb) Mario Moretti Marius Maximus (mariuszekpl) Martin Suer Mazinsw MChaos Miab3 Michael (EgonHugeist) MilesYou Mingda Ondrej (reddwarf) Pavel (mpv) Pierre le Riche RalfS Richard6688 Sabbiolina Sanyin Sinisa (sinisav) Sllimr7139 Stefan (itSDS) Vadim Orel Win2014 Wloochacz Wolfgang Ehrhardt Zed
  22. 22. Hall of fame Alexander (sha) Alexander (volax) AlexPirate Alfred Glaenzer (alf) Arnaud Bouchez Aweste Bas Schouten BigStar Cheemeng CoMPi Damien (ddemars) Daniel Kuettner David Mead (MDW) Delphinium (louisyeow) DigDiver EgorovAlex Emanuele (lele9) Eric Grange Esmond Esteban Martin (EMartin) EvaF Goran Despalatovic (gigo) Joe (jokusoft) Jordi Tudela Leon Oosthuizen Maciej Izak (hnb) Mario Moretti Marius Maximus (mariuszekpl) Martin Suer Mazinsw MChaos Miab3 Michael (EgonHugeist) MilesYou Mingda Ondrej (reddwarf) Pavel (mpv) Pierre le Riche RalfS Richard6688 Sabbiolina Sanyin Sinisa (sinisav) Sllimr7139 Stefan (itSDS) Vadim Orel Win2014 Wloochacz Wolfgang Ehrhardt Zed … YOUR NAME ?
  23. 23. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  24. 24. Architecture Switch BBM → Clean nTier → SOA SOAP → REST RAD → MVC/MVVM SQL → ORM NoSQL → ODM OOP → SOLID
  25. 25. Architecture Switch ### → ### … see corresponding set of Slides
  26. 26. Design with Interfaces What, not how A type that comprises abstract virtual methods Rely on abstraction rather than implementation
  27. 27. Design with Interfaces Abstraction is your health Publish classes as services Test, mock Write SOLID code
  28. 28. Design with Interfaces Abstraction is your health Publish classes as services Test, mock Write SOLID code and manage memory for you
  29. 29. Design with Interfaces Abstraction is your health Publish classes as services Test, mock Write SOLID code and manage memory for you unless zeroing weak pointers
  30. 30. SOLID Principles Single responsibility Open/closed Liskov substitution Interface segregation Dependency inversion .. unleash interfaces!
  31. 31. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  32. 32. Cross Cutting Features UTF-8 JSON TDynArray TDocVariant Logging Testing Compression Crypto ECC PDF Mustache SpiderMonkey Uncoupled features: could be used without the ORM/SOA/MVC framework
  33. 33. SynCommons UTF-8 JSON From the ground up With objects, records, dynamic arrays, variants, any value Performance and integration
  34. 34. SynCommons TDynArray Wrapper to an existing dynamic array TList<> on steroids e.g. sorting, search, binary or JSON serialization using enhanced RTTI if available
  35. 35. SynCommons TDynArray In conjunction with records and variants: value objects data transfer objects (DTO)
  36. 36. SynCommons TDocVariant Stores documents objects, arrays, variants with low overhead natively JSON with late-binding support
  37. 37. SynCommons TDocVariant var V: variant; // stored as any variant ... TDocVariant.New(V); // or slightly slower V := TDocVariant.New; V.name := 'John'; // property accessed via late-binding V.year := 1972; // now V contains {"name":"john","year":1972}
  38. 38. SynCommons TDocVariant V.name := 'Mark'; // overwrite a property value writeln(V.name); // will write 'Mark' V.age := 12; // add a property to the object writeln(V.age); // will write '12' writeln(V); // implicit conversion to JSON string // i.e. '{"name":"Mark","age":12}' writeln(VariantSaveJSON(V1)); // as RawUTF8
  39. 39. SynCommons TDocVariant + mORMot.pas TSQLRecordData = class(TSQLRecord) private fName: RawUTF8; fData: variant; public published property Name: RawUTF8 read fTest write fTest stored AS_UNIQUE; property Data: variant read fData write fData; end;
  40. 40. TDocVariant + mORMot.pas property Data: variant read fData write fData; We store a TDocVariant in Data to mutate a SQL database into a NoSQL engine
  41. 41. TDocVariant + mORMot.pas property Data: variant read fData write fData; We store a TDocVariant in Data to mutate a SQL database into a NoSQL engine
  42. 42. TDocVariant + mORMot.pas var aRec: TSQLRecordData; aID: integer; begin // initialization of one record aRec := TSQLRecordData.Create; aRec.Name := 'Joe’; // create a TDocVariant aRec.data := _JSONFast('{name:"Joe",age:30}'); // or we can use this overloaded constructor aRec := TSQLRecordData.Create( ['Joe',_ObjFast(['name','Joe','age',30])]);
  43. 43. TDocVariant + mORMot.pas // now we can play with the data, e.g. via late-binding: writeln(aRec.Name); // will write 'Joe' writeln(aRec.Data); // write '{"name":"Joe","age":30} // one year older aRec.Data.age := aRec.Data.age+1; // add a property to the schema aRec.Data.interests := 'football'; aID := aClient.Add(aRec); // we stored {"name":"Joe","age":31,"interests":"footbal"} aRec.Free; // now we can retrieve the data e.g. via aID end;
  44. 44. TDocVariant + mORMot.pas property Data: variant read fData write fData; Data will be stored as TEXT in the underlying RDBMS
  45. 45. TDocVariant + mORMot.pas property Data: variant read fData write fData; Data will be stored as TEXT in the underlying RDBMS Of course, if the database is a MongoDB engine, the data will be stored as a true BSON document
  46. 46. SynCommons Logging Low overhead Local or remote Fast viewer tool Exception catch, stack trace Used by the whole framework
  47. 47. SynCommons Testing Light and cross-platform Convention over configuration Stubs and mocks
  48. 48. Compression SynZip faster unzip SynLZO SynLZ speed symmetric
  49. 49. SynCrtSock Cross-platform Network library Socket WinHTTP WinINet clients Optimized HTTP server IOCP driven http.sys kernel-mode WebSockets
  50. 50. SynCrypto SHA 1 – 256 MD5 – RC4 AES 128 – 192 – 256 ECB – CBC – OFB – CTR HMAC - PBKDF2 PRNG Pascal and/or optimized asm (AES-NI, SSE42)
  51. 51. SynECC Certificate-based public-key cryptography using cutting edge ECC-secp256r1 For data signature, content encryption and safe transmission
  52. 52. SynPDF From TCanvas to PDF Unicode Font embedding Encryption
  53. 53. SynPDF From TCanvas to PDF Unicode Font embedding Encryption Code-based report engine
  54. 54. SynMustache Mustache template system Data context as TDocVariant UTF-8 JSON With extensions
  55. 55. SynMustache Data Context { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": true }
  56. 56. SynMustache Template <h1>{{header}}</h1> {{#items}} {{#first}} <li><strong>{{name}}</strong></li> {{/first}} {{#link}} <li><a href="{{url}}">{{name}}</a></li> {{/link}} {{/items}} {{#empty}} <p>The list is empty.</p> {{/empty}}
  57. 57. SynMustache Result <h1>Colors</h1> <li><strong>red</strong></li> <li><a href="#Green">green</a></li> <li><a href="#Blue">blue</a></li> <p>The list is empty.</p>
  58. 58. SynMustache Data Context { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": true }
  59. 59. SynMustache Template <h1>{{header}}</h1> {{#items}} {{#first}} <li><strong>{{name}}</strong></li> {{/first}} {{#link}} <li><a href="{{url}}">{{name}}</a></li> {{/link}} {{/items}} {{#empty}} <p>The list is empty.</p> {{/empty}}
  60. 60. SynMustache Result <h1>Colors</h1> <li><strong>red</strong></li> <li><a href="#Green">green</a></li> <li><a href="#Blue">blue</a></li> <p>The list is empty.</p>
  61. 61. SynMustache Data Context { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": true }
  62. 62. SynMustache Template <h1>{{header}}</h1> {{#items}} {{#first}} <li><strong>{{name}}</strong></li> {{/first}} {{#link}} <li><a href="{{url}}">{{name}}</a></li> {{/link}} {{/items}} {{#empty}} <p>The list is empty.</p> {{/empty}}
  63. 63. SynMustache Result <h1>Colors</h1> <li><strong>red</strong></li> <li><a href="#Green">green</a></li> <li><a href="#Blue">blue</a></li> <p>The list is empty.</p>
  64. 64. SynMustache Data Context { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": true }
  65. 65. SynMustache Template <h1>{{header}}</h1> {{#items}} {{#first}} <li><strong>{{name}}</strong></li> {{/first}} {{#link}} <li><a href="{{url}}">{{name}}</a></li> {{/link}} {{/items}} {{#empty}} <p>The list is empty.</p> {{/empty}}
  66. 66. SynMustache Result <h1>Colors</h1> <li><strong>red</strong></li> <li><a href="#Green">green</a></li> <li><a href="#Blue">blue</a></li> <p>The list is empty.</p>
  67. 67. SynSM/SyNode Latest Spidermonkey Javascript JIT engine Call JS from Delphi TSMVariant for late binding
  68. 68. SynSM/SyNode Latest Spidermonkey Javascript JIT engine Call JS from Delphi TSMVariant for late binding SynSM + mORMot = multi-threaded node.js
  69. 69. Sample 23
  70. 70. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  71. 71. DB Layer SynMongoDB NoSQL SynDB SQL Uncoupled features: could be used without the ORM/SOA/MVC framework
  72. 72. SynMongoDB MongoDB native access BSON types - TBSONVariant TDocVariant Extended JSON
  73. 73. Sample 24
  74. 74. SynDB Direct RDBMS access layer Not linked to DB.pas Multi providers UTF-8 JSON Interface based Knows SQL dialects SynDBExplorer
  75. 75. SynDB Not linked to DB.pas Enter the 21th century Less data types By-pass slow TDataSet Unicode even before Delphi 2009 Array binding Native JSON support Remote access
  76. 76. SynDB Providers
  77. 77. SynDB Connect to a DB var Props: TSQLDBConnectionProperties; ... Props := TOleDBMSSQLConnectionProperties.Create( '.SQLEXPRESS','AdventureWorks2008R2','',''); try UseProps(Props); finally Props.Free; end;
  78. 78. SynDB Execute statements procedure UseProps(Props: TSQLDBConnectionProperties); var I: ISQLDBRows; begin I := Props.Execute( 'select * from Sales.Customer '+ 'where AccountNumber like ?',['AW000001%']); while I.Step do assert(Copy(I['AccountNumber'],1,8)='AW000001'); end;
  79. 79. SynDB Late-binding procedure UseProps(Props: TSQLDBConnectionProperties); var Row: Variant; begin with Props.Execute( 'select * from Sales.Customer '+ 'where AccountNumber like ?‘,['AW000001%'],@Row) do while Step do assert(Copy(Row.AccountNumber,1,8)='AW000001'); end;
  80. 80. SynDB TQuery emulation Q := TQuery.Create(aSQLDBConnection); try Q.SQL.Clear; // optional Q.SQL.Add('select * from DOMAIN.TABLE'); Q.SQL.Add(' WHERE ID_DETAIL=:detail;'); Q.ParamByName('DETAIL').AsString := '1234'; Q.Open; Q.First; // optional while not Q.Eof do begin assert(Q.FieldByName('id_detail').AsString='1234'); Q.Next; end; Q.Close; // optional finally Q.Free; end;
  81. 81. SynDB Fast read/only TDataSet ds1.DataSet := ToDataSet(ds1, aProps.Execute('select * from people',[])); Read/write TClientDataSet ds1.DataSet := ToClientDataSet(ds1, aProps.Execute('select * from people',[]));
  82. 82. SynDB Remote access via HTTP
  83. 83. SynDB Remote access via HTTP http.sys based server SynLZ compression Digital signature Authentication
  84. 84. SynDB Remote access via HTTP Mutate SQLite3 into a high performance Client-Server RDBMS No library to deploy on Client side Easy remote hosting on Server side
  85. 85. SynDB Remote access via HTTP Mutate SQLite3 into a high performance Client-Server RDBMS No library to deploy on Client side Easy remote hosting on Server side
  86. 86. SynDBExplorer Manage and request your DBs Any supported database High performance grid Export to CSV or SQLite3 SQLite3 integrated Remote server or client
  87. 87. SynDBExplorer
  88. 88. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  89. 89. ORM/ODM/SOA/MVC
  90. 90. ORM/ODM/SOA/MVC RESTful ORM/ODM SOA Real Time MVC
  91. 91. RESTful ORM Not an ORM with a transmission layer But a RESTful ORM from the ground up
  92. 92. TSQLRest RESTful access Convention over configuration CRUD methods - Cache Authentication – Authorization Services On Client or Server side
  93. 93. TSQLRest
  94. 94. TSQLRest
  95. 95. TSQLRest
  96. 96. TSQLRest
  97. 97. TSQLRestServer Server Storage In-memory SQLite3 local External SQL External NoSQL Redirected
  98. 98. TSQLRestServer
  99. 99. TSQLRestServer Per table redirection
  100. 100. TSQLRestClient Client Access In process Library HTTP Named pipes Windows messages
  101. 101. TSQLRest Cache
  102. 102. TSQLRecord Convention over configuration TSQLSampleRecord = class(TSQLRecord) private fQuestion: string; fName: string; fTime: TModTime; published property Time: TModTime read fTime write fTime; property Name: string read fName write fName; property Question: string read fQuestion write fQuestion; end;
  103. 103. TSQLRecord Convention over configuration TSQLSampleRecord = class(TSQLRecord) private fQuestion: RawUTF8; fName: RawUTF8; fTime: TModTime; published property Time: TModTime read fTime write fTime; property Name: RawUTF8 read fName write fName; property Question: RawUTF8 read fQuestion write fQuestion; end;
  104. 104. TSQLModel Define your data model function CreateSampleModel: TSQLModel; begin result := TSQLModel.Create([TSQLSampleRecord]); end; Shared on both Client and Server side
  105. 105. Database: TSQLRest CRUD Operations procedure TForm1.FindButtonClick(Sender: TObject); var Rec: TSQLSampleRecord; begin Rec := TSQLSampleRecord.Create( Database,'Name=?',[StringToUTF8(NameEdit.Text)]); try if Rec.ID=0 then QuestionMemo.Text := 'Not found' else QuestionMemo.Text := UTF8ToString(Rec.Question); finally Rec.Free; end; end;
  106. 106. Database: TSQLRest CRUD Operations procedure TForm1.AddButtonClick(Sender: TObject); var Rec: TSQLSampleRecord; begin Rec := TSQLSampleRecord.Create; try Rec.Name := StringToUTF8(NameEdit.Text); Rec.Question := StringToUTF8(QuestionMemo.Text); if Database.Add(Rec,true)=0 then ShowMessage('Error adding the data') else begin NameEdit.Text := ''; QuestionMemo.Text := ''; NameEdit.SetFocus; end; finally Rec.Free; end; end;
  107. 107. TSQLRestServer var Model: TSQLModel; Database: TSQLRestServerDB; HTTPServer: TSQLHttpServer; … Model := CreateSampleModel; Database := TSQLRestServerDB.Create(Model,'data.db3'); Database.CreateMissingTables; HTTPServer := TSQLHttpServer.Create('8080',[Database]); HTTPServer.AccessControlAllowOrigin := '*';
  108. 108. TSQLRestClient var Model: TSQLModel; Database: TSQLRest; … Model := CreateSampleModel; Database := TSQLHttpClient.Create(ServerIP,'8080',Model);
  109. 109. Sample 04
  110. 110. Sample 04 http://localhost:8080/root http://localhost:8080/root/samplerecord disable authentication… http://localhost:8080/root/samplerecord http://localhost:8080/root/samplerecord/1
  111. 111. SynFile
  112. 112. TSQLRestServer External SQL var Model: TSQLModel; Props: TSQLDBConnectionProperties; Database: TSQLRestServerDB; HTTPServer: TSQLHttpServer; … Model := CreateSampleModel; Props := TODBCConnectionProperties.Create('', 'Driver=PostgreSQL Unicode';…','',''); VirtualTableExternalRegisterAll(Model,Props); Database := TSQLRestServerDB.Create(Model,':memory:'); Database.CreateMissingTables; HTTPServer := TSQLHttpServer.Create('8080',[Database]); HTTPServer.AccessControlAllowOrigin := '*';
  113. 113. Sample 28
  114. 114. TSQLRecord Mapping by Convention TSQLRecordPeopleExt = class(TSQLRecord) .. published property FirstName: RawUTF8 index 40 property LastName: RawUTF8 index 40 property Data: TSQLRawBlob property YearOfBirth: integer property YearOfDeath: word property LastChange: TModTime property CreatedAt: TCreateTime end;
  115. 115. TSQLRecord Mapping by configuration Model := TSQLModel.Create([TSQLRecordPeopleExt],'root'); VirtualTableExternalRegister( Model,TSQLRecordPeopleExt,Props,'Test.People');
  116. 116. TSQLRecord Mapping by configuration Model := TSQLModel.Create([TSQLRecordPeopleExt],'root'); VirtualTableExternalRegister( Model,TSQLRecordPeopleExt,Props,'Test.People'); Model.Props[TSQLRecordPeopleExt].ExternalDB. MapField('ID','Key'). MapField('YearOfDeath','YOD');
  117. 117. TSQLRecord Change Tracking Objects Time Machine Database.TrackChanges([TSQLInvoice]);
  118. 118. TSQLRecord Change Tracking Objects Time Machine Database.TrackChanges([TSQLInvoice]); aInvoice := TSQLInvoice.Create; aHist := TSQLRecordHistory.CreateHistory( aClient,TSQLInvoice,400); try writeln('History Count: ',aHist.HistoryCount); for i := 0 to aHist.HistoryCount-1 do begin aHist.HistoryGet(i,aEvent,aTimeStamp,aInvoice); writeln; writeln('Event: ',ord(aEvent))^); writeln('TimeStamp: ',TTimeLogBits(aTimeStamp).ToText); writeln('Identifier: ',aInvoice.Number); end;
  119. 119. BATCH Send all modifications at once “Unit of Work” pattern Array Binding or Multiple INSERT Huge performance boost
  120. 120. Sample 15
  121. 121. SOA Interface-based services Design by contract Factories Instances live mode REST UTF-8 JSON Security Thread safety
  122. 122. SOA Define the contract type ICalculator = interface(IInvokable) ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}'] /// add two signed 32 bit integers function Add(n1,n2: integer): integer; end;
  123. 123. SOA Implement the contract type TServiceCalculator = class(TInterfacedObject, ICalculator) public function Add(n1,n2: integer): integer; end; function TServiceCalculator.Add(n1, n2: integer): integer; begin result := n1+n2; end;
  124. 124. SOA Publish the contract on the Server Side RestServer.ServiceRegister( TServiceCalculator,[TypeInfo(ICalculator)],sicShared); Define the contract on the Client Side RestServer.ServiceRegister( [TypeInfo(ICalculator)],sicShared);
  125. 125. SOA Use the service var I: ICalculator; begin I := Rest.Services<ICalculator>; if I<>nil then result := I.Add(10,20); end; var I: ICalculator; // for older versions of Delphi begin if Rest.Services['Calculator'].Get(I) then result := I.Add(10,20); end; On both client and server sides
  126. 126. Sample 14
  127. 127. Real Time Features Real Time Notifications Via WebSockets
  128. 128. Real Time Features Real Time Notifications Via WebSockets Data Replication Master / Slave Event-Driven Asynchronous callbacks
  129. 129. Data Replication On Demand Master / Slave Master Slave MasterServer (MasterModel) master.db3 MasterClient (MasterModel) HTTP SlaveServer (SlaveModel) On Demand Replication slave.db3
  130. 130. Data Replication Real Time Master / Slave Master Slave MasterServer (MasterModel) master.db3 MasterClient (MasterModel) WebSockets TCP/IP SlaveServer (SlaveModel) Replication slave.db3
  131. 131. Data Replication Multi Offices Synch Main Office Office A Office B Main Server External DB Local Server A HTTP Local Server B HTTP Client 1 Client 2 Client 3 local network Client 1 Client 2 Client 3 Client 4 local network
  132. 132. Data Replication Multi Offices Synch Main Office Office A Office B Main Server Local Data A Reference Read Only Local Data B Reference Read Only Local Data A Business Read/Write Replication Local Data B Business Read Only Local Data A Business Read Only Replication Local Data B Business Read/Write
  133. 133. Real Time Features Event-Driven Asynchronous callbacks Interface-based services callbacks Bi-directional connection via WebSockets using application-level protocols Security, frame gathering, REST emulation
  134. 134. Event-Driven Asynchronous callbacks Interface-based services callbacks ILongWorkCallback = interface(IInvokable) ['{425BF199-19C7-4B2B-B1A4-A5BE7A9A4748}'] procedure WorkFinished(const workName: string; timeTaken: integer); procedure WorkFailed(const workName, error: string); end; ILongWorkService = interface(IInvokable) ['{09FDFCEF-86E5-4077-80D8-661801A9224A}'] procedure StartWork(const workName: string; const onFinish: ILongWorkCallback); function TotalWorkCount: Integer; end;
  135. 135. Event-Driven Asynchronous callbacks Interface-based services callbacks Publisher Subscriber 1 Event Subscriber 2 Event Subscriber 3
  136. 136. Sample 31
  137. 137. MVC/MVVM Auto Generated UI Dynamic Web Sites
  138. 138. Web Apps Classic MVC
  139. 139. Web Apps Model View Controller ORM Mustache IMVCApplication Classic MVC
  140. 140. Web Apps Model View Controller MVCModel.pas *.html MVCViewModel.pas Blog MVC Sample
  141. 141. Web Apps Implement a Controller method name → page name var const params → URI params var out params → Mustache context
  142. 142. Web Apps Implement a Controller procedure TBlogApplication.AuthorView(var ID: integer; out Author: TSQLAuthor; out Articles: variant); begin RestModel.Retrieve(ID,Author); Author.HashedPassword := ''; // no need to publish it if Author.ID<>0 then Articles := RestModel.RetrieveDocVariantArray( TSQLArticle,'','Author=? order by RowId desc limit 50',[ID],ARTICLE_FIELDS) else raise EMVCApplication.CreateGotoError(HTML_NOTFOUND); End; → /blog/AuthorView?....
  143. 143. Web Apps Implement a Controller procedure TBlogApplication.AuthorView(var ID: integer; out Author: TSQLAuthor; out Articles: variant); http://localhost:8092/blog/mvc-info → /blog/AuthorView?ID=..[integer].. {{Main}}: variant {{ID}}: integer {{Author}}: TSQLAuthor {{Articles}}: variant
  144. 144. Web Apps /blog/AuthorView?ID=123 procedure TBlogApplication.AuthorView(var ID: integer; out Author: TSQLAuthor; out Articles: variant); begin → ID = 123 RestModel.Retrieve(ID,Author); Author.HashedPassword := ''; // no need to publish it if Author.ID<>0 then Articles := RestModel.RetrieveDocVariantArray( TSQLArticle,'','Author=? order by RowId desc limit 50',[ID],ARTICLE_FIELDS) else raise EMVCApplication.CreateGotoError(HTML_NOTFOUND); end;
  145. 145. Web Apps Mustache Data Context procedure TBlogApplication.AuthorView(var ID: integer; out Author: TSQLAuthor; out Articles: variant); begin RestModel.Retrieve(ID,Author); Author.HashedPassword := ''; // no need to publish it if Author.ID<>0 then Articles := RestModel.RetrieveDocVariantArray( TSQLArticle,'','Author=? order by RowId desc limit 50',[ID],ARTICLE_FIELDS) else raise EMVCApplication.CreateGotoError(HTML_NOTFOUND); end; {{ID}} {{Author}} {{Articles}}
  146. 146. Sample 30
  147. 147. Web Apps Sample 30 http://localhost:8092/blog/default http://localhost:8092/blog/mvc-info http://localhost:8092/blog/articleView?id=99 http://localhost:8092/blog/articleView/json?id=99 http://localhost:8092/blog/authorView?id=1
  148. 148. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A
  149. 149. Server Delphi Win32 Win64 10.2 10.1 XE8 XE7 XE6 XE5 XE4 XE3 XE2 XE 2010 2009 2007 2005 7 6 FPC Win32 Linux-x86 Linux-ARM 3.0.x + 3.1.x (trunk)
  150. 150. Clients Delphi Win32 Win64 OSX Android iOS 10.2 10.1 XE8 XE7 XE6 XE5 XE4 XE3 XE2 XE 2010 2009 2007 2005 7 6 5 FPC All platforms 2.6.x 3.x.x
  151. 151. Clients Smart Mobile Studio 2.2 HTML5 Mobile / PhoneGap any REST JSON Client AJAX C# Java Python…
  152. 152. Sample 27
  153. 153. Sample 27 Project14ServerHttpWrapper http://localhost:888/root/wrapper/ + SMS Project14Client RegressionTests + LogView server RegressionTestsServer + SMS Sample 29
  154. 154. mORMot & Friends Open Source Architecture & Design Cross-Cutting features DB Layer ORM/ODM/SOA/MVC Cross platform Q&A

×