AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Kleine Demo zu mORMot
Thema durchsuchen
Ansicht
Themen-Optionen

Kleine Demo zu mORMot

Ein Thema von Sir Rufo · begonnen am 5. Nov 2011 · letzter Beitrag vom 30. Apr 2013
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Kleine Demo zu mORMot

  Alt 5. Nov 2011, 11:34
Datenbank: SQLite • Version: 3 • Zugriff über: mORMot
So hier mal eine kleine Demo zu mORMot inkl. Source und Binaries (wer das nicht selber kompilieren will)
Screenshots spare ich mir mal, denn es geht nicht um die Bilder sondern das ORM

Der Kern des Ganzen besteht aus einem Model, welches die Daten-Objekte beinhaltet.
Aus diesen Datenobjekten werden dann automatisch die Tabellen erzeugt, bzw. erweitert.

In der Demo verwende ich folgendes Datenobjekt:
Delphi-Quellcode:
unit Model.Demo.Person;

interface

uses
  SynCommons, SQLite3Commons;

type
  TGeschlecht = ( gsMann, gsFrau );

  TSQLPerson = class( TSQLRecord )
  private
    fVorname : SynUnicode; // ist ein Unicode-String
    fNachname : SynUnicode; // ist ein Unicode-String
    fGeschlecht : TGeschlecht; // ja, Enums gehen auch
    function GetAnzeige : string;
  public
    property Anzeige : string read GetAnzeige;
  published
    property Vorname : SynUnicode read fVorname write fVorname;
    property Nachname : SynUnicode read fNachname write fNachname;
    property Geschlecht : TGeschlecht read fGeschlecht write fGeschlecht;
  end;

implementation

{ TSQLPerson }

function TSQLPerson.GetAnzeige : string;
begin
  Result := Nachname + ', ' + Vorname;
end;

end.
Aus den published Properties werden die Feldnamen der Tabelle gebildet.
Die Tabelle selber bekommt als Namen Person (also TSQL<TabellenName>).

Um aus den Daten-Objekten ein Model zu erstellen benutze ich eine eigene Unit, die mir alle Daten-Objekte sammelt und in einem Model zusammenstellt:
Delphi-Quellcode:
unit Model.Demo;

interface

uses
  SQLite3Commons;

function CreateModel : TSQLModel;

implementation

uses
  Model.Demo.Person;

function CreateModel : TSQLModel;
begin
  Result := TSQLModel.Create( [TSQLPerson], 'Demo' );
end;

end.
Ok, bis hier sollte das alles noch nachvollziehbar sein

Jetzt zum schwierigien Teil Client und Server.

In der Demo verwende ich einen Http-Server. Also brauchen wir eine VCL-Formular-Anwendung (oder meinetwegen auch eine Service-Anwendung) und setzen diesen Server einmal auf:
Delphi-Quellcode:
uses
  mORMot.Connector, mORMot.Connector.Server,
  Model.Demo;

...

fSrvCon := // eine Server-Instanz für
  TmORMotServerHttp.Create( // einen Http-Server
  TmORMotConfigurator.Create, // mit der Konfiguration
  CreateModel // und diesem Model
  );
ja, das war schon alles ...

Jetzt der passende Client:
Delphi-Quellcode:
uses
  mORMot.Connector, mORMot.Connector.Client,
  Model.Demo;

...

fCltCon := // eine Client-Instanz
  TmORMotClientHttp.Create( // für den Zugriff via Http
  TmORMotConfigurator.Create, // mit der Konfiguration
  CreateModel // und diesem Model
  );
Der TmORMotConfigurator kümmert sich um das Erzeugen aller benötigten Objekte.
Steuern kann man das Verhalten über eine Ini-Datei.
TmORMotConfigurator.Create('<Pfad zur Ini-Datei>'); Wird keine Ini-Datei angegeben, dann wird der Name der Ini-Datei aus dem Anwendungsnamen gebildet:
Code:
<MeinAnwendungsName>_mORMot.ini
Notwendig ist die nicht, da für alle Einstellungen sinnvolle Default-Werte hinterlegt sind.

Um z.B. den Port für den Http-Server einzustellen trägt man folgendes in die Ini-Dateien für Client und Server ein:
Code:
[Server]
;Port Default 8080
Port=8888
Ist der Server nicht auf dem lokalen Rechner, dann trägt man in der Client-Ini einfach den Hostnamen ein:
Code:
[Server]
;Host Default localhost
Host=<Adresse des Servers>
Die Konfiguration wird immer nur beim Erzeugen der Connectoren benutzt, somit ist ein Neustart von Server/Client erforderlich.

Vielleicht sollte man noch erwähnen dass der Server ein REST-Server ist und die Daten auch direkt via WebBrowser ausgelesen werden können.
Sind im Demo-Server schon Datensätze vorhanden, dann einfach mal diesen Link öffnen
http://localhost:8080/Demo/Person/1
(Wer den FireFox einsetzt sollte sich das AddOn JSONview installieren)

So das sollte für den ersten Test schon mal reichen
Angehängte Dateien
Dateityp: 7z mORMot_Demo_Source.7z (11,5 KB, 166x aufgerufen)
Dateityp: 7z mORMot_Demo_Bin.7z (1,65 MB, 152x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Kleine Demo zu mORMot

  Alt 6. Nov 2011, 10:06
In den Sourcen von mORMot ist ein kleiner Bug bzgl. des Lock/UnLock von Records.

In der unit SQLite3Commons; muss folgendes angepasst werden
Delphi-Quellcode:
function TSQLRestClientURI.Retrieve(aID: integer; Value: TSQLRecord;
      ForUpdate: boolean=false): boolean;
var Table: TSQLRecordClass;
    Resp: RawUTF8;
begin
  result := false;
  if (self=nil) or (aID<=0) or (Value=nil) then
    exit;
  Table := Value.RecordClass;
  if ForUpdate and not Model.Lock(Table,aID) then
    exit; // error marking as locked by the client
  with URIGet(Table,aID,Resp,ForUpdate) do
  if Lo=200 then begin
    Value.FillFrom(Resp);
    Value.fInternalState := Hi;
    if ForceBlobTransfert then
      result := RetrieveBlobFields(Value) else
      result := true;
  end
  else // dieser else-Zweig fehlt :o)
    Model.UnLock(Table,aID);
end;
Der Autor ist aber recht fix mit dem Bug-Fixing, somit sollte dieser Fehler kurzfristig in den Original-Quellen behoben sein.
Fehlermeldung im Synopse-Forum
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Kleine Demo zu mORMot

  Alt 6. Nov 2011, 19:10
Der Fehler ist nun auch im Repository behoben
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Kleine Demo zu mORMot

  Alt 6. Nov 2011, 23:03
Nabend Sir,

Danke für die Demo. Morgen werde ich wohl endlich Zeit dafür haben...

Hast Du Erfahrungen, wie die Perfomance mit großen Datenmengen ist (vor allem auch über Netzwerk und im Vergleich zu einer klassischen Datenbankanwendung)?

Ich hatte mal früher mit Firebird ein kleines (sehr billiges) Testprojekt erstellt, bei dem man 3 Panels verschieben konnte und diese Verschiebung auch parallel auf einem zweiten "Designer" erfolgte.
Das funktioniert auch im Netzwerk, wenn man nicht Firebird embedded nutzt.

Siehst Du mal eine Demomöglichkeit mit mORMot... ?
Miniaturansicht angehängter Grafiken
konzept.png  
Angehängte Dateien
Dateityp: zip OlympicKonzeptBin.zip (2,63 MB, 58x aufgerufen)
Dateityp: zip OlympicKonzeptPas.zip (17,8 KB, 46x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Kleine Demo zu mORMot

  Alt 7. Nov 2011, 00:10
Also zum Thema Geschwindigkeit:

Als Http-Server ist die Performance schon etwas schlechter. Das solltest du mit der beiliegenden Demo sehen können.
Dieses liegt aber zum einen am Protokoll und an der AJAX-Kompatibilität (die kann man aber auch abschalten).
Man kann aber die Datenbank eben nicht nur per Http, sondern auch z.B. per NamedPipe den Clients zur Verfügung stellen, und das ist dann sehr schnell.

Einen direkten Vergleich mit anderen Datenbank-Systemen bzw. Übertragungsprotokollen habe ich noch nicht gemacht.
Wäre evtl. auch unfair, da diese ja schließlich nicht die Möglichkeit bieten ein komplexes Business-Objekt einfach so zu verarbeiten.

Sollte die Datenbank selber (ist ja ein SQLite3 im Hintergrund) zu langsam sein, so kann man auch eine andere Datenbank (Zugriff muss via OleDB oder ODBC möglich sein) als Basis nehmen.

Letztendlich kommt es eben darauf an, was man erreichen möchte:

Ich bin gerade dabei eine Datenschnittstelle für MDE-Geräte damit zu bauen. Der Hersteller der MDE-Software bekommt als Vorgabe mit diesem REST-Server seine Daten auszutauschen. Meine Anwendung liest dann von diesem Server die Daten ein.

Der Vorteil liegt dabei klar auf der Hand: Mir ist es von nun an egal, was für (MDE-)Geräte da Daten bereitstellen und meine Anwendung kann bleiben wie sie ist, es sei denn auf der Ebene gibt es Gründe für eine Änderung.

Mal sehen wie die Hersteller darauf reagieren ... ich gebe da mal ein Feedback

ich habe mir mal 2 Methoden zum Speichern und Laden aus deiner Demo-Anwendung rausgepickt und auf mORMot umgeschrieben.

Das Model:
Delphi-Quellcode:
type
  TSQLPanel = class( TSQLRecord )
  private
    fLeft : integer;
    fTop : integer;
  published
    property Left : integer read fLeft write fLeft;
    property Top : integer read fTop write fTop;
  end;
die Methode zum speichern:
Delphi-Quellcode:
procedure TFormTestObjectDB.odbPanel1Click(Sender: TObject);
var
  odbPanel: TodbPanel;
  lPanel : TSQLPanel;
begin
  odbPanel := Sender as TodbPanel;
  lPanel := TSQLPanel.Create;
  try
    lPanel.Left := odbPanel.Left;
    lPanel.Top := odbPanel.Top;
    lPanel.ID := odbPanel.Tag;
    fCltCon.Client.Update( lPanel );
  finally
    lPanel.Free;
  end;
end;
die Methode zum laden
Delphi-Quellcode:
procedure TFormTestObjectDB.Timer1Timer(Sender: TObject);
var
  lPanel : TSQLPanel;
begin
  lPanel := TSQLPanel.Create;
  try
    if fCltCon.Client.Retrieve( 1, lPanel ) then
    begin
      odbPanel1.Left := lPanel.Left;
      odbPanel1.Top := lPanel.Top;
      odbPanel4.Left := lPanel.Left;
      odbPanel4.Top := lPanel.Top;
    end;
    if fCltCon.Client.Retrieve( 2, lPanel ) then
    begin
      odbPanel2.Left := lPanel.Left;
      odbPanel2.Top := lPanel.Top;
      odbPanel5.Left := lPanel.Left;
      odbPanel5.Top := lPanel.Top;
    end;
    if fCltCon.Client.Retrieve( 3, lPanel ) then
    begin
      odbPanel3.Left := lPanel.Left;
      odbPanel3.Top := lPanel.Top;
      odbPanel6.Left := lPanel.Left;
      odbPanel6.Top := lPanel.Top;
    end;
  finally
    lPanel.Free;
  end;
end;
es ist aber auch möglich, die Datensätze gleich auf einen Rutsch zu lesen
fCltCon.FillPrepare( fCltCon.Client, 'ID BETWEEN 1 AND 3' ); oder parametrisiert
fCltCon.FillPrepare( fCltCon.Client, 'ID BETWEEN ? AND ?', [], [ 1, 3 ] ); dann sieht die Methode so aus:
Delphi-Quellcode:
procedure TFormTestObjectDB.Timer1Timer(Sender: TObject);
var
  lPanel : TSQLPanel;
  op1, op2 : TodbPanel;
begin
  lPanel := TSQLPanel.Create;
  try
    if lPanel.FillPrepare( fCltCon.Client, 'ID BETWEEN ? AND ?', [], [ 1, 3 ] ) then
      while lPanel.FillOne do
        begin
          case lPanel.ID of
            1 : begin op1 := odbPanel1; op2 := odbPanel4; end;
            2 : begin op1 := odbPanel2; op2 := odbPanel5; end;
            3 : begin op1 := odbPanel3; op2 := odbPanel6; end;
          end;
          op1.Left := lPanel.Left; op1.Top := lPanel.Top;
          op2.Left := lPanel.Left; op2.Top := lPanel.Top;
        end;
    lPanel.FillClose;
  finally
    lPanel.Free;
  end;
end;
Ein wenig Performance könntest du aber auch dadurch gewinnen, wenn du dir für diese Zugriffe eine TSQLPanel-Instanz vorhältst, dann sparst du dir die Zeit für das ständige Create/Destroy.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 7. Nov 2011 um 00:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Kleine Demo zu mORMot

  Alt 7. Nov 2011, 00:20
BTW: Wenn man meine Demo von Http auf NamedPipe umstellen möchte, dann muss man diese Änderungen vornehmen:
Delphi-Quellcode:
// für den Server
fSrvCon := // eine Server-Instanz für
// TmORMotServerHttp.Create( // einen Http-Server
  TmORMotServerNamedPipe.Create( // einen NamedPipe-Server
  TmORMotConfigurator.Create, // mit der Konfiguration
  CreateModel // und diesem Model
  );

// für den Client
fCltCon := // eine Client-Instanz
// TmORMotClientHttp.Create( // für den Zugriff via Http
  TmORMotClientNamedPipe.Create( // für den Zugriff via NamedPipe
  TmORMotConfigurator.Create, // mit der Konfiguration
  CreateModel // und diesem Model
  );
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
neo4a

Registriert seit: 22. Jan 2007
Ort: Ingolstadt
362 Beiträge
 
Delphi XE2 Architect
 
#7

AW: Kleine Demo zu mORMot

  Alt 7. Nov 2011, 07:27
Wenn Du also Dein Datenmodell als Delphi-Objekt ausführst, ist die Bereitstellung eines Rest-Zugriffs auf einen DB-Server dann nur noch ein Einzeiler. Die (Delphi-) Clients können ja trotzdem noch nativ mit dem DB-Server arbeiten. Damit kann man externen Anwendungen Standard-Protokoll-Zugriff auf "seine" Datenbank ermöglichen und hat trotzdem noch exklusive Hoheit über die Geschäftsregeln (ohne umständliche Stored Procedures oder Trigger).

Das ist zwar nicht die Hauptaufgabe von mORMot, aber m.E. ein sehr netter und vor allem schnell realisierter "Seiteneffekt".
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Kleine Demo zu mORMot

  Alt 13. Nov 2011, 13:38
Ok, interessant ist das sicher. Zwei Fragen habe ich aber:

Wenn mehrere Clients den Server nutzen, wie werden dann Konflikte gehändelt?
Wenn ich eine Datenbank aus Version 1 habe und will die mit einer Programmversion 5 (mit anderer Datenstruktur) benutzen, was passiert dann? Gibt es eine Art Differenzscripte o.ä.?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Kleine Demo zu mORMot

  Alt 13. Nov 2011, 14:32
Wenn du dein Konzept richtig aufsetzt, dann gibt es keine Konflikte (Lock/Unlock)

Und unterschiedliche Versionen Client/Server unterliegen eigentlich den gleichen Bedingungen wie bei einem normalen DB-Server.

Die Erweiterung der Tabellenstruktur wird automatisch vom Server auf Basis des Models vorgenommen.
Da muss man sich um nichts kümmern.

Ebensowenig wie du ein Script mitliefern musst, damit die DB aufgesetzt wird.

Problematisch wird es immer dann, wenn du Felder komplett umdeklarierst (z.B. Text->Integer) oder Felder umbenennst.
Aber dieses Problem hast du bei jeder Datenbank und ist kein Alleinstellungsmerkmal von mORMot
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (13. Nov 2011 um 14:38 Uhr)
  Mit Zitat antworten Zitat
general-e

Registriert seit: 1. Jun 2005
Ort: Kamen
5 Beiträge
 
Delphi XE Enterprise
 
#10

AW: Kleine Demo zu mORMot

  Alt 22. Apr 2013, 13:18
Hallo,

ich grabe mal diesen Thread hier wieder aus, da ich glaube, dass er ganz gut zum Thema (mORMot in der Praxis) passt.

Ich bin gerad in der Situation, dass ich mir Gedanken über die Konzeption/Layout/DB-Design unsere zuküftigen Projekte machen kann.
Nach einigem Suchen/Lesen bzgl. N-Tier komme ich immer wieder auf mORMot.
Für jemanden der keinerlei Erfahrung mit ORM und Client/Server System hat ist der Anfang doch recht schwer.
Besonders bei einer solch gewaltigen Doku (die sich auch noch stündich ändert )

Ein kleines Testprojekt habe ich mir mal aufgesetzt.

Ich habe ein paar Fragen diesbezüglich wie ihr das System in der Praxis nutzt.

1. Sind eure Formulare eher tabellenbasiert oder zeigt ihr immer nur einen Datensatz an mit der Möglichkeit zu suchen/blättern?
2. Wenn ich eine Tabelle (ich nutze hier Devexpress cxGrid mit eigenem CustomDatasource) anzeige, wie bekomme ich dann z.B. bei einem Artikel (TSQLRecord) den Namen der hinterlegten Artikelgruppe (TSQLRecord). Muss an diesen Stellen wieder mit SQL arbeiten?
3. Macht das interne Rechtesystem Sinn, wenn man wesentlich mehr Rechte braucht?
Ich brauche z.B.
Rechte auf Objekte (Artikel): Einfügen, Ändern, Löschen, Drucken, Filtern, Suchen, Exportieren, ...
Rechte auf Funktionen: Wareneingang buchen, Lieferschein schreiben, Rechnung schreiben, ...

mfg

Marco
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      

 

Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz