From: Justin B. <jgb...@gm...> - 2009-04-10 16:13:55
|
All, I've just uploaded a set of Template Haskell utilities that make working with HaskellDB simpler. Download ======= http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haskelldb-th Repository ======== http://patch-tag.com/publicrepos/haskelldb-th Motivation ======= Because HaskellDB depends on statically typed tables and fields, normally you need to generate Haskell source from your database. This can be painful and makes simple scripts or tests hard to write. This package allows you to define tables, fields, and records using TH syntax, and HaskellDB can import those modules just like any other Haskell source. Examples ======= Two examples from the docs are given below, first for mkDBDirectTable and then for mkRecord. mkDBDirectTable will create a table definition with appropriate field definitions. From the haddock docs: -- | Creates definitions for a table and all its fields in the style of DBDirect. -- Takes a table name and a list of fields (as types). Generates -- a table type and a function to construct the table. The function -- will be the tablename in lower case. The type alias will -- be the table name with the first character capitalized. -- -- For example: -- -- > mkDBDirectTable "Table1" [("Col1", [t|Int|]) -- > , ("Col2", [t|Bool|])] -- -- Will produce -- -- > type Table1 = (RecCons Col1 (Expr Int) -- > (RecCons Col2 (Expr Bool))) -- > -- > table1 :: Table Table1 -- > table1 = baseTable "Table1" $ -- > hdbMakeEntry Col1 # -- > hdbMakeEntry Col2 -- > -- > data Col1 = Col1 -- > instance FieldTag Col1 where fieldName _ = "col1" -- > col1 :: Attr Col1 Int -- > col1 = mkAttr Col1 -- > -- > data Col2 = Col2 -- > instance FieldTag Col2 where fieldName _ = "col2" -- > col2 :: Attr Col2 Int -- > col2 = mkAttr Col2 -- mkRecord makes it simpler to construct queries combining columns from multiple tables: {- | Create a record from the list of tables and fields given. The first element of each tuple is a table. The second is a list of fields from that table which will be in the new record. The record will be constructed in the order of tables and fields given. This is a Template Haskell function which must be spliced in and is intended to use the @'@ (quote) facility for capturing names. An example: > import Status_v (Status_v, status_v) > import qualified Status_v as Status_v > > import Dtls_v (Dtls_v, dtls_v) > import qualified Dtls_v as Dtls_v > > > qry = do > status <- table status_v; > dtls <- table dtls_v; > project $(mkRecord [('dtls, ['Dtls_v.desc > , 'Dtls_v.hdr_id > , 'Dtls_v.prt_id > , 'Dtls_v.dtl_id]) > ,('status, ['Status_v.stat_nbr])]) The type of qry is then > (RecCons Dtls_v.Desc (Expr (Maybe BStr40)) > (RecCons Dtls_v.Hdr_id (Expr (Maybe Int)) > (RecCons Dtls_v.Prt_id (Expr (Maybe BStr30)) > (RecCons Dtls_v.Dtl_id (Expr (Maybe Int)) > (RecCons Status_v.Stat_nbr (Expr (Maybe Int)) RecNil)))))) If other fields need to be added to the record, they must come before the call to mkRecord: > project $ filtered << someTable ! someField # > $(mkRecord [('dtls, ['Dtls_v.prt_desc > , 'Dtls.hdr_id > , 'Dtls.prt_id > , 'Dtls.dtl_id]) > ,('status, ['Status_v.stat_nbr])]) -} Enjoy! Justin |