Client Server als DBServer Ersatz

Deutschsprachiges X#-Forum – German language forum

Moderator: wriedmann

User avatar
Heinrich
Posts: 33
Joined: Wed Feb 10, 2016 4:44 pm

Client Server als DBServer Ersatz

Post by Heinrich »

Hallo zusammen

Im Englischen "Suggestions" Bereich habe ich gelesen, dass ein Ersatz für DBServer gewünscht ist.
Leider ist mir die englische Sprache nicht geläufig. So kann ich da nicht mit diskutieren.

Also vor ca. 1 Jahr habe ich begonnen, einen DB-Server Ersatz zu programmieren, welcher von bArrayServer abgeleitet ist. Diese Klasse reagiert genau gleich wie ein normaler DB-Server und kann ohne grosse Anpassung an ein VO Fenster gehängt werden. Als Datenbasis verwendet die Klasse MySQL / Maria DB oder SQLite. Es wäre sicher kein allzugrosser Aufwand Postgrees oder Firebird zu unterstützen.
MySQLArrayServer.png
MySQLArrayServer.png (86.4 KiB) Viewed 632 times
Vielleicht hat ja jemand Interesse.

Heinrich
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Client Server als DBServer Ersatz

Post by wriedmann »

Hallo Heinrich,

das hört sich sehr interessant an und wäre auch etwas, was man sich anschauen könnte/sollte - trifft das, was Karl gemeint hat, recht gut.
Ich habe auch von einem australischen Kollegen gelesen, der einen DataServer auf PostgreSQL-Basis geschrieben hat, nur war ich leider nicht in der Lage, Näheres zu erfahren.

Ich habe vor ca. 13 Jahren was Ähnliches in VO geschrieben. Das arbeitet über das HTTP-Protokoll auf Daten, die auf einem Webserver abgelegt sind und kommt komplett ohne lokale Datenhaltung aus. Auch wenn das mit normalen DataWindows arbeitet, ist es doch kein Drop-In-Ersatz für das DBFCDX-RDD.

Ist Dein Server in Vulcan/X# geschrieben? Nur weil ich die .NET ProviderFactory in Deinem Diagramm sehe...

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Heinrich
Posts: 33
Joined: Wed Feb 10, 2016 4:44 pm

Client Server als DBServer Ersatz

Post by Heinrich »

Hallo Wolfgang

Der Server ist in X# mit dem Schalter VO geschrieben.
Verwendet wird zudem noch der bArrayServer von Joachim Bieler (könnte man eventuell ablösen).

Heinrich
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Client Server als DBServer Ersatz

Post by wriedmann »

Hallo Heinrich,

das wäre sicher mal Wert angeschaut zu werden.

Danke!

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Heinrich
Posts: 33
Joined: Wed Feb 10, 2016 4:44 pm

Client Server als DBServer Ersatz

Post by Heinrich »

Hallo Wolfgang

Beiliegend ein kleines Beispiel, welches einen vom DataServer abgeleiteten DataAdapter enthält.
Damit das Beispiel ohne Fremdprodukte läuft, habe ich die Vererbung vom bArrayServer aufgehoben.

Mit MySQL und MariaDB funktioniert das Beispiel einwandfrei. Bei SQLite habe ich noch etwas Probleme.

Das Beispiel benutzt das in xSharp vorhandene "Standard VO MDI" als Grundlage und ist etwas angepasst worden.


Gruss Heinrich
xSharp_SQL_Beispiel.zip
(30.92 KiB) Downloaded 63 times
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Client Server als DBServer Ersatz

Post by wriedmann »

Hallo Heinrich,

super, danke! Werde ich ausprobieren - MySQL-Datenbanken habe ich ein paar zur Verfügung.

Wolfgang

P.S. ich habe jetzt mal meine Applikationen drauf abgeklopft, ob ich sie mit einem solchen DBServer zum Laufen bringen würde - und bei den meisten würde das nicht funktionieren. Bei den Pflege-Masken wären zwar keine großen Anpassungen notwendig, aber jede Menge Verarbeitungen und Listen sind effektiv so programmiert, daß die nurmit sequentiellem Datenbank-Zugriff laufen, und andernfalls komplett umzuprogrammieren wären.
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Heinrich
Posts: 33
Joined: Wed Feb 10, 2016 4:44 pm

Client Server als DBServer Ersatz

Post by Heinrich »

Hallo Wolfgang

Was genau meinst Du mit "sequentiell" ?
Hast Du ein kleines Beispiel?

Gruss Heinrich
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Client Server als DBServer Ersatz

Post by wriedmann »

Hallo Heinrich,

ganz viele Verarbeitungen in meinen Programmen (und Drucke sowieso) laufen so ab, daß ich einen Order setze, dann die Sätze in einer definierten Reihenfolge hintereinander lese, bis ein bestimmter Wert erreicht ist, und meistens dann pro Satz noch Teilsätze lese.

Das sind aber alles Dinge, die mit SQL auch gehen, bzw. noch viel einfacher zu lösen sind - aber halt eine Umprogrammierung bedingen. Das ist aber sehr viel Code, und diese Zeit habe ich nicht.
Das können bestimmte Listen sein, die Auswahl von Sätzen für die Verrechnung, das Zusammensuchen von Daten für Statistiken oder für Abgleich mit anderen Systemen, aber alle Code, der zum Schreiben bzw. Neuschreiben sehr viel Zeit kosten würde.

Mit MySQL sollte man das auch noch irgendwie hinbekommen, das MySQL über das API ein solches sequentielles Arbeiten erlaubt, aber bei MySQL gefällt mir die Lizenz immer weniger - und vor allem verstehe ich, dass Oracle die Kunden lieber bei seiner eigenen Datenbank hätte als bei MySQL.

lg

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Client Server als DBServer Ersatz

Post by wriedmann »

Hallo Heinrich,

danke nochmals für das Beispiel - ich denke, das kann manchen beim Übergang zu SQL sehr weiterhelfen.

Für meine Applikationen schaut das aber schwierig aus, da ich zum einen teilweise sehr große Tabellen habe (viele Felder und viele Sätze), und beim Öffnen keine Angabe der benötigten Sätze und/oder Felder mache.

Um bereits in den Fenstern DBF mit SQL austauschen zu können, müsste ich einen ziemlich intelligenten Caching-Algorithmus haben, der z.B. bei einem Order-Wechsel alle gecachten Datensätze verwirft und komplett neu einliest, aber eben immer nur einen Teil, um Client und Datenbank nicht zu sehr zu belasten.

Leider sind meine Applikationen meist sehr stark auf die Datenhaltung in DBFs samt dem entsprechenden Zugriff optimiert, und das fällt mir bei einer SQL-Migration auf den Kopf.

Ich habe aber bereits seit mehr als 15 Jahren Erfahrung mit verschiedenen SQL-Datenbanken - den Königsweg habe ich aber bisher noch nicht gefunden.

Vielleicht sehe ich das alles auch nur viel zu kompliziert....

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Heinrich
Posts: 33
Joined: Wed Feb 10, 2016 4:44 pm

Client Server als DBServer Ersatz

Post by Heinrich »

Hallo Wolfgang

Als MySQL Alternative bietet sich MariaDB an. Hier stimmt das Lizenzmodell noch und ist zudem auf jeder Synology bereits vorinstalliert.

Wenn Du bei den Fenstern den bArrayServer verwendest, kannst Du da die Sortierung nach jedem Einlesen neu bestimmen. Es geht sogar dynamisch bei einem Orderwechsel im Fenster und das ohne dass die Daten neu gelesen werden müssten.
Ein Beispiel aus meiner Fensterklasse:

Code: Select all

// Suchbegriff ist erstellt, jetzt die Daten mit Defaultsortierung einlesen und an Fenster hängen
  SELF:_oSchuetzen:OrderBy(#nachname, #vorname, #ort)  
  SELF:_oSchuetzen:Where( cSuchStr )
  SELF:_oSchuetzen:Execute()
Falls jetzt die Sortierung geändert werden muss, kann dies mit dem bArrayServer ohne neues Einlesen erfolgen

Code: Select all

  SELF:_oSchuetzen:CreateOrder({|Server|RTrim(Server:VEREIN)+" "+Server:NACHNAME})
  SELF:_oSchuetzen:SetOrder(1)
Betreffend Anpassung hast Du leider recht. Wenn man von DBF auf SQL wechselt fällt je nach vorliegender Business-Logik mehr oder weniger Anpassungsarbeit an. War bei mir auch so. Da ich jedoch schon vor über 10 Jahren damit begonnen habe alle Auswertungen mit mengenorientierten Abfragen zu erstellten und dafür je Datei eine eigene DbServerklasse geschrieben habe, war in diesem Bereich die Anpassung überschaubar.

Beim Wechsel von VO auf xSharp habe ich auch gleichzeitig den Wechsel von DBF auf SQL vollzogen. Dabei habe ich zuerst die ganze Applikation übernommen um zu sehen wo es Inkompatibilitäten hat. War zum Glück nicht allzu schlimm. :)
Danach habe ich die Serverklassen auf SQL angepasst ohne grosse Optimierung. Erst nachdem die Auswertungen so liefen wie unter VO habe ich begonnen die SQL Zugriffe zu optimieren.

Beispiel VO:

Code: Select all

METHOD GetSkStandblaetter( cSkNr, cJahr, dDatVon, dDatBis ) CLASS DbResultatBP
  Local aRet as Array
  Local aSave as Array

  aSave		:= {}
	
  // Umgebung sichern
    self:SaveUmgebung( @aSave )

  // IndexOrder setzen
    self:SetOrder("SkJahr")

  // auf erstes mögliches Resultat positionieren, kein Softseek
  self:Seek( cSkNr+cJahr, false, false )

  // alle Resultate der gewünschten Sektion lesen
  aRet := {}
	
  Do While .not. self:EoF .and. self:FIELDGET(#sknr) == cSkNr .and. self:FIELDGET(#jahr) == cJahr
    // ist das Resultat innerhalb des gewünschten Zeitraumes?
		
    If (self:FIELDGET(#Stbldrk1) >= dDatVon .and. self:FIELDGET(#Stbldrk1) <= dDatBis ) .or. ;
      (self:FIELDGET(#Stbldrk2) >= dDatVon .and. self:FIELDGET(#Stbldrk2) <= dDatBis ) .or. ;
      (self:FIELDGET(#Stbldrk3) >= dDatVon .and. self:FIELDGET(#Stbldrk3) <= dDatBis )

      // gefundenen oder leeren Datensatz lesen
      AAdd( aRet, LeseDatensatz( self ) )
    Endif

    // nächster Record
    self:Skip(1)
  enddo

  // Umgebung restaurieren
  self:RestoreUmgebung( aSave )
Return aRet
Beispiel xSharp und SQL:

Code: Select all

METHOD GetSkStandblaetter( cSkNr AS STRING, cJahr AS STRING, cAnlassId AS STRING, dDatVon AS DATE, dDatBis AS DATE ) AS ARRAY 
  LOCAL aRet AS ARRAY
  // 
  SELF:cSql := "Select * from " + SELF:cTable + " Where verein_id = '" + cSkNr + "'"
  SELF:cSql += " and jahr = '" + cJahr + "' and anlassid = '" + cAnlassId + "'"
  SELF:cSql += " and STBLDRK1 >= '" + DToS(dDatVon)  +   "'" 
  SELF:cSql += " and STBLDRK1 <= '" + DToS(dDatBis) + "'"

  aRet := SELF:GetDaten2Array( SELF:cSQL )

RETURN aRet
Heinrich

Ps:
Bei meinem Beispiel "xSharp_SQL_Beispiel.zip" hat sich ein Fehler eingeschlichen.
Methode "_GetPrimaryFields()", Zeile 177
falsch => AAdd( SELF:_aPrimaryFld, myField["ColumnName"]:ToString() )
richtig => AAdd( SELF:_aPrimaryFld, { myField["ColumnName"]:ToString() }) // Array anhängen
Post Reply