Entw.: Migration einer älteren Delphi-Applikation

Warum ist eine Migration notwendig?

Eine Applikation, die auf BDE und einer alten Delphi-Version basiert, besitzt Schwächen, auch wenn diese Applikation zuverlässig funktioniert. Hier eine Aufzählung mit den wichtigsten Nachteilen, wenn die Applikation nicht modernisiert wird:

  • → Neuerungen der Delphi-Entwicklungsumgebung (dbExpress, DataSnap, Azure) lassen sich nicht nutzen. Zukünftige Delphi-Versionen werden einen 64-bit-Compiler besitzen und auch andere Plattformen unterstützen.
  • BDE ist wirklich veraltet. Man muss mit seinen Macken leben und versuchen sie zu umgehen. Neue Datenbank-Links wird es nicht mehr geben. Auch fehlt die Unicode-Unterstützung.
  • → Es ist ein Rechner vorzuhalten, der die alte Entwicklungsumgebung besitzt. Ein Neuaufsetzen einer alten Entwicklungsumgebung auf einem neuen Rechner mit neuerer OS ist oft sehr aufwendig. Oft misslingt dies auch.
  • → Ein grosser Nachteil für den Kunden ist, dass das Programm sehr viel schlechter von anderen Entwicklern gepflegt werden kann, da diese Entwickler kaum in der Lage sind, die alte Entwicklungsumgebung aufzusetzen.
  • → Die BDE-Performance ist gegenüber der dbExpress-Performance wirklich schlecht.
  • → Laufzeit-Themes zur Oberflächengestaltung sind nur mit Aufwand einzubinden. Bei den neuen Delphi-Versionen ist nur ein Schalter zu setzen.

Bei einer Verwendung von Fremdkomponenten (evtl. ohne Sourcen), besteht oft keine Chance, sie in die neuere Entwicklungsumgebung zu übernehmen. Hier sollte man auf jedem Fall versuchen, diese Fremdkomponenten zu ersetzen.

Was ist zu tun?

  • → Konvertierung der Strings. Delphi unterstützt ab der Version Delphi 2009 nun standardmässig Unicode. Der Typ string ist ein Alias für UnicodeString, nicht für AnsiString. Deshalb sollte man die bisherigen Strings in AnsiString wandeln. Eine Komplettumwandlung nach UnicodeString ist oft zu aufwändig.
  • → Austausch der BDE durch die Datenbank-API dbExpress. Statt einer dbExpress-Migration besteht auch die Möglichkeit, die Applikation nach uniDAC oder ODAC zu migrieren. Diese Produkte besitzen einen Migration Wizard, welche einem die meiste Arbeit abnehmen. Die Datenbank-API ODAC ist die bessere Wahl, wenn als Datenbank nur ORACLE verwendet wird und ein Datenbankwechsel auch nicht geplant ist. Die erreichbare Performance ist hier am besten. Siehe dazu die Performance-Übersichten der Datenbank-API's .
    Es gibt zusätzlich einige dbExpress-Treiber der Fa. Devart. Der Einzeltreiber dbxoda für Oracle bietet z.B. zusätzliche Konfigurationsmöglichkeiten, die die Migration stark vereinfachen. Leider kostet ein einzelner Treiber zusätzlich Geld (ca. 260 EUR inkl. Sourcen).

Voraussetzungen für eine erfolgreiche Migration

  • → Die neueste Delphi-Version XE als Enterprise-Edition.
  • → Installation von GExperts
  • → Einen DFM-Editor zum schnelleren Ändern der Delphi-Formulare.
  • → Evtl. Software für eine andere Datenbank-API (uniDAC, ODAC oder für dbExpress dbxoda)
  • → Zur Typumwandlung string nach AnsiString gibt es das Tool von Roger Connell: DelphiStringToAnsiStringConverter

1. Schritt: Konvertierung nach AnsiString

Für diesen Schritt kann das Tool von Roger Connell verwendet werden.

Konvertierung nach AnsiStringKonvertierung nach AnsiString

Die Bedieneroberfläche des Tools ist selbsterklärend.

Nach der Konvertierung sind einige Änderungen wieder zurück zunehmen. Dies betrifft z.B. alle onGetText-, onSetText-, onGetEditText- oder onSetEditText-Methoden der TField-Objekte. Sie benötigen nun UnicodeString's ( <-> string). Welche Stellen betroffen sind, wird von der IDE bzw. Compiler als Fehler gemeldet.

Beispiel:
procedure TStmGleisDlg.tblWorkGEAENDERTGetText(Sender: TField; var Text: AnsiString; DisplayText: Boolean);
wieder zurücksetzen nach:
procedure TStmGleisDlg.tblWorkGEAENDERTGetText(Sender: TField; var Text: String; DisplayText: Boolean);

Am Schluss dieses ersten Schrittes erfolgt der Test. Die Applikation sollte nach der AnsiString-Konvertierung wieder vollständig korrekt funktionieren.

Anmerkung: Bei einer Migration hatten alle DBGrid's auf einmal einen schwarzen Hintergrund (bei clWindow als Farbe). Hier waren die Spaltenfarben auf clWhite zu setzen.

2. Schritt: Konvertierung von der BDE nach dbExpress

Für diese recht umfangreichen Arbeiten bietet sich das Tool GExperts an. Bei der Installation integriert sich das Tool in die IDE der Entwicklungsumgebung.

GExperts-MenüGExperts

GExperts bietet den Entwickler einige recht komfortable Werkzeuge. Der geübte Umgang mit diesen Werkzeugen spart einem Entwickler einiges an sonst aufwendigen manuellen Arbeiten. Meine Erfahrungen mit diesem Tool sind eindeutig positiv.



Klassen ersetzen mit GExpertsKlassen ersetzen

Hervorzuheben ist hier die Möglichkeit Klassen auszutauschen. Der Austausch findet auf .pas- und .dfm-Ebene statt.


Suchen und ersetzen mit GExpertsSuchen und ersetzen

Hilfreich ist auch die Verwendung der Suchfunktion von GExperts und anschliessenden Replace.


Zum schnelleren Ändern bzw. Neueinfügen von Formulareigenschaften verwende ich einen DFM-Editor. Das Ändern über den Objektinspektor ist mir für die umfangreichen Änderungen zu mühselig.

Folgende Klassen sind auszutauschen:

  • → Konvertierung der TDatabase-Komponente nach TSQLConnection
  • → Konvertierung aller TQuery-Komponenten nach TSQLQuery mit Hilfe von GExperts
  • → Konvertierung aller TTable-Komponenten nach TSQLTable mit Hilfe von GExperts, aber nur dann, wenn nicht mit Filtern gearbeitet wurde.
  • → Wurde mit Filtern gearbeitet, so bietet sich die Komponente TSimpleDataSet an. Hier ist aber statt einem Tabellennamen ein Select anzugeben. Meine Empfehlung ist, immer mit dieser Komponente zu arbeiten, auch wenn dies etwas mehr Aufwand bedeutet. Beim Einfügen der neuen Formulareigenschaften hilft der DFM-Editor.
  • → Konvertierung aller TStoredProc-Komponenten nach TSQLStoredProc mit Hilfe von GExperts
  • → Bei allen Komponenten TSQLQuery, TSQLTable und TSQLStoredProc ist die Eigenschaft SQLConnection zu besetzen.
  • → Die Parameter unter params sind korrekt zu definieren. Parametertypen ftUnknown funktionieren nicht.
  • → Konvertierung aller TDateTimeField-Komponenten nach TSQLTimeStampField mit Hilfe von GExperts. Auch bei Verwendung der Konstanten ftDateTime sollten die Konstanten ftTimeStamp bzw. ftOraTimeStamp mit berücksichtigt werden.

Verwendung des Standardtreibers

Bei Verwendung des Standardtreibers, hier speziell der Oracle-Treiber, sind folgende recht umfangreiche Arbeiten zu verrichten:

  • → Konvertierung aller TStringField-Komponenten nach TWideStringField mit Hilfe von GExperts. Auch bei Verwendung der Konstanten ftString sollte man diese nach ftWideString wandeln bzw. die Konstante ftWideString bei der Verarbeitung berücksichtigen.
  • → Konvertierung aller TFloatField-Komponenten nach TFMTBCDField mit Hilfe von GExperts. Auch bei Verwendung der Konstante ftFloat sollten die Konstante ftFMTBcd mit berücksichtigt werden.
  • → Bei der Verwendung der Oracle-Datenbank muss die Konvertierung auch für TIntegerField-Komponenten nach TFMTBCDField mit Hilfe von GExperts erfolgen. Alle Algoritmen, die die Konstante ftInteger verwenden, sollten berücksichtigen, dass die Felder nun vom Typ ftFMTBcd sind.
  • → Bei Verwendung des Standardtreibers treten noch folgende Fehler auf:
    - Ein Select der Form select count(*) from xtable funktioniert nicht.
       Er ist abzuändern nach select count(*) as Cnt from xtable.
    - Parameter in Select's sollten ohne Leerzeichen angegeben werden.
       WG_NR_1=_:Wg1 funktioniert nicht, da ein Leerzeichen vorhanden ist.
       Fehlerfrei ist WG_NR_1=:Wg1.

Verwendung eines speziellen dbExpress-Treibers

Wird der Treiber der Fa. Devart verwendet, so erspart man sich die obige Arbeiten, die bei Verwendung des Standardtreibers notwendig wären. Statt der dbExpress-Komponente TSQLConnection ist die spezielle Komponente TCRSQLConnection zu verwenden. Alle dbExpress-Komponenten, wie z.B. TSQLQuery, TSQLTable und TSQLStoredProc sind auch bei Verwendung des speziellen dbExpress-Treibers zu nutzen. Mit den folgenden erweiterten Parameterangaben der spezielle Komponente TCRSQLConnection erhält man annähernd das alte BDE-Verhalten für die neue Datenbank-API:
 LongStrings=True
 EnableBCD=False
 UseUnicode=False
 UnicodeEnvironment=False
 IntegerPrecision=11

Während der Arbeiten sind alle Komponenten TSQLQuery, TSQLTable und TSQLStoredProc zu testen, indem man sie zwischenzeitlich auf aktiv schaltet. Ein abschliessender ausführlicher Test ist aufgrund der Menge von Source-Änderungen unumgänglich.