Gabi und Sascha
Kategorien : Alle | Berlin | Bücher | Fotografie | Java | Linkhalde | Weichware | Verfassung

Ich habe ein kleines Programm geschrieben, um CSV Dateien mit SQL Befehlen von der Kommenadozeile ad-hoc zu untersuchen: sql4csv. Ziel war es ein Query wie das folgende von der Bash Kommandozeile ab zu setzen:


    > scq select distinct author from books.csv

Das Ergebnis wird dann wieder in Form einer CSV Datei ausgegeben:


    author  
    Douglas Adams  
    Terry Pratchet

Bei der Entwicklung habe ich Wert auf einfache Verwendung gelegt. So soll es nicht nötig sein die Werttypen (integer, numeric oder Datumsangaben) der Spalten vor der Benutzung. Vielmehr soll dies das Tools möglichst selbst erkennen und die Spaltentypen entsprechend anpassen. Damit sollen auch Abfragen wie


    > scq select ABC from xyz.csv where VALUE < 10

möglich sind.

Für integer und numeric Typen ist das auch ohne grosse Probleme möglich. Kniffelig ist es bei Datums- und Zeitabgaben. Hier gibt es zig unterschiedliche Formate. Deswegen habe ich mich für einen pragmatischen Weg der Umsetzung entschieden: es werden aktuell die drei für mich wichtigsten Datumsformate für den Gregorianischen Kalender unterstützt :-)

Datums- und Zeitformate

  • Y - steht für das Jahr. Jahre werden immer vierstellig angegeben
  • M - steht für den Monat
  • D - steht für den Tag im Monat
  • h - steht für Stunden
  • m - steht für Minuten
  • s - steht für Sekunden

Datumsangaben

YYYY-MM-TT

ISO 8601 ähnlich.

Unterstützt wird auch eine sogenannte lazy Schreibweise, bei der auf einen führende Null (0) bei Zahlen unter 10 verzichtet werden kann. Dies bedeutet, dass auch ein Datum 2016-9-6 als 6. September 2016 erkannt wird.

MM/DD/YYYY

Amerikanische Datumsschreibweise.

Wie bei der ISO 8601 Schreibweise wird auch hier eine lazy Schreibweise ohne führende Null unterstützt.

DD.MM.YYYY

Entspricht der numerischen DIN 5008.

Wie bei der ISO 8601 Schreibweise wird auch hier eine lazy Schreibweise ohne führende Null unterstützt.

Zeitangaben

Zeiten werden immer mit einem Doppelpunkt getrennt. Dabei unterstützt sql4csv nur die Reihenfolge hh:mm:ss. Dieses Format allerdings auch lazy, also ohne führende Null und die Sekunde kann ebenfalls weggelassen werden. In diesem Fall wird die Sekunde intern auf Null gesetzt..

Zeitstempel

Zeitstempel sind eine Kombination aus Datum und Zeit. sql4csv erlaubt alle Kombinationen von Datums- und Zeitangaben. Dabei kann als Separator das ISO 8601 T verwendet werden oder ein Leerzeichen.

Beispiele

  • 2016-7-3 1:16
  • 8/30/1969T23:5:07
  • 11.11.2011 11:11:11

Implementierung

sql4csv wurde in Java 8 implementiert. Ich habe es auch geschrieben, um die neuen Sprachfeatures von Java 8 in der Praxis zu lernen und anzuwenden. So kommen intensiv Lambdas zum Einsatz und auch Methodenreferenzen. Die gesamte Datums- und Zeitbearbeitung basiert auf dem java.time API.

Als Datenbank verwende ich Derby als in-memory Datenbank. Ich verwende nicht SQLite - wie dies einige andere Implementierungen für ein solches Tool tun - da dies entweder eine vorhandene Installation von SQLite voraussetzt oder ich die Binaries für die unterschiedlichsten Plattformen mitliefern müsste. Das ist zu kompliziert und wird der Einfachheit des Werkzeuges nicht gerecht.

Probleme

SQL Queries und die Bash als Kommandozeileninterpreter vertragen sich nur mässig miteinander. Beispielsweise interpretiert die Bash das Asterisk Zeichen (*) anders als in SQL vorgesehen. Und diese Interpretation kann auch nicht einfach ausgeschaltet werden. Ein Query wie


    > scq select * from books.csv where author = 'Douglas Adams '

ist nicht möglich. Die Bash ersetzt das * Zeichen durch die Dateinamen des aktuellen Verzeichnisses. Als Abhilfe kann das Hilfstool scq-cols verwendet werden:


    > scq select $(scq-cols books.csv) from books.csv where author = 'Douglas Adams'

Das ist nicht schön, aber eine pragmatische Lösung. Nach einigen malen benutzen hatte ich mich daran gewöhnt.

Ebenso müssen runde Klammern (z.B. für Gruppierungen) und spitze Klammern <> für grösser und kleiner Vergleiche durch eine Backslash (\) maskiert werden. Insgesamt kann durch diese Einschränkungen die Lesbarkeit des Queries beeinträchtigt werden.

Download und Installation

Im sql4csv Repository auf Github findet ihr eine Download und Installationsanleitung, um das Tools selbst einmal ausprobieren zu können.