home
erste Version am 13.12.2020
letzte Änderung am 16.12.2020

ERMzilla (Seite 2)

Version 1.08

Heute ist der Sonntag unmittelbar vor meinem vierwöchigen Urlaub. Gerade wurde der harte (oder auch totale?) Lockdown wegen der Corona-Pandemie angekündigt.
Also keine Verwandtschaftsbesuche zu Weihnachten. Auch das Böllern fällt flach. Wie schön. Weniger Lärm, kein Pulver-Gestank.
Ebenso heißt das natürlich: noch weit mehr Zeit als gedacht .... für ERMzilla.

Für die Änderungs-Historie habe ich gerade eine weitere Klasse angelegt. Die Datei hat läppische 83 Zeilen und funktioniert soweit wunderbar.
Ich habe es mir allerdings auch ziemlich einfach gemacht (und hoffentlich rächt sich das nicht, sobald das Programm komplexer wird):
Derzeit gibt es noch minimale Störungen bei der Interoperabilität mit der Klasse, die die markierten Objekte verwaltet. Und zwar dann, wenn ein neu gesetzter Eckpunkt markiert ist, die Strg-Z-Taste betätigt wird und dabei der markierte Eckpunkt verschwindet.
Darum kümmere ich mich nach einem Mittagsschläfchen. :-)

Nun wird der Index eines Eckpunktes vor dem Zugriff darauf geprüft. Damit gibt es jetzt zwar keine Fehlermeldungen mehr - trotzdem wandert die Markierung eines verschwundenen Eckpunktes weiterhin zum vorigen Eckpunkt. Das lässt sich auch nicht so leicht beheben, weil für die Markierungen die Indices der Eckpunkte gespeichert werden. Bei der Änderungs-Historie sind es hingegen die Koordinaten. Und weil beides auch so bleiben soll (ansonsten gäbe es Update-Anomalien beim Verschieben des gesamten ERMs),  werden jetzt Markierungen bei einem Strg-Z kurzerhand gelöscht.

Die got/lost-Focus-Magie sieht jetzt so aus, dass die Hintergrundfarbe von ERMzilla auf hellrot (oder so ähnlich) gestellt wird, wenn beim Focus-Verlust ungespeicherte Änderungen existieren.
Zwar wird das Fenster damit jetzt auch dann hellrot, wenn man es verschiebt oder dessen Größe ändert - aber was solls.
Hier die v1.08.

Die nächste Erweiterung werden dann wohl die im ERM angezeigten Kommentare.


Überlegungen #1

Gerade fällt mir auf, dass der Urlaub offiziell noch nichteinmal begonnen hat und ich trotzdem nur noch zwei größere Baustellen habe .... also bezüglich der bisherigen ToDo's.
Zum Glück gibt es aber ja auch noch ein paar Service-Scripte zu bauen.

Beispielsweise ein Script, dass die Tabellen- und Relations-Deklarationen aus MySQL ausliest und im ERMzilla-Format ablegt.
Vielleicht sogar hin und zurück. Wobei das ERMzilla-nach-MySQL-Script dann aber auch mit Beziehungen umgehen können müsste, für die kein FOREIGN_KEY-Constraint generiert werden darf/kann.
Praktisch habe ich derzeit -immer mal wieder- Beziehungen vom Typ  0,1-0,n  per ERMzilla dokumentiert. Und wenn beide Seiten mit "0," anfangen, wird das wohl eher nix mit einem Constraint. ;-)
Außerdem habe ich das Format der Beziehungen bewusst und mit voller Absicht nur insofern festgelegt, dass ein "-"-Zeichen als Trennmarke vorkommen muss (naja...okay, Leerzeichen sind auch nicht erlaubt). Aber ansonsten kann man da alles eintragen, was man an den beiden Enden der Relationen angezeigt haben möchte. Damit wäre es zwangsläufig vorbei, wenn es ein ERMzilla-nach-MySQL-Script gäbe.

Andererseits hatte ich schon vor ein/zwei Wochen zeitweilig darüber nachgedacht, parallel zum RELATION-Keyword noch ein Keyword für genau solche zurInfo-Beziehungen vorzusehen.
Zwecks Lesbarkeit (und mangels besserer Ideen für Keyword-Namen) wären die zurInfo-Beziehungen dann über das bisherige RELATION-Keyword abzubilden. Die echten/harten Beziehungen würden zukünftig per neuem REFERENCE- oder CONSTRAINT-Keyword definiert werden.
Das sollte (derzeit noch problemlos) machbar sein .... und hieße: einmal Strg-H (Suchen und Ersetzen) in allen bisherigen *.ermz-Dateien.

Zur Erklärung: diese hässlichen 0,1-0,n-Beziehungen gehen üblicherweise zu Tabellen, die wir für vor-aggregierte Daten nutzen.
So nach dem Prinzip Data Warehouse - nur eben vollintegriert. Ja...gruselig......der Frontend-PHP-Code ist voll von LEFT [OUTER] JOINs....aber es ist nun mal so, wie es ist.
Das Gerade-ziehen der Beziehungen kommt dabei aus dem Backend (was mittlerweile mein Baby ist), erfolgt aber nur zyklisch per System-Service oder z.T. sogar nur einmal pro Stunde mittels Cronjob.

Das Fazit ist, dass vielleicht erstmal das neue Relations-Keyword kommen sollte, bevor das NOTE-Keyword kommt.


Version 1.09

Der erste (echte) Urlaubstag soll dazu genutzt werden, das neue Keyword CONSTRAINT zu implementieren. Gleichzeitig braucht es natürlich auch noch ein Keyword CONSTPOS für die entsprechenden Positionsdaten.
Praktisch wird sich die neue Klasse wohl kaum von der jetzige Relation-Klasse unterscheiden. Daher könnte auch in Erwägung gezogen werden, die jetzige Relation-Klasse lediglich um ein weiteres Attribut zur Fallunterscheidung zu erweitern.
Das hätte den Vorteil, dass nicht überall, wo jetzt über alle Table- und Relation-Objekte iteriert wird, zusätzlich noch über alle Constraint-Objekte iteriert werden muss.

Die Keywords RELATION und CONSTRAINT würden beide in der Relation-Klasse landen, das Keyword RELPOS gälte für beide Beziehungstypen. Lediglich bei der Darstellung in __drawDC() würde je Typ ein eigener wx.Pen genutzt werden. Und das MySQL-Export-Script würde natürlich nur die CONSTRAINT-Beziehungen berücksichtigen.

So. Schon fertig - höchstens ne halbe Stunde Arbeit. Auf diese Weise waren nur drei kleine Änderungen in den Klassen Relation und FileOps sowie in __drawDC() nötig, um das neue Keyword zu implementieren.

Vielleicht ließe sich das Keyword NOTE auf ähnliche Weise über die Table-Klasse abbilden. Eine NOTE braucht zwar keine Tabellen-Spalten und Relationen müssen da auch nicht dran andocken, nichtsdestotrotz bräuchte es die meisten Funktionen aus der Table-Klasse ebenfalls in einer Note-Klasse.
Ich mache für die CONSTRAINT-Änderungen mal eine eigene Version - zu der ich notfalls zurückkehren kann, falls das zu großes Gemurkse wird.


Version 1.10

Schon gehts los mit den Stolpersteinen: eine Tabelle braucht einen Namen, über den sie von TABPOS referenziert werden kann. Eine NOTE sollte eigentlich keinen Namen brauchen. Ohne diesen könnte sie aber höchstens durch ihre Position innerhalb der Datei bzw. ihren Vorkommens-Index referenziert werden. Und die aktuelle Position im NOTE-Satz selbst abzulegen, ist mal so gar keine Option. Das würde in der Github-Ansicht zu Änderungs-Sätzen im statischen Bereich der Datei führen.
Also hilft es nix: eine NOTE braucht einen eindeutigen Namen. Etwa als:
    NOTE comment_1 Dies ist ein Kommentar!

So. Auch fertig. Hier musste ich sogar nur in den Klassen Table und FileOps ändern.
Ein ERM mit Kommentar sieht etwa so aus:
ERM mit Kommentar

Und so, wenn es ungespeicherte Änderungen gibt und das Programm den Fokus verloren hat:
ERMzilla bei Focus-Verlust und ungespeicherten Änderungen

Die zugehörige ERM-Datei ist diese:
TABLE Company
id int PK
name varchar
desc varchar
addr varchar
TABCOLOR Company #0088ff
CONSTRAINT Company.Company2Project 1-n Company.id Company2Project.company_id
CONSTRAINT Company.Company2Person 1-n Company.id Company2Person.company_id

TABLE Project
id int PK
name varchar
desc varchar
TABCOLOR Project #0088ff
CONSTRAINT Project.Company2Project 1-n Project.id Company2Project.project_id
CONSTRAINT Project.Project2Person 1-n Project.id Project2Person.project_id

TABLE Person
id int PK
name varchar
addr varchar
TABCOLOR Person #0088ff
CONSTRAINT Person.Company2Person 1-n Person.id Company2Person.person_id
CONSTRAINT Person.Project2Person 1-n Person.id Project2Person.person_id
CONSTRAINT Person.Person2Skill 1-n Person.id Person2Skill.person_id

NOTE komm_01 Dies ist ein Kommentar\nmit einem Zeilenumbruch.

TABLE Skill
id int PK
name varchar
TABCOLOR Skill #0088ff
CONSTRAINT Skill.Person2Skill 1-n Skill.id Person2Skill.skill_id

TABLE Company2Project
company_id int PK
project_id int PK

TABLE Project2Person
project_id int PK
person_id int PK
from_dt datetime
to_dt datetime

TABLE Company2Person
person_id int PK
company_id int PK
from_dt datetime
to_dt datetime

TABLE Person2Skill
person_id int PK
skill_id int PK



TABPOS Company (42,28)
RELPOS Company.Company2Project LL (14,70) (14,266)
RELPOS Company.Company2Person RL
TABPOS Project (224,238)
RELPOS Project.Company2Project LR
RELPOS Project.Project2Person RL
TABPOS Person (462,14)
RELPOS Person.Company2Person LR
RELPOS Person.Project2Person RR (602,84) (602,294)
RELPOS Person.Person2Skill RL
TABPOS komm_01 (378,154)
TABPOS Skill (686,224)
RELPOS Skill.Person2Skill RR (826,266) (826,70)
TABPOS Company2Project (42,224)
TABPOS Project2Person (406,238)
TABPOS Company2Person (224,14)
TABPOS Person2Skill (672,14)

Gerade sehe ich, dass die Tabellenanzahl (ganz links in der Statusleiste) den Kommentar als Tabelle zählt.
Na welch Wunder. Natürlich lässt sich das leicht fixen - so dass dort dann "t:8, r:8,n:1" angezeigt würde.
Weil ich das Archiv für die v1.10 aber gerade schon gebaut habe, landet der Fix in v1.11. Jetzt ist erstmal Mittagspause.


Version 1.11

Heute will ich mal damit anfangen, Größe und Position des ERMzilla-Fensters aus dem Kontextmenü heraus speicherbar zu machen. Zusammen damit können dann auch noch ein paar weitere Settings persistent (aber änderbar) im *.conf-File abgelegt werden.

Wie schön, wenn man bereits einen großen Fundus an wxPython-Scripten hat.
Wieder konnte ich ganze Funktionen aus einem über sechs Jahre alten Script kopieren und mit minimalen Anpassungen in ERMzilla verwenden.
Das ToDo "Align-ERM" ist auch bereits implementiert.

Damit bleibt nur noch "Zoom-In, Zoom-Out" übrig.
Vielleicht reicht es dafür ja, die FontSize und das Raster zu ändern. Schließlich sind das die Parameter, die die Größe einer Tabelle determinieren.
Einen Test ist es wert.

Natürlich klappt das nicht. Schließlich müssen auch die Abstände der Tabellen untereinander und die Positionen der Eckpunkte angepasst werden.
Elender Mist. Da macht man einmal keine neue Version, zu der man zurückkehren könnte - und schon geht genau das in die Wicken.

Andererseits können die Änderungen auch drin bleiben. Die hatte ich gebraucht, um importierte globale Konstanten nachträglich ändern zu können.
Der Trick dabei ist, sie nicht per "from globalStuff import *" reinzuholen - sondern per "import globalStuff". Bei allen Zugriffen braucht es dann den Import-Namen als Prefix. Also beispielsweise "globalStuff.RASTER". Und der Umbau hat natürlich zu reichlich Änderungen in allen Dateien geführt.

Für eine funktionierende Zoom-Funktion sollten wohl zunächst mal alle DC-Koordinaten in Raster-Koordinaten umgerechnet werden.
Warum wird eigentlich nicht grundsätzlich auf Raster-Koordinaten operiert? Irgendwann (ganz zu Beginn des Projekts) war das jedenfalls mal so gedacht. Und dann bin ich aus irgend einem Grund wieder davon abgekommen ... aber welchem?
Tabellen und Eckpunkte liegen ohnehin immer auf dem Raster (andernfalls wäre es viel zu friemelig, exakt waagerechte und senkrechte Relationen zu zeichnen).
Vielleicht sah es ja scheiße aus, wenn man das gesamte ERM in Raster-Schritten verschoben hat.
Egal. Das bleibt jetzt so.
Nachtrag: gerade habe ich das testhalber mal eingebaut. Das Aussehen ist kein Problem ... jedoch funktioniert langsames Verschieben in eine Richtung gar nicht und bei der anderen Richtung wird es unsteuerbar schnell.

Hauaha... das waren aber mal reichlich Änderungen. Der Umbau für die zoombaren Tabellen- und Eckpunkt-Koordinaten war schnell gebaut.
Was dann aber schon zwei/drei oder auch vier Stündchen gekostet hat, war der Umbau der Undo-Historie (bzw. das Erkennen der Notwendigkeit dafür). Die dort verwendeten Datenstrukturen waren nicht dazu geeignet, nachträglich schreibend auf gespeicherte Positionsdaten zuzugreifen. Ich hatte da Listen von Tupeln aus Listen, die ihrerseits Tupel aus Tupeln und Listen enthielten. Gruselig. Folglich musste die ganze Klasse erstmal auf vernünftige und überschaubare Datentypen umgebaut werden.
Als Lohn dafür kann man ab sofort Objekt-Positionen ändern, dann Zoomen und in einem anderen Zoom-Level die Strg-Z-Taste drücken - trotzdem landet alles wieder genau dort, wo es (relativ gesehen) hingehört.

Was ich beizeiten noch ändern muss, ist die Art und Weise, wie die Seite des Tabellen-Andock-Punktes einer Relation zwischen links und rechts gewechselt werden kann. Das dafür bisher verwendete MouseWheel hat ja gerade eine andere Funktion bekommen. Und komfortabel oder gar intuitiv bedienbar war das eh nie. Aber nicht mehr heute.


Gestern Abend war mir noch aufgefallen, dass sich das Zoomen in ERMzilla irgendwie anders anfühlt, als etwa in OpenStreetMap. Richtig fühlt es sich erst an, wenn die aktuelle Position des Maus-Zeigers berücksichtigt wird und der unter dem Maus-Zeiger befindliche Bereich des ERMs seine Position durch den Zoom nicht wesentlich ändert. Leichtes Gewackel lässt sich nicht vermeiden, weil schließlich das Raster eingehalten werden muss.
Durch die neusten Änderungen fühlt sich das Zoomen jedenfalls so an, wie man es von OpenStreetMap (oder auch wxOSM) her kennt.

Dann stellt sich jetzt die Frage, wie dem Programm ein Seitenwechsel-Wunsch für einen Tabellen-Andock-Punkt mitgeteilt werden kann.
Idealerweise sollte auch gleich der Umstand berücksichtigt werden, dass mehrere Relationen an einer Tabellen-Spalte andocken - und man genau eine definierte Relation zur anderen Seite verschieben will.
Mit der Funktion isPointOnTableConnector() kann erkannt werden, ob sich der Maus-Zeiger über einem Tabellen-Andock-Punkt befindet.
Ebenfalls kann erkannt werden, welche Relationen an diesem Punkt andocken. Bei mehr als einer andockenden Relation, sollte eine davon auswählbar sein.
Ein kleiner PopUp-Dialog mit den entsprechenden Relations-Namen wäre denkbar - aber sehr viel Arbeit, weil er quasi selbstgebaut auf dem DC dargestellt werden müsste. Ebenso wäre ein spezielles, dynamisches Kontext-Menü denkbar.
Also: wird ein Tabellen-Andock-Punkt mit der linken Maus-Taste angeklickt, wechselt er die Seite. Bei mehr als einer angedockten Relation öffnet sich hingegen zunächst ein Kontext-Menü mit den Relations-Namen und nach Auswahl wechselt die gewählte Relation die Tabellen-Seite. Der einzige Wermutstropfen an dieser Methode ist, dass die Relationen aussagekräftige Namen haben sollten.

Im tiefsten Zoom-Level (-9) sieht das ERM damit so aus:
ERMzilla im tiefsten Zoom-Level und mit Kontextmenü

Und so sieht es aus, wenn ein Tabellen-Andock-Punkt angeklickt wurde, an dem mehrere Relationen andocken:
Seiten-Wechsel-Auswahl

Hier die v1.11.



Die Fortsetzung folgt auf Seite 3.