MySQL/MariaDB in Haskell

Seit einer Weile "arbeite" ich daran ein mittelgroßes Projekt in Haskell zu implementieren. Heute habe ich mich dazu mit der Datenbankanbindung beschäftigt. Dazu gibt es in Haskell HDBC [1]. HDBC erlaubt es euch, zusammen mit einem Driver für die entsprechende Datenbank einer Datenbank SQL-Anfragen zu stellen. Theoretisch soll sogar das Wechseln der Datenbank ziemlich schmerzlos funktionieren. HDBC an sich kann über die Paketquellen auf Raspbian installiert werden.

Das erste Problem ist allerdings HDBC-mysql zu installieren. Ich verwende dazu einen Raspberry Pi 3 mit Raspbian 8 Jessie. ghc existiert dafür zwar, aber es gibt keinen interaktiven Modus.

Zum Installieren von Paketen in Haskell gibt es das Tool cabal [2],[3]. Dh. als erstes muss das Paket 'cabal-install' mit apt-get nachinstalliert werden. Theoretisch sollte das Tool in der Lage sein, Pakete automatisch herunterzuladen und zu installieren, wenn ihr einen Namen eingebt. Dazu müsstet ihr dem Tool mitteilen, dass es ein Update seiner internen Datenbank machen soll. Als Repository verwendet das Tool standardmäßig hackage. Dafür hatten aber etwa 500 MB freier Arbeitsspeicher nicht mehr gereicht, nachdem das Tool also RAM und Swap vollgeschrieben hatte, wurde es während des Updatens von Linux beendet.

Danach meinte das Tool zwar, dass die entfernten und die lokalen Daten übereinstimmen HDBC-mysql konnte ich so aber dennoch nicht herunterladen. Also habe ich mich auf die Suche nach den Quellen dieses Pakets gemacht und unter [4] gefunden. Das Repository zu klonen und zu installieren hatte nicht funktioniert, also habe ich mir das letzte Release 0.6.6.1 heruntergeladen und entpackt.

Im Archiv enthalten ist unter anderem eine Setup.lhs und eine HDBC-mysql.cabal-Datei. Auf letztere kann ich dann endlich cabal anwenden:

cabal install HDCB-mysql.cabal

cabal lief nun problemlos durch und hat das Paket installiert. Nun kann HDBC-mysql benutzt werden. Folgender Code dient mir dafür als Testcode:

import Control.Monad 
import Database.HDBC 
import Database.HDBC.MySQL 

myshow :: [[SqlValue]] -> IO()
myshow [] = return ()
myshow (x:xs) = do putStrLn ( "Hello" )
                   myshow2 x
                   myshow xs

myshow2 :: [SqlValue] -> IO()
myshow2 [] = return ()
myshow2 (x:xs) = do putStrLn ( show x )
                    myshow2 xs

main :: IO()
main = do conn <- connectMySQL defaultMySQLConnectInfo { mysqlHost = "127.0.0.1", mysqlUser = "test", mysqlPassword = "t3stpasswort", mysqlDatabase="oettingergames" }
          rows <- quickQuery' conn "SELECT * FROM game" []
          myshow rows

quickQuery liefert [[SqlValue]] zurück, dh. eine Liste von Listen von SqlValue. Die inneren Listen deuten jeweils einen Datensatz an, dh. jedes Element einer inneren Liste ist eine Spalte in der Relation. Die äußere Liste umfasst also alle abgefragten Datensätze.

[1] https://hackage.haskell.org/package/HDBC-mysql
[2] https://www.haskell.org/cabal/
[3] https://www.haskell.org/cabal/users-guide/
[4] https://github.com/bos/hdbc-mysql

Letzte Bearbeitung: 01.04.2016 20:42