26. Mai 2009 

for english readers

MySQL dump

Die freundlichen Datenlieferer schicken ein MySQL-Dumpfile. Das ist ein 107 MB Text-Dokument.

So stellt BBEdit den MySQL-Dumpfile dar:
-- MySQL dump 9.08
--
-- Host: localhost Database: auskunftdemo
---------------------------------------------------------
-- Server version 4.0.14-nt
  
--
-- Table structure for table '_person'
--
  
CREATE TABLE _person (
MATCHCODE char(15) default NULL,
BEZEICHN char(50) default NULL,
KUERZEL char(10) default NULL,
ZIMMER char(10) default NULL,
TELEFON char(15) default NULL,
KEY i_person1 (MATCHCODE)
) TYPE=MyISAM;
--
-- Dumping data for table '_person'
--
  
INSERT INTO _person VALUES ('BALKEN','Herr Balken','bal','','');
INSERT INTO _person VALUES ('RƒTES','Herr R‰tes','r‰t','','');

es folgen weitere 1.170.482 Zeilen

Alle Tabellen-Beschreibungen und Datensätze in einem einzigen Dokument. Alles in SQL-Syntax als Text. Von Kommentaren getrennt zuerst die Tabellen-Definition, danach die Datensätze. Das Schema wiederholt sich für alle 15 Tabellen. In der Summe sind das 1.170.508 Zeilen. Der Anfang ist hier wie in BBEdit dargestellt.

Klasse. Das komprimiert gut (8 MB) und es kann nichts verloren gehen.

Wie jetzt die 107 MB auseinanderdröseln, damit ich die Daten in 4D übernehmen und den Mehrwert (in diesem Fall PDF) herstellen kann? Das ist ein guter Anlaß zu testen, wie realitätsnah die SQL-Fähigkeiten der V11 sind.

Die ersten Versuche, nur für den Fall das es so einfach wäre:

  • den Dump auf 4D V11 ziehen und fallen lassen
  • über Importieren/Von Datei …
führen zu keinem Erfolg. Also doch selber eine Lösung bauen.

Nach einigem Rumprobieren blieb nur die Lösung: Zeile für Zeile einzulesen und auf den Zeileninhalt zu reagieren. Das sind 3 mögliche Reaktionen

  • -- ist Kommentar und wird nicht verarbeitet
  • CREATE TABLE bedeutet weitere Zeilen bis zum ";" einlesen
  • INSERT INTO kann sofort umgesetzt werden

Tabellen-Deklaration

Aus den ersten Versuchen und auch vorher schon hatte ich gelernt, daß 4D V11 sehr pingelig* ist bzgl. der Typdefinition. char(15) will es nicht, es muß für 4D V11 varchar(15) heißen, text ist als varchar ohne Längenangabe zu definieren. Auch sonst sind MySQL und 4D V11 bzgl. der SQL-Syntax unterschiedlicher Auffassung: default NULL kann die V11 nicht ab, ebensowenig KEY und TYPE=MyISAM.

Also muß die Tabellen-Deklaration, sobald sie eingelesen ist von allem bereinigt werden, an dem sich 4D stört. Dabei nutzte ich die Gelegenheit, den CREATE TABLE Befehl durch CREATE TABLE IF NOT EXISTS zu ersetzen, um den Import mehrfach in dieselbe 4D Struktur ausführen zu können und die Tabellen nur einmal zu erzeugen. Den KEY habe ich mir ganz geschenkt. Zusätzliche "," und ")" und doppelte Leerzeichen "  " werfen in 4D V11 SQL-Fehler und werden deshalb mitbereinigt.

: ($what="Bereinigen")  ` weil 4D mit dem SQL von MySQL nicht harmoniert
  $statementTxt:=$P_Self->
  $statementTxt:=Replace string($statementTxt;" CREATE TABLE";" CREATE TABLE IF NOT EXISTS")
  $statementTxt:=Replace string($statementTxt;" char";" varchar")
  $statementTxt:=Replace string($statementTxt;" text";" varchar")
  $statementTxt:=Replace string($statementTxt;" default NULL";"")
  $statementTxt:=Replace string($statementTxt;" TYPE=MyISAM";"")
  
  $pos_L:=Position("KEY";$statementTxt)
  While ($pos_L>0)
  End while
  
  $statementTxt:=Replace string($statementTxt;Char(Line feed );"")
  $statementTxt:=Replace string($statementTxt;Char(Carriage return );"")
  $statementTxt:=Replace string($statementTxt;" ";" ")
  $statementTxt:=Replace string($statementTxt;",)";")")
  $statementTxt:=Replace string($statementTxt;", )";")")
  $P_Self->:=$statementTxt

Der Rest ist einfach. Über EXECUTE IMMEDIATE wird die SQL-Deklaration umgesetzt. Das sieht dann so aus:
: ($what="Execute_Immediate")
  $statementTxt:=$P_Self->
  Begin SQL
    EXECUTE IMMEDIATE :$statementTxt;
  End SQL

SQL-Definition der Tabelle für 4D V11 bereinigen und Tabelle erzeugen, falls nötig, wird so aufgerufen:
SQL_Mngr ("Bereinigen";->$receivedSQLStatement)
ON ERR CALL("NoError")  `bei unbekannten Dumps in NorError einen Stoppunkt setzen
SQL_Mngr ("Execute_Immediate";->$receivedSQLStatement)
ON ERR CALL("")

Datenimport

Die Daten sind in einem einfachen, einzeiligen INSERT INTO abgelegt. Also so:
INSERT INTO _person VALUES ('RƒTES','Herr R‰tes','r‰t','','');
Eine Zeile einlesen RECEIVE PACKET($docRef;$receivedText;$stopChar)
und mit SQL_Mngr ("Execute_Immediate";->$receivedText) ausführen.

Zuerst war ich versucht, wie schon so häufig, die Zeichen oberhalb Ascii 127 mit einem eigenen Verfahren in MacRoman umzusetzen. Das ist inzwischen vereinfacht durch

USE CHARACTER SET

USE ASCII MAP heißt in der V11 USE CHARACTER SET("iso-8859-1";$importFilter_L) und kann mit einer Auswahl der IANA Namen verwendet werden. In diesem Falle für den Import "iso-8859-1" und für den Export USE CHARACTER SET("MacRoman";$exportFilter_L). Einfach - praktisch - gut.

sqlmngr

Performance

Hinreichend! Die großen Tabellen haben 700.000, 350.000 und 100.000 Datensätze. Der gesamte Import dauerte ca. 20 Minuten. BBEdit braucht zum Öffnen der Original-107 MB-Textdaten bereits einige Minuten.

Alles in einer Methode

Das Verfahren hat sich wieder bewährt. Alles was zu diesem Modul gehört

  • Menüaufruf
  • Prozeßstart
  • Formularmethode
  • Objektmethoden
  • interne Methodenaufrufe
  • Dienstleister
  • Management hierarchischer Listen
ist in einer Methode zusammengefasst und 1-2-3 Parameter decken ab, was gebraucht wird.

Dreaming of a rich-text-editor in 4D gilt analog für HTML-Editoren. Es ist mühsam, 4D Sprache in HTML darzustellen. Mit CSS und vorbereiteten Code-Schnipseln geht es, aber das Gelbe vom Ei ist es nicht. Besäße 4D einen Richtext-Editor – eingebaut oder über ein PlugIn, hätte ich mir schon lange geholfen. Von einem CSS-fähigen 4D Write wage ich gar nicht zu träumen :-)

* ich ziehe Pragmatismus vor. In meinem Code würde ich gegen char oder varchar prüfen und richtig reagieren, dito auf int und int32. Wahrscheinlich ist das zu einfach, zu sehr 4D gedacht.

Sie möchten den Sourcecode haben? Kein Problem! Überweisen Sie, was es Ihnen wert ist auf mein PayPal-Konto: info@mettre.de. Was ist denn üblich?

4D Themen: Berichte in Arbeit