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):
- beim Eintritt ins MouseLeftDown-Event werden alle
Positionsdaten temporär gesichert.
- am Ende des MouseLeftUp-Events werden die gemerkten
Positionsdaten mit den aktuellen Daten verglichen und erkannte
Änderungen einer Liste zugefügt.
- analog passiert dies auch beim MouseWheel-Event - abgesehen
davon, dass sich hier alles innerhalb der einen Funktion
abspielt.
- bei Strg-Z wird das letzte Element von der Liste genommen und
die darin enthaltenen Positionsdaten in die jeweiligen Tabellen-
und Relations-Objekte kopiert.
- die Operationen "Datei per Drag&Drop laden", "reload" oder
"save" löschen die Historie in einem Rutsch.
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:

Und so, wenn es ungespeicherte Änderungen gibt und das Programm den
Fokus verloren hat:

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:

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

Hier die v1.11.
Die Fortsetzung folgt auf Seite 3.