4 Monate

Verfasst am: Samstag, 31. Mrz. 2012 um 22:12

Etwa 4 Monate nach der Mission accomplished habe ich es, allen störrischen Datenbanksystemen zum Trotz geschafft, heute die zweite stabile Softwareversion vom BVASystem fertigzustellen. Aufmerksame Leser des Blogs werden sicher wissen, mit was ich mich die letzten Monate beschäftigt habe. Für alle anderen fasse ich es trotzdem noch einmal kurz zusammen:

Neuerungen am Programm

Die größte Veränderung am Programm ist sicher die Unterstützung von den Datenbanksystemen MySQL, Firebird und Oracle. Bisher war es nur möglich, MySQL als Datenbanksystem zu verwenden. Die Installation war aufwendig und wahrscheinlich nicht immer leicht. Hier konnte ich definitiv eine Verbesserung erreichen, indem die notwendige Datenbankstruktur nun durch ein Administrationstool erstellt werden kann. Es sind hier weit weniger Benutzereingaben bzw. -aktionen notwendig um ans Ziel zu gelangen.

Aber auch am Hauptprogramm gab es Veränderungen. Das Modul zum Auslesen der EXIF-Bildinformationen wurde erweitert, die neu erfassten Daten werden beim Bildimport  in der Datenbank gespeichert und sie können in einem Bildinformationspopup-Fenster jederzeit angezeigt werden.

Ausblick

Ich hoffe, das ich bis zur nächsten stabilen Softwareversion wieder einen ähnlichen Zeitrahmen benötigen werde. Vorgenommen habe ich mir, das ich die Metadaten-Funktionalität verstärkt erweitere. Ich denke, das diese Funktionalität das BVASystem am stärksten von anderen Bildverwaltungssystemen unterscheidet. Darum denke ich, das die Entwicklungszeit hier gut investiert ist.

Als erstes möchte ich ein neues Metadatenelement implementieren, welches nicht auf dem EXIF-Header basiert. Dieses Metadatenelement wird die mittlere Bildhelligkeit sein. Damit wird es dann beispielsweise möglich sein, Nachtaufnahmen von Tagaufnahmen zu unterscheiden, auch wenn sie am gleichen Tag aufgenommen wurden. Mehr dazu werde ich hier berichten, sobald die neue Funktionalität in einer Entwicklerversion getestet werden kann.

Außerdem habe ich mir vorgenommen, einen vierten Anzeigemodi zu schaffen, auf dem alle Bildinformationen zusammenhängend angezeigt und später auch editiert werden können. Und auch am Administrationstool werde ich weiterarbeiten. Wichtig ist zum Beispiel die Möglichkeit zur Aktualisierung einer veralterten BVASystem Datenbankstruktur.

Datenbanksystem-Unterschiede 4

Verfasst am: Mittwoch, 28. Mrz. 2012 um 13:24

Heute möchte ich meine kleine Datenbanksystem-Unterschied-Serie zum Abschluss bringen.  Als letztes geht es um einen kleinen SQL-Befehl, der im Gegensatz zu den anderen Unterschieden, im alltäglichen Betrieb benötigt wird. Es geht um die Frage:

Wie kann ich die Datensatz-ID des zuletzt gespeicherten Datensatzes erhalten?

Fügt man in eine beliebige Tabelle mit Hilfe eines „INSERT INTO …“-Befehls einen Datensatz hinzu, so weiß man im Normalfall nicht, welcher Wert per Autoincrement/Trigger für das ID-Feld generiert wurde. Diesen Wert benötigt man allerdings, wenn weitere Daten in einer abhängigen Tabelle (foreign keys) gespeichert werden sollen.

Eine Lösung wäre, das man den gerade eingefügten Datensatz wieder selektiert und das ID-Feld ausliest. Dies ist aber nicht notwendig, da alle 3 Datenbanksysteme für diesen Fall eine einfachere Lösung bieten.

MySQL

MySQL besitzt eine Funktion, mit der man die zuletzt hinzugefügte ID erfragen kann. Der Funktionsaufruf ist per SELECT-Befehl möglich und sieht wie folgt aus:

SELECT LAST_INSERT_ID() AS ID

Wichtig ist hier, das der Befehl gleich nach dem INSERT aufgerufen wird, da sich der Wert bei einem weiteren INSERT ändert.

Firebird

Bei Firebird kann man den zur Datenbanktabelle gehörenden Generatorwert erfragen. Es ist ein wenig aufwendiger als bei MySQL, da man für unterschiedliche Tabellen unterschiedliche Generatoren abfragen muss. Die Abfrage sieht wie folgt aus:

SELECT gen_id(GEN_BVA_CREATIONTREE, 0) AS ID from rdb$Database

Vorteil ist hier, das der Generatorwert jederzeit abgefragt werden kann. Auch ohne INSERT kann der aktuelle Wert des Generators abgefragt werden.

Oracle

Mit einer ähnlichen Abfrage kommt man bei Oracle zu seinem ID Wert.  Sie sieht wie folgt aus:

SELECT GEN_BVA_CREATIONTREE.CURRVAL AS ID FROM DUAL

 

Datenbanksystem-Unterschiede 3

Verfasst am: Donnerstag, 22. Mrz. 2012 um 16:01

Im letzten Teil war bereits für Firebird und Oracle ein Datenbanktrigger enthalten, der die Aufgabe hatte, das Auto-ID Feld zu füllen. Der Vollständigkeit halber möchte ich heute einen einfachen Trigger für alle 3 Datenbanksysteme vorstellen. Da die syntaktischen Unterschiede zwischen den Triggern nicht größer sein könnten, werde ich die 3 SQL-Befehle relativ unkommentiert im Raum stehen lassen. Die Möglichkeiten des einzelnen Datenbanksystems sind in den jeweiligen Dokumentationen besser erfasst. Bevor ich jetzt auf die 3 Datenbanksysteme eingehe, möchte ich aber kurz erläutern was ein Trigger ist.

Was ist ein Trigger?

Ein Datenbanktrigger ist eine Datenbankfunktionalität, die in eigentlich jedem größeren Datenbanksystem integiert ist. Man kann sich einen Trigger wie ein kleines Programm vorstellen, das bei bestimmten Datenbankaktionen ausgeführt wird. Beispielsweise kann vor dem Einfügen eines Datensatzes geprüft werden, ob die Daten valide sind. Oder es wird ein Trigger erstellt, der das Erstellungsdatum des Datensatzes speichert.

Genau so ein Trigger soll mein Beispiel für den Vergleich zwischen MySQL,Firebird und Oracle sein. In der Tabelle bva_image speichert der Trigger in dem Feld mod_date das aktuelle Systemdatum ab, sobald ein Datensatz in der Tabelle hinzugefügt wird.

Trigger unter MySQL

CREATE TRIGGER  bva_image_insert_timestamp
 BEFORE INSERT on bva_image
 FOR EACH ROW
  SET NEW.mod_date = NOW();

Trigger unter Firebird

CREATE TRIGGER bva_image_insert_timestamp FOR bva_image
 BEFORE INSERT
 AS
 BEGIN
  NEW.mod_date = CURRENT_TIMESTAMP;
 END

Trigger unter Oracle

CREATE OR REPLACE TRIGGER IMAGE_INSERT_TIMESTAMP
 BEFORE INSERT ON BVA_IMAGE
 FOR EACH ROW
 BEGIN
  :new.mod_date := SYSDATE;        
 END;

Störrische Datenbanksysteme

Verfasst am: Samstag, 17. Mrz. 2012 um 18:11

Eigentlich wollte ich heute hier berichten, das das BVASystem 2.1.0.39-dev nun 3 verschiedene Datenbankmanagementsysteme unterstützt. Leider gab es in den letzten Tagen eine Reihe von Problemen, so das es aktuell nur 2 Datenbanksysteme (MySQL und Firebird) sind. In der nächsten Version werde ich Oracle als drittes Datenbanksystem nachreichen.

Probleme mit Firebird

Schon zu Beginn der Arbeiten zur neuen Version des BVASystems gab es die ersten Probleme. Firebird nutzt ein komplett anderes System um eine Datenbankverbindung aufzubauen als MySQL oder Oracle. Firebird benötigt den Pfad und Dateinamen der Datenbankdatei, um eine Verbindung herzustellen. Da ich Pfad und Dateiname im Administrationstool nicht erfasst habe, war es mir nicht möglich, für alle 3 Datenbanksysteme den gleichen Einstellungsdialog zu verwenden. Also musste ich in den sauren Apfel beißen und einen weiteren Einstellungsdialog entwickeln.

Das zweite Problem war, das auch später im BVASystem immer wieder der Pfad und der Dateiname der Datenbank benötigt wird. Da ich dies absolut nicht wollte, habe ich recht lange nach einer Lösung gesucht und auch eine gefunden. Die Lösung heißt: „aliases.conf“ Im Programmverzeichnis von Firebird liegt eine aliases.conf, in der ein Alias für eine Kombination aus Pfad und Dateiname angelegt werden kann. Das BVASystem Administrationstool legt den benötigten Alias, bei der Erstellung der Datenbankstruktur, mit an. Die einzige Aufgabe, die manuell ausgeführt werden muss, ist ein Neustart des Datenbankservers. Ohne Neustart steht der neue Alias noch nicht zur Verfügung und die Datenbankverbindung schlägt fehl.

Probleme mit Oracle

Auch Oracle erwies sich als nicht weniger störrisch. Die notwendigen Datenbankscripte waren relativ schnell entwickelt, aber bei der von mit genutzten Version 9 lassen sich absolut keine Trigger erzeugen. Per SQLPlus funktionieren die einzelnen Befehle der Scripte wunderbar, aber beim Administrationstool werden vom ODBC-Treiber die Zeilenwechsel durch einen doppelten Wagenrücklauf (#13) ersetzt. Oracle schimpft dann bei der Übersetzung der Trigger, das ein ungültiges Zeichen gefunden wurde. Tests mit der Version 10 funktionierten dagegen einwandfrei. Daher habe ich mich entschlossen, die Unterstützung von Oracle 9 wieder zu entfernen bzw. sie durch Version 11 zu ersetzten. Da ich dafür allerdings mindestens 1 Woche benötige, habe ich entschieden, Oracle auf die nächste Programmversion zu verschieben. Ich hoffe, das dies dann das letzte Problem war, auf dem Weg zur Unterstützung von 3 Datenbanksystemen.

Ausblick

Neben der Oracle Unterstützung habe ich vor, noch einen Programmfehler aus dem BVASystem zu entfernen. Zum Beispiel stürzt das Programm leider ab, wenn ein Bild mit fehlerhaften Exif-Header geladen wird. Außerdem habe ich vor, die Installationsanleitung anzupassen, da nun die Erstellung der Datenbank mit dem Administrationstool einfacher geworden ist.

 

Datenbanksystem-Unterschiede 2

Verfasst am: Freitag, 16. Mrz. 2012 um 14:59

Im zweiten Teil meiner kleinen Serie soll es nun um die Definition eines Auto-ID Feldes gehen. Ein Auto-ID Feld ist ein Datenbankfeld, welches automatisch, beim Einfügen eines neuen Datensatzes, gefüllt wird. Meist wird für diese Zwecke ein Zahlenfeld genutzt. Der erste Datensatz erhält die ID 1, der zweite die 2, der dritte die 3 usw. Benötigt werden die Auto-ID Felder recht häufig, da mit ihnen Verknüpfungen zu anderen Datenbanktabellen, so genannte „Foreign Keys“, hergestellt werden können.

Auto-ID Feld unter MySQL

Wie einfach es ist, unter MySQL ein Auto-ID Feld zu erzeugen, hatte ich bereits im Teil 1 erwähnt. Man muss nur bei der Erzeugung einer Tabelle beim gewünschten Feld das Schlüsselwort AUTO_INCREMENT hinzufügen. Als Datenbankentwickler freut man sich sicher, das man so schnell fertig ist.  Aber man stößt sehr schnell an eine Grenze, wenn man komplexere Sachen umsetzen möchte. Zum Beispiel ist es nicht ohne weiteres möglich, eine eindeutige ID über mehrere Tabellen zu definieren.

Auto-ID Feld unter Firebird

Unter Firebird sind mehrere Einzelschritte notwendig, um ein Auto-ID Feld zu definieren. Als erstes wird logischerweise wie in Teil 1 bereits beschrieben die Tabelle angelegt. Als zweiten Schritt erzeugt man sich einen sogenannten Generator, der die jeweils zuletzt genutzte ID speichert. Die Erzeugung eines Generators erfolgt mit folgendem SQL-Befehl:

CREATE GENERATOR GEN_BVA_CREATIONTREE

Als nächstes muss der Generator mit einem Wert initialisiert werden. Im Beispiel wird der Generator mit dem Wert 0 initialisiert.

SET GENERATOR GEN_BVA_CREATIONTREE TO 0

Als letztes und wichtigstes Element wird ein Trigger benötigt, der vor dem Einfügen eines Datensatzes ausgeführt wird. Der Trigger erhöht den Generatorwert um 1 und trägt den Wert in das gewünsche Auto-ID-Feld der Tabelle ein.

CREATE TRIGGER ID_TRIGGER_BVA_CREATIONTREE FOR BVA_CREATIONTREE
 BEFORE INSERT
 AS
 BEGIN
  NEW.ID = GEN_ID(GEN_BVA_CREATIONTREE,1);
 END

Hier ist es möglich über mehrere Tabellen einen eindeutigen Index zu erzeugen. Dafür muss man in den jeweiligen Triggern den gleichen Generator nutzen.

Auto-ID Feld unter Oracle

Oracle arbeitet prinzipiell nach dem gleichen Konzept wie Firebird. Allerdings heißt der Generator bei Oracle Sequenz. Außerdem entfällt der Initialisierungsschritt, da die Initialisierung bereits bei der Erstellung der Sequenz erfolgt. Die Befehlsfolge für Oracle sieht wie folgt aus:

CREATE SEQUENCE GEN_BVA_CREATIONTREE
 START WITH 1
 INCREMENT BY 1
 NOMAXVALUE
 NOCACHE
 ORDER;
CREATE OR REPLACE TRIGGER ID_TRIGGER_BVA_CREATIONTREE
 BEFORE INSERT ON BVA_CREATIONTREE
 FOR EACH ROW
 BEGIN
  SELECT GEN_BVA_CREATIONTREE.nextval INTO :new.id FROM DUAL;
 END;
/

Datenbanksystem-Unterschiede 1

Verfasst am: Dienstag, 13. Mrz. 2012 um 14:25

Vor einiger Zeit schrieb ich, das eine Datenbankverbindung per ODBC den Vorteil hat, das sie für jedes Datenbanksystem funktioniert, welches ODBC unterstützt. Aktuell, nach der Entwicklung des Administrationstools, muss ich diese Aussage leicht korrigieren. Richtig ist, das die Standard SQL-Befehle, wie SELECT, INSERT, UPDATE usw, mit jedem Datenbanksystem genutzt werden können. Nutzt man allerdings speziellere Dinge wie zum Beispiel SQL-Befehle zum Anlegen von Datenbanktabellen, dann unterscheidet sich die Syntax von Datenbanksystem zu Datenbanksystem.

Da ich gerade beim Schreiben der Scripte zum Erstellen der BVASystem-Datenbankstruktur für MySQL, Firebird und Oracle bin, möchte ich heute eine kleine Serie starten, welche die Unterschiede zwischen diesen 3 Datenbanksystemen zusammenfasst. Dabei werde ich allerdings nur auf die Unterschiede eingehen, die mir im Zusammenhang mit dem BVASystem aufgefallen sind.

Starten möchte ich heute mit den unterschiedlichen Syntax des SQL-Befehls „CREATE TABLE“. Im folgendem werde ich an der Tabelle „bva_creationtree“ zeigen, wo die  Unterschiede zwischen den Datenbanksystemen liegen.

CREATE TABLE unter MySQL

Richtig bequem finde ich bei MySQL die Möglichkeit ein Auto-ID Feld zu generieren. Hierfür muss einfach neben das gewünschte Feld das Schlüsselwort „AUTO_INCREMENT“ geschrieben werden. Bei Firebird und Oracle werden die Auto-ID Felder über eine Kombination aus Generator/Sequenz und Trigger gelöst. Damit dieser Blog nicht zu unübersichtlich wird, werde ich im nächsten Teil noch einmal ausführlich auf das Thema eingehen.

Als zweite Besonderheit bei MySQL fällt auf, das am Ende des Befehles eine „Engine“ ausgewählt werden kann. MySQL unterstützt unterschiedliche Speicherengines. Je nach Einsatzzweck unterscheiden sich die Speicherengines in ihrer Performance. Da mir die Transaktionssicherheit recht wichtig ist, nutze ich die langsamere InnoDB-Engine.

Der komplette SQL-Befehl für die bva_creationtree Tabelle sieht wie folgt aus:

CREATE TABLE bva_creationtree (
 id INT NOT NULL AUTO_INCREMENT,
 parent_id INT ,
 caption VARCHAR(10)  NOT NULL,
 PRIMARY KEY (id),
 INDEX fk_bva_creationtree (parent_id ASC),
 CONSTRAINT fk_bva_creationtree
   FOREIGN KEY (parent_id)
   REFERENCES bva_creationtree (id)
) ENGINE = InnoDB

CREATE TABLE unter Firebird

Schaut man sich den gleichen SQL-Befehl für Firebird an, so sieht er auf dem ersten Blick relativ ähnlich aus.

CREATE TABLE bva_creationtree (
 id INT NOT NULL,
 parent_id INT,
 caption VARCHAR(10) NOT NULL,
 PRIMARY KEY (id),
 CONSTRAINT fk_creationtree
   FOREIGN KEY (parent_id)
   REFERENCES bva_creationtree (id)
 )

Auf dem zweiten Blick fällt dann auf, das für den Fremdschlüssel „fk_creationtree“ kein zusätzlicher Index definiert wurde. Der zusätzliche Index ist bei Firebird nicht notwendig, da er mit dem Constraint zusammen anglegt wird. Das Auto-ID Feld „id“ muss wie bereits beschrieben manuell angelegt werden. Ansonsten gibt es keine weiteren Unterschiede.

CREATE TABLE unter Oracle

Größere syntaktische Unterschiede gibt es bei Oracle. Als erstes fällt auf, das sich die Datentypbezeichnungen unterscheiden: NUMBER(38) anstelle von INT, VARCHAR2() anstelle von VARCHAR() und INT anstelle von FLOAT. Bequem ist, das einfache Primärschlüssel oder auch Constraints direkt hinter der Felddefinition angegeben werden können. Alternativ können sie aber  beispielsweise auch per „CONSTRAINT pk_creationtree PRIMARY KEY (id)“ angelegt werden.

Nach dem Ende des eigentlichen Create Table SQL-Befehlt gibt man bei Oracle an, in welchem Tablespace die Daten der Tabelle gespeichert werden sollen und wie die Tabelle sich verhalten soll, wenn sie zusätzlichen Speicher benötigt. Die dort getätigten Einstellungen haben Auswirkungen auf die Performance. Speichert man große Datenmengen in einer Tabelle, ist es sinnvoll sie in größeren Schritten zu vergrößern, da die Vergrößerung dann nicht mit jedem neuen Datensatz durchgeführt werden muss.

Der vollständige SQL Befehl für die Beispieltabelle sieht wie folgt aus:

CREATE TABLE bva_creationtree (
 id NUMBER(38) NOT NULL PRIMARY KEY,
 parent_id NUMBER(38),    
 caption VARCHAR2(10) NOT NULL,
 CONSTRAINT fk_creationtree
   FOREIGN KEY (parent_id)
   REFERENCES bva_creationtree (id)  
 )
 TABLESPACE bva
 STORAGE
  ( INITIAL     1M
    NEXT         1M
    PCTINCREASE 0
    MINEXTENTS     1
    MAXEXTENTS     UNLIMITED
  )

Eine Hürde weniger

Verfasst am: Sonntag, 26. Feb. 2012 um 14:00

Ich freue mich gerade, da wieder ein sehr wichtiger Punkt auf meiner Todo-Liste abgeschlossen werden konnte. Das Administrationstool, welches sich seit einigen Versionen mit im Installationspaket befindet, ist nun in der Lage, die für das BVASystem notwendige Datenbankstruktur zu erzeugen. Die manuelle Einrichtung der Datenbank, mit Hilfe der MySQL-Workbench entfällt nun. Dadurch sollte es für technisch nicht so erfahrene Anwender einfacher sein, das BVASystem einzurichten.

Ausblick

Mein aktueller Zeitplan sieht so aus, das es noch eine weitere Zwischenversion vor der Veröffentlichung der nächsten stabilen Softwareversion geben wird. In dieser Zwischenversion werde ich die Datenbankscripte, die dem Administrationstool hinterlegt sind so erweitern, das 2 weitere Datenbankmanagementsysteme vom BVASystem verwendet werden können. Wahrscheinlich werden es Oracle und Firebird werden. Aber ganz sicher bin ich mir bei der Auswahl noch nicht. Nach der Zwischenversion heißt es dann noch einmal intensives Testen und wahrscheinlich auch intensives Fehlerbeseitigen.

Wie funktioniert das Anlegen der Datenbankstruktur mit dem Administrationstool?

Das Anlegen der Datenbankstruktur ist recht einfach. Im Administrationstool wählt man dafür im Hauptmenü den Eintrag „Datenbankstruktur erstellen“ aus. Es öffnet sich dann folgender Dialog:

Administrationstool: Datenbankstruktur erzeugen

Administrationstool: Datenbankstruktur erzeugen

In diesem Dialog muss man als erstes die Verbindungsdaten zum Datenbankserver eintragen und anschließend auf „Verbinden“ klicken. Wenn die Verbidnung hergestellt wurde, aktiviert sich die untere Hälfte des Dialoges. Hier wählt man nun aus, ob das BVASystem in ein bestehendes Datenbankschema integriert oder ob ein neues Datenbankschema angelegt werden soll. In beiden Fällen muss der Name für das Datenbankschema festgelegt werden. Als letztes hat man noch die Wahl, wer der Besitzer der Datenbanktabellen sein soll und ob ein Standardbenutzer angelegt werden soll. Wenn alle Einstellungen ausgewählt wurden, schließt man die Auswahl mit Druck auf den Knopf „Struktur erstellen“ ab. Anschließend wird die Datenbankstruktur automatisch erstellt. In der Log-Ansicht wird der Anwender über Erfolg bzw. Misserfolg der einzelnen Arbeitsschritte informiert.

Das Bildinformations-Popupfenster

Verfasst am: Sonntag, 12. Feb. 2012 um 19:03

Dem aufmerksamen Leser dieses Blogs sollte bekannt sein, das ich mir als nächsten kleinen Meilenstein für das BVASystem, ein Popupfenster ausgesucht hatte, in dem Informationen zu dem jeweiligen Bild angezeigt werden. Dieses Bildinformations-Popupfenster ist nun in der Version 2.1.0.37-dev der Bilddatenbank endlich fertig.

Bildinformations-Popupfenster mit EXIF-Daten

Bildinformations-Popupfenster mit EXIF-Daten

Ich freue mich sehr, das ich nun dieses Fenster beim Betrachten meiner Fotos zur Verfügung habe. Endlich werden die gespeicherten Informationen angezeigt und ich kann nun mit nur einem Klick prüfen, welche Aufnahmebedingungen beim Fotografieren herrschten. Aktuell werden im Informations-Popupfenster die, meiner Meinung nach, 8 wichtigsten Daten aus dem Exif-Header angezeigt. Zu den 8 Parametern gehören:

  • Aufnahmedatum
  • Kamerahersteller/Kameramodell
  • Brennweite
  • Iso-Empfindlichkeit
  • Belichtungszeit
  • Blende
  • Abstand zum Objekt

Die Komponente, die zur Anzeige der Bildinformationen dient, ist allerdings so implementiert, das es später möglich sein wird, sich genau die Informationen anzeigen zu lassen, die man persönlich bevorzugt. Auch die Anzahl der Informationen ist nicht in Stein gemeißelt, ab dem 9ten Element wird einfach eine Scrollbar in dem Fenster angezeigt.

Außerdem habe ich in den letzten Tagen noch an dem Administrationstool weitergearbeitet. Ich habe für die Erstellung des BVASystem Datenbankschemas einen Optionsdialog erstellt, der alle notwendigen Informationen erfasst. Den Dialog werde ich allerdings erst in einem späteren Blog beschreiben, da die Implementierung der eigentlichen Funktionalität erst in den nächsten 2-3 Wochen ansteht.

Interne Änderungen

Verfasst am: Donnerstag, 02. Feb. 2012 um 22:19

Der aktuelle Versionssprung stand ganz im Zeichen der internen Änderungen. Notwendig wurden sie zum einen durch den Wechsel auf die ODBC-Technologie und zum zweiten durch das neu entstandene Administrationstool.

Welche Änderungen wurden vorgenommen?

Die erste größere interne Änderung betrifft die Herstellung einer Datenbankverbindung. Bisher war es so, das Servername, Datenbank, Nutzer und Passwort einzelnd benötigt wurden, um eine Datenbankverbindung herzustellen. Das ODBC-Konzept arbeitet dagegen mit sogenannten ODBC-Connectionstrings. Das sind Zeichenketten, die in irgendeiner Form die 4 oben genannten Parameter enthalten. Dummerweise hat der ODBC-Connectionstring für jedes Datenbanksystem einen anderen Aufbau. Daher habe ich nun eine „odbc.ini“ angelegt, welche eine Sammlung von Verbindungsstrings enthält. Je nach eingestellter Datenbank wird einer ausgewählt und zum Herstellen der Datenbankverbindung genutzt. Der Vorteil daran ist, das wenn sich der Aufbau eines ODBC-Connectionstrings ändert, so brauch ich am Programm nichts ändern. Es reicht aus, wenn die „odbc.ini“ angepasst wird.

Damit ich es beim Administrationstool leichter habe, habe ich die Handhabung der Einstellungsdateien komplett überarbeitet. Äußerlich hat sich an den Einstellungsdateien nichts geändert. Der Aufbau ist nach wie vor so, wie in der Installationsanleitung beschrieben. Aber gibt nun intern eine strikte Trennung zwischen allgemeinen Einstellungen, Einstellungen für das BVASystem und Einstellungen für das Administrationstool. Allgemeine Einstellungen sind zum Beispiel die Einstellungen für die gewählte Sprachdatei. Da ich sie für beide Programme benötige, habe ich den Vorteil das ich das Eintellungsobjekt doppelt verwenden kann. Außerdem erreiche ich durch die Trennung, das nur die Einstellungen gelesen bzw. geschrieben  werden, die wirklich benötigt werden.

Weitere Neuerungen

Alle weiteren Änderungen beziehen sich auf das noch relativ junge Administrationstool. Neu hinzugekommen ist dort die Auswahl des  Datenbanksystems, mit dem das BVASystem arbeiten soll. Bisher kann dort allerdings nur „Keine Datenbank“ und „MySQL“ ausgewählt werden. Weitere Datenbanksysteme werde ich nachtragen, sobald die notwendige Datenbankstruktur ebenfalls mit dem Administrationstool erstellt werden kann. Außerdem ist neu, das die im Adminstrationstool durchgeführten Aktionen und Aktionsergebnisse in einem Log erfasst werden.

Administrationstool: Datenbanksystem festlegen

Administrationstool: Datenbanksystem festlegen

Ausblick

In der nächsten Version ist zu erwarten, das das Popupfenster zur Anzeige von EXIF-Daten vorrangetrieben wird. Außerdem habe ich mir vorgenommen, im Administrationstool den Einstellungsdialog zur Erstellung einer BVASystem Datenbank zu gestalten. Die Funktionalität dahinter wird dann in den darauffolgenden Versionen erstellt. Eine ausführlichere Roadmap könnt ihr euch im Bugtracker anschauen.

Wie erstelle ich ein Popupfenster?

Verfasst am: Sonntag, 29. Jan. 2012 um 23:26

Popupmenüs kennt wohl jeder Windowsnutzer, aber warum sollte der Mechanismus nicht genutzt werden, um komplexere Aufgaben  zu übernehmen. Mit diesem Blog möchte ich kurz beschreiben, wie man ein Popupfenster erstellt, auf dem man dann beliebige Komponenten platzieren kann. Das Popupfenster basiert auf einem einfachen Formular, bei dem allerdings einige Dinge berücksichtigt werden müssen.

Keinen Rahmen

Damit das Popupfenster einem Popupmenü ähnlich sieht, darf das Formular keinen Rahmen haben. Setzt dafür einfach die Eigenschaft BorderStyle des Formulars auf bsNone. Zusätzlich platziere ich meist ein TPanel auf das Formular (alClient), damit ich einen sichtbaren Rand erhalte.

Schließen des Popups

Da das Forumlar keinen Rahmen besitzt, gibt es erstmal keine Möglichkeit, um dieses zu schließen, wenn es einmal angezeigt wird. Folgendes Event für  das Panel schafft Abhilfe:

procedure TfrmBVAImageInfo.pClientClick(Sender: TObject);
begin
 Close;
end;

Damit das Popup-Fenster ebenfalls geschlossen wird, wenn man außerhalb des Fensters auf die darunterliegende Anwendung klickt, wird folgendes Event benötigt:

procedure TfrmBVAImageInfo.FormDeactivate(Sender: TObject);
begin
 Close;
end;

Anzeige des Popupfensters

Damit das FormDeactivate Event ausgelöst werden kann, darf das Popupfenster nicht Modal geöffnet werden. Außerdem muss beim Anzeigen den Fensters die Position des Formulars, an die aktuelle Mausposition verschoben werden. Hierfür kann folgende Funktion genutzt werden:

procedure TBVAThumbnail.ShowImageInfo(aX,aY:Integer; aItem:TBVADLDataListItem);
begin
 if aX+FInfo.Width < Screen.DesktopWidth-10
  then FInfo.Left := aX
  else FInfo.Left := Screen.DesktopWidth-FInfo.Width-10;
 if aY+FInfo.Height < Screen.DesktopHeight -10
  then FInfo.Top  := aY
  else FInfo.Top  := Screen.DesktopHeight-FInfo.Height-10;
 FInfo.Show;
end;

FShow ist hierbei das Formular des Popupfensters und aX bzw aY die aktuelle Mausposition, die man aus dem jeweiligen Mausevent erhält, welches das Popup öffnen soll. Durch die beiden If-Abfragen wird sichergestellt, das das Popupfenster immer ganz sichtbar ist.

WMActivate

Zu guter letzt benötigt man noch einen kleinen Trick, damit während das Popupfenster angezeigt wird, das Hauptfenster der Anwendung weiterhin als aktives Fenster sichtbar bleibt:

procedure TfrmBVAImageInfo.WmActivate(var Msg: TWMActivate);
begin
  SendMessage(Application.MainForm.Handle, WM_NCACTIVATE, Ord(Msg.Active <> WA_INACTIVE), 0);
  inherited;
end;

Das fertige Popupfenster sieht dann wie folgt aus:

Bildinformationspopup

Bildinformationspopup