HaskellDB Datenbank-Features in Haskell 15.01.2013 Johannes Reiher Gliederung • • • • • Was ist HaskellDB? Installation ORM Funktionsweise Vor- und Nachteile 15.01.2013 Johannes Reiher Was ist HaskellDB? • Datenbank-Interface-Bibliothek • Ursprünglich für Hugs entwickelt • Ermöglicht SQL-Abfragen, Insert, Update und Delete - rein in Haskell geschrieben • Operationen basieren auf relationaler Algebra 15.01.2013 Johannes Reiher Installation • • • • HaskellDB-Paket HaskellDB-Connector (z.B. HDBC, ODBC) Datenbankserver (z.B. PostgreSQL, MySQL) Existierende Datenbank 15.01.2013 Johannes Reiher Connection module Publications.Model.Connect where import Database.HaskellDB.HDBC import Database.HaskellDB.Sql.PostgreSQL import Database.HDBC.PostgreSQL (connectPostgreSQL) withDB :: [(String,String)] -> (Database -> IO a) -> IO a withDB opts = hdbcConnect generator (connectPostgreSQL conninfo) where conninfo = unwords [ k ++ "=" ++ v | (k,v) <- opts ] opts = [("host","localhost") ,("user","your_username") ,("password","your_password") ,("dbname","your_db_name")] 15.01.2013 Johannes Reiher ORM - Begriffe • „Object-Relational-Mapping“ • Verbindung von Objektorientierung und SQL • Speicherung in Relationen – Datenbankobjekte • Aufbau durch strukturierte Datentypen • Möglichkeit der Strukturierung, Kapselung, Vererbung… 15.01.2013 Johannes Reiher ORM – Mapping von Feldern {-# LANGUAGE TemplateHaskell #-} -- | All database fields. module Publications.Model.Fields where import Database.HaskellDB.TH -- Keys. field "Id" "id" "id" [t|Int|] -- Data fields. field "Title" "title" "title" [t|String|] 15.01.2013 Johannes Reiher ORM – Mapping von Feldern field "Title" "title" "title" [t|String|] Name des Typs 15.01.2013 Name des Feldes Johannes Reiher Spaltenbezeichnung in der Datenbank ORM – Mapping von Tabellen {-# LANGUAGE TemplateHaskell #-} -- | Database tables and entities. module Publications.Model.Tables where import Publications.Model.Fields as Fields import Database.HaskellDB.TH import Prelude () -- | Content table. table "content" "content“ ['id ,'title ] 15.01.2013 Johannes Reiher ORM - Importe import qualified Publications.Model.Fields as F import qualified Publications.Model.Tables as T import Database.HaskellDB import Database.HaskellDB.HDBRec 15.01.2013 Johannes Reiher Abfragen simpleSelection = do table T.content simpleDoubleSelection = do table T.content table T.authors simpleProjection = do content <- table T.content project $ F.id << content!F.id simpleProjection2 = do content <- table T.content project $ F.id << content!F.id # F.title << content!F.title 15.01.2013 Johannes Reiher simpleRestriction = do content <- table T.content restrict $ content!F.title .==. constant "Coco Jambo" return content -- | Equality comparison on Exprs, = in SQL. (.==.) :: Eq a => Expr a -> Expr a -> Expr Bool -- | Inequality on Exprs, <> in SQL. (.<>.) :: Eq a => Expr a -> Expr a -> Expr Bool (.<.) :: Ord a => Expr a -> Expr a -> Expr Bool (.>=.) :: Ord a => Expr a -> Expr a -> Expr Bool -- | \"Logical and\" on 'Expr', AND in SQL. (.&&.):: Expr Bool -> Expr Bool -> Expr Bool -- | \"Logical or\" on 'Expr'. OR in SQL. (.||.) :: Expr Bool -> Expr Bool -> Expr Bool 15.01.2013 Johannes Reiher Beispiele SELECT X.FirstName, X.LastName FROM Authors AS X WHERE X.City = 'OakLand' oaklands = do{ x <- table authors ; restrict (x!city .==. constant "Oakland") ; project (au_fname = x!au_fname ,au_lname = x!au_lname) } 15.01.2013 Johannes Reiher Beispiele samecity = do{ x <- table authors ; y <- table authors ; restrict (x!au_id .<>. y!au_id) ; restrict (x!city .==. y!city) ; project (au_fname = x!au_fname ,au_lname = x!au_lname ,city = x!city) } 15.01.2013 Johannes Reiher SQL-Output λ> ppSqlUnOpt simpleSelection SELECT id, title FROM content as T1 λ> ppSqlUnOpt simpleProjection SELECT id as id1, title as title1 FROM content as T1 15.01.2013 Johannes Reiher Insert / Delete simpleInsert db = do insert db T.content ( F.id << constant 123 # F.title << constant “Lemon Tree") simpleDelete db = do delete db T.content (\content -> content!F.title .==. constant "Coco Jambo") Update analog „insert“ 15.01.2013 Johannes Reiher Vorteile • • • • • Exakte Syntaxprüfung durch Compiler SQL-Wissen wird nicht benötigt Alle Haskell-Features (lazy evaluation…) Plattformunabhängigkeit Felder der Datenbank können beliebig gemappt werden (keine Namensbindung) 15.01.2013 Johannes Reiher Nachteile • • • • Kryptische Fehlermeldungen bei einfachen Fehlern Abhängigkeit vom Datenbanksystem (SQL-Standard) Feldbezeichner können mehrmals verwendet werden Bei jeder Änderung des Datenbankschemas muss neu kompiliert werden 15.01.2013 Johannes Reiher Quellen • http://viblo.se/pmwiki/uploads/Projects/hask elldb.pdf • http://chrisdone.com/posts/haskelldb-tutorial • http://hackage.haskell.org/package/haskelldb • http://haskelldb.sourceforge.net/leijen/haskel lDB/example.html • http://www.itwissen.info/definition/lexikon/O bjektrelationale-Datenbank-object-relationaldatabase.html 15.01.2013 Johannes Reiher