Copyright | (c) Ole Krüger 2015-2016 |
---|---|
License | BSD3 |
Maintainer | Ole Krüger <ole@vprsm.de> |
Safe Haskell | None |
Language | Haskell2010 |
- data TableConstraint
- mkTable :: Name -> [TableConstraint] -> Q [Dec]
- data Row a = Row {}
- newtype Reference a = Reference Int64
- data Query = Query {
- queryStatement :: !ByteString
- queryParams :: ![Value]
- pgsq :: QuasiQuoter
- mkCreateQuery :: Name -> Q Exp
- data ResultError
- data ErrandError
- type Errand = ReaderT Connection (ExceptT ErrandError IO)
- runErrand :: Connection -> Errand a -> IO (Either ErrandError a)
- query :: Result a => Query -> Errand [a]
- query_ :: Query -> Errand ()
- insert :: Table a => a -> Errand (Reference a)
- find :: (Table a, HasID i) => i a -> Errand (Row a)
- update :: (Table a, HasID i) => i a -> a -> Errand ()
- delete :: (Table a, HasID i) => i a -> Errand ()
Tables
data TableConstraint Source
Options to mkTable
.
Unique [Name] | A combination of fields must be unique.
|
ForeignKey [Name] Name [Name] | A combination of fields references another combination of fields from a different table.
|
mkTable :: Name -> [TableConstraint] -> Q [Dec] Source
Implement Table
for a data type. The given type must fulfill these requirements:
- Data type
- No type context
- No type variables
- One record constructor with 1 or more fields
- All field types must have an instance of
Column
Example:
{-# LANGUAGE TemplateHaskell #-} module Movies where ... data Movie = Movie { movieTitle :: String, movieYear :: Int } deriving ShowmkTable
''Movie [] data Actor = Actor { actorName :: String, actorAge :: Int } deriving ShowmkTable
''Actor [] data MovieCast = MovieCast { movieCastMovie ::Reference
Movie, movieCastActor ::Reference
Actor } deriving ShowmkTable
''MovieCast []
Resolved row
Reference to a row
Queries
Query including statement and parameters.
Use the pgsq
quasi-quoter to conveniently create queries.
Query | |
|
Generate a Query
from a SQL statement.
Table and column names
All plain identifiers will be treated as Haskell names. They are going to be resolved to their
fully-qualified and quoted version. Beware, the use of names which don't refer to a table type
or field will likely result in unknown table or column errors. The associated table name of a
type is retrieved using describeTableName
.
If you don't want a name to be resolved use a quoted identifier.
Example:
{-# LANGUAGE QuasiQuotes #-} module MyModule where ... data Table = Table { myField :: Int }mkTable
''Table [] myQuery ::Query
myQuery = [pgsq
| SELECT * FROM Table WHERE myField > 1337 |]
The SQL statement associated with myQuery
will be:
SELECT * FROM "MyModule.Table" WHERE "MyModule.myField" > 1337
Variables
You can use reference variables with $myVariable
. The variable's type has to be an instance of
Column
, otherwise it cannot be attached as query parameter.
Example:
magicNumber :: Int magicNumber = 1337 myQuery ::Query
myQuery = [pgsq
| SELECT * FROM Table WHERE myField > $magicNumber |]
Row identifiers
Each instance of (
, Table
a) => Row
a(
and each row of the actual table inside the database
has an identifier value. These identifiers are used to reference specific rows. The identifier
column is exposed via the Table
a) => Reference
a&MyTable
pattern. Identifier field names are resolved using
describeTableIdentifier
.
Example:
[pgsq
| SELECT *
FROM TableA, TableB
WHERE refToB = &TableB |]
Note refToB
is a field of TableA
.
In different circumstances one would write such query as follows.
SELECT * FROM TableA a, Table b WHERE a.refToB = b.id
mkCreateQuery :: Name -> Q Exp Source
Generate a Query
which will create the table described my the given type.
Example:
data Table = Table { myField :: Int }mkTable
''Table [] ...query_
$(mkCreateQuery
''Table)
Errands
data ResultError Source
Error that occured during result processing
data ErrandError Source
Error during errand
type Errand = ReaderT Connection (ExceptT ErrandError IO) Source
An interaction with the database
runErrand :: Connection -> Errand a -> IO (Either ErrandError a) Source
Run an errand.
query :: Result a => Query -> Errand [a] Source
Execute a query and process its result set. It is essential that all fields required by the underlying result parser are present.
insert :: Table a => a -> Errand (Reference a) Source
Insert a row into the table and return a Reference
to the inserted row.