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
|