|
Registriert seit: 8. Jan 2007 479 Beiträge |
#1
Inspiriert durch diese Frage im Forum, möchte ich die Gelegenheit nutzen, einige mORMot Funktionen an einem Beispiel zu demonstrieren. Ziel ist es, so viel Funktionalität wie möglich mit nur wenigen Zeilen Quelltext zu präsentieren. Es geht hier um Konzepte, nicht um eine fertige Copy-Paste Lösung. Die enthaltenen Verweise zur Dokumentation verlinken zur aktuell verfügbaren
![]() Im Anhang befindet sich der Sourcecode und das ausführbare Programm. Disclaimer: Der Sourcecode ist weder getestet noch optimiert. Er sollte mit Delphi ab Version 10.2 funktionieren. Die Benutzung der zur Verfügung gestellten Materialien erfolgt auf eigene Gefahr. Die erstellte Klasse TImageResourceDB verwaltet Bilder und verwendet als Datengrab eine SQLite Datenbank. Das Interface ist sehr einfach gehalten und umfasst nur wenige Funktionen:
Delphi-Quellcode:
Nichts Besonderes, mag man meinen. Mit den wenigen Zeile bekommt man:
TImageResourceDB = class(TObject)
private FRestServer: TRestServerDB; function CreateModel: TOrmModel; protected function LoadData(pmStream: TStream; const pmcRowID: TID): Boolean; function SaveData(const pmcImageData: RawBlob; const pmcTitle, pmcComment: String; const pmcMetaData: Variant; var pmvRowID: TID): Boolean; public constructor Create(const pmcFileName: TFileName; const pmcPassword: RawUtf8 = ''); destructor Destroy; override; class function InitDefaultMetaData(const pmcCreator, pmcLocation: RawUtf8; pmLatitude, pmLongitude: Double; pmDate: TDate; pmTime: TTime): Variant; function LoadImage(pmImage: TImage; const pmcRowID: TID): Boolean; overload; function LoadImage(pmImage: TImage; const pmcSearchPhrase: String; pmResultIDs: PIDDynArray = Nil): Boolean; overload; function LoadImage(pmImage: TImage; const pmcMetaFieldName: String; const pmcMetaFieldValue: Variant; pmResultIDs: PIDDynArray = Nil): Boolean; overload; function SaveImage(pmImage: TImage; const pmcTitle, pmcComment: String; const pmcMetaData: Variant; pmRowID: PID = Nil): Boolean; overload; function SaveImage(pmStream: TStream; const pmcTitle, pmcComment: String; const pmcMetaData: Variant; pmRowID: PID = Nil): Boolean; overload; end;
Beschleunigung beim Speichern und Lesen von Bildern Um den letzten Punkt gleich abzuhandeln, hierzu ein paar Benchmark-Wert aus der Anwendung ermittelt mit einem 2MB großen PNG-Bild:
Embedded SQLite Datenbank Um eine SQLite Datenbank statisch ins Programm einzubinden, muss nur die Unit mormot.db.raw.sqlite3.static hinzugefügt werden. Danach kann der Zugriff auf die SQLite3 Engine low-level, oder besser über eine TRest* Klasse erfolgen. Über Connection Klassen lassen sich auch andere Datenbanken anbinden. Es gibt Connections für die Frameworks ZEOS, FireDac/AnyDac, UniDac, ODBC, OleDB API und direkte Anbindungen für SQLite, PostgreSQL, Oracle OCI und MongoDB. Die Anbindung erfolgt über die schnellst mögliche Variante. Zum Beispiel verwendet ZEOS direkt ZDBC, anstatt über die Delphi DB Klassen zu gehen. Daraus ergibt sich eine deutliche Beschleunigung. ORM initialisieren Alle Klassen für das ORM müssen Nachfahre(n) der Klasse TOrm sein. Der Tabellenname in der Datenbank ergibt sich aus dem Klassennamen. Alle öffentlichen (published) Eigenschaften einer ORM Klasse werden als Feld in der Datenbank repräsentiert. Zusätzlich wird das Feld ID/RowID angelegt. Welche Feld-Typen möglich sind, ist in der ![]() ![]()
Delphi-Quellcode:
Anmerkung: smFull ist mit Abstand der langsamste Modus, aber gewährleistet ein 100%iges ACID-Verhalten. In der Praxis ist smNormal ein guter Kompromiss aus Sicherheit und Geschwindigkeit. Im Beispiel besteht kein Grund für eine Authentifizierung, daher wird die automatische Erstellung der hierfür notwendigen Tabellen unterdrückt.
type
TOrmFile = class(TOrm) ... published property Title: RawUTF8 read FTitle write FTitle; property Comment: RawUtf8 read FComment write FComment; property MetaData: Variant read FMetaData write FMetaData; ... end; ... FRestServer := TRestServerDB.Create(TOrmModel.Create([TOrmFile, ...]), DBFileName, False, DBPassword); FRestServer.Model.Owner := FRestServer; FRestServer.DB.Synchronous := smFull; FRestServer.DB.LockingMode := lmExclusive; FRestServer.Server.CreateMissingTables(0, [itoNoAutoCreateGroups, itoNoAutoCreateUsers]); Aufgaben über das ORM erledigen Eine Übersicht aller ORM Funktionen erhält man beim Blick in das IRestOrm Interface. Es steht eine Vielzahl von Möglichkeiten zur Auswahl. Die Anwendung ist sehr einfach. Das Hinzufügen eines Datensatzes geschieht wie folgt:
Delphi-Quellcode:
SQLite Volltextsuche
var
ormFile: TOrmFile; begin ormFile := TOrmFile.Create; try ormFile.Title := 'my first one'; ormFile.Comment := 'Arnaud is the best'; ... FRestServer.Server.Add(ormFile, True); finally ormFile.Free; end; Um die Volltextsuche zu aktivieren, erstellt man eine eigene ORM Klasse, die von einer in mORMot vorhanden, spezialisierten Basisklassen (TOrmFts5/TOrmFts5Porter/TOrmFts5Unicode61) abstammt. In dieser Klasse werden die Felder der Datenklasse, die zum Suchen vorgesehen sind, wiederholt. Die Suche ist eine einfache SQL Abfrage:
Delphi-Quellcode:
Anmerkung: Die Funktion FormatUtf8() ist der Delphi Format() Funktion ähnlich. Eine Zusatzfunktion ist, dass Argumente mit :(): umschlossen werden. Diese Markierung wird im ORM zur Optimierung verwendet.
var
sqlWhere: RawUtf8; searchIDs: TIDDynArray; begin sqlWhere := FormatUtf8('% MATCH ? ORDER BY rank DESC', ['SearchTable'], [SearchPhrase]); if FRestServer.Server.FTSMatch(TOrmFileSearch, sqlWhere, searchIDs) then Feld mit Meta-Daten Ein Eigenschaftsfeld der Klasse vom Typ DocVariant wird im ORM als JSON gespeichert. Ein DocVariant ist eine beliebig komplexe Datenstruktur aus Objekt(en) und/oder Arrays, oder aus Kombinationen von beiden. WOW. Die DocVariant Syntax sieht für Pascal Entwickler etwas gewöhnungsbedürftig aus, weil es eher an eine Scriptsprache erinnert. Mehr dazu in der ![]()
Delphi-Quellcode:
In SQLite ab Version 3.38.0 lässt sich das mit folgender SQL Syntax abfragen:
var
metaData: Variant; begin TDocVariant.New(metaData); metaData.Number := 10; metaData.Creator := 'Thomas'; metaData.Birthday := EncodeDate('Top Secret!');
Code:
Zusammenfassung
Schema: SELECT * FROM File WHERE MetaData->>'$.Creator'='Thomas' ORDER BY ...
mORMot ist gut dokumentiert. Die Hilfe umfasst mehr als 2500 Seiten. Davon enthalten die ersten ca. 650 Seiten einen sehr lesenswerten allgemeinen Teil, der Rest ist API Dokumentation. mORMot muss nicht in der IDE installierten werden! Es reicht aus, die entsprechenden Bibliothekspfade einzufügen. Bei neuen Anwendungen ist mORMot2 zu empfehlen. Hier der Link zum ![]() ![]() Bis bald... Thomas |
|||||||||
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |