Copyright | (c) Eitan Chatav 2017 |
---|---|
Maintainer | eitan@morphism.tech |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
This module is where Squeal commands actually get executed by
LibPQ
. It containts two typeclasses, IndexedMonadTransPQ
for executing
a Definition
and MonadPQ
for executing a Manipulation
or Query
,
and a PQ
type with instances for them.
Using Squeal in your application will come down to defining
the schema
of your database and including PQ schema schema
in your
application's monad transformer stack, giving it an instance of MonadPQ
.
This module also provides functions for retrieving rows from the Result
of executing Squeal commands.
- data Connection :: *
- connectdb :: forall schema io. MonadBase IO io => ByteString -> io (K Connection schema)
- finish :: MonadBase IO io => K Connection schema -> io ()
- withConnection :: forall schema0 schema1 io x. MonadBaseControl IO io => ByteString -> PQ schema0 schema1 io x -> io x
- lowerConnection :: K Connection (table ': schema) -> K Connection schema
- newtype PQ (schema0 :: TablesType) (schema1 :: TablesType) (m :: Type -> Type) (x :: Type) = PQ {
- unPQ :: K Connection schema0 -> m (K x schema1)
- runPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (x, K Connection schema1)
- execPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (K Connection schema1)
- evalPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m x
- class IndexedMonadTransPQ pq where
- class Monad pq => MonadPQ schema pq | pq -> schema where
- type PQRun schema = forall m x. Monad m => PQ schema schema m x -> m (K x schema)
- pqliftWith :: Functor m => (PQRun schema -> m a) -> PQ schema schema m a
- data Result :: *
- data Row :: *
- ntuples :: MonadBase IO io => K Result columns -> io Row
- getRow :: (FromRow columns y, MonadBase IO io) => Row -> K Result columns -> io y
- getRows :: (FromRow columns y, MonadBase IO io) => K Result columns -> io [y]
- nextRow :: (FromRow columns y, MonadBase IO io) => Row -> K Result columns -> Row -> io (Maybe (Row, y))
- firstRow :: (FromRow columns y, MonadBase IO io) => K Result columns -> io (Maybe y)
- liftResult :: MonadBase IO io => (Result -> IO x) -> K Result results -> io x
- data ExecStatus :: *
- resultStatus :: MonadBase IO io => K Result results -> io ExecStatus
- resultErrorMessage :: MonadBase IO io => K Result results -> io (Maybe ByteString)
Connection
:: MonadBase IO io | |
=> ByteString | conninfo |
-> io (K Connection schema) |
Makes a new connection to the database server.
This function opens a new database connection using the parameters taken from the string conninfo.
The passed string can be empty to use all default parameters, or it can contain one or more parameter settings separated by whitespace. Each parameter setting is in the form keyword = value. Spaces around the equal sign are optional. To write an empty value or a value containing spaces, surround it with single quotes, e.g., keyword = 'a value'. Single quotes and backslashes within the value must be escaped with a backslash, i.e., ' and .
To specify the schema you wish to connect with, use type application.
>>>
:set -XDataKinds
>>>
:set -XPolyKinds
>>>
:set -XTypeOperators
>>>
type Schema = '["tab" ::: '[] :=> '["col" ::: 'NoDef :=> 'Null 'PGint2]]
>>>
:set -XTypeApplications
>>>
:set -XOverloadedStrings
>>>
conn <- connectdb @Schema "host=localhost port=5432 dbname=exampledb"
Note that, for now, squeal doesn't offer any protection from connecting with the wrong schema!
finish :: MonadBase IO io => K Connection schema -> io () Source #
Closes the connection to the server.
withConnection :: forall schema0 schema1 io x. MonadBaseControl IO io => ByteString -> PQ schema0 schema1 io x -> io x Source #
lowerConnection :: K Connection (table ': schema) -> K Connection schema Source #
Safely lowerConnection
to a smaller schema.
PQ
newtype PQ (schema0 :: TablesType) (schema1 :: TablesType) (m :: Type -> Type) (x :: Type) Source #
We keep track of the schema via an Atkey indexed state monad transformer,
PQ
.
PQ | |
|
IndexedMonadTransPQ PQ Source # | |
(~) TablesType schema0 schema1 => MFunctor Type (PQ schema0 schema1) Source # | |
(MonadBase b m, (~) TablesType schema0 schema1) => MonadBase b (PQ schema0 schema1 m) Source # | |
(MonadBaseControl b m, (~) TablesType schema0 schema1) => MonadBaseControl b (PQ schema0 schema1 m) Source # | |
(MonadBase IO io, (~) TablesType schema0 schema, (~) TablesType schema1 schema) => MonadPQ schema (PQ schema0 schema1 io) Source # | |
(~) TablesType schema0 schema1 => MonadTrans (PQ schema0 schema1) Source # | |
(~) TablesType schema0 schema1 => MMonad (PQ schema0 schema1) Source # | |
(Monad m, (~) TablesType schema0 schema1) => Monad (PQ schema0 schema1 m) Source # | |
Monad m => Functor (PQ schema0 schema1 m) Source # | |
(Monad m, (~) TablesType schema0 schema1) => Applicative (PQ schema0 schema1 m) Source # | |
type StM (PQ schema0 schema1 m) x Source # | |
runPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (x, K Connection schema1) Source #
Run a PQ
and keep the result and the Connection
.
execPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m (K Connection schema1) Source #
Execute a PQ
and discard the result but keep the Connection
.
evalPQ :: Functor m => PQ schema0 schema1 m x -> K Connection schema0 -> m x Source #
Evaluate a PQ
and discard the Connection
but keep the result.
class IndexedMonadTransPQ pq where Source #
An Atkey indexed monad is a Functor
enriched category.
An indexed monad transformer transforms a Monad
into an indexed monad.
And, IndexedMonadTransPQ
is a class for indexed monad transformers that
support running Definition
s using define
and embedding a computation
in a larger schema using pqEmbed
.
pqAp :: Monad m => pq schema0 schema1 m (x -> y) -> pq schema1 schema2 m x -> pq schema0 schema2 m y Source #
indexed analog of <*>
pqJoin :: Monad m => pq schema0 schema1 m (pq schema1 schema2 m y) -> pq schema0 schema2 m y Source #
indexed analog of join
pqBind :: Monad m => (x -> pq schema1 schema2 m y) -> pq schema0 schema1 m x -> pq schema0 schema2 m y Source #
indexed analog of =<<
pqThen :: Monad m => pq schema1 schema2 m y -> pq schema0 schema1 m x -> pq schema0 schema2 m y Source #
indexed analog of flipped >>
pqEmbed :: Monad m => pq schema0 schema1 m x -> pq (table ': schema0) (table ': schema1) m x Source #
Safely embed a computation in a larger schema.
define :: MonadBase IO io => Definition schema0 schema1 -> pq schema0 schema1 io (K Result '[]) Source #
Run a Definition
with exec
, we expect that libpq obeys the law
define statement1 & pqThen (define statement2) = define (statement1 >>> statement2)
class Monad pq => MonadPQ schema pq | pq -> schema where Source #
MonadPQ
is an mtl
style constraint, similar to
MonadState
, for using LibPQ
to
manipulateParams
runs aManipulation
with params from a type with aToParams
constraint. It callsexecParams
and doesn't afraid of anything.manipulate
is likemanipulateParams
for a parameter-free statement.runQueryParams
is likemanipulateParams
for query statements.runQuery
is likerunQueryParams
for a parameter-free statement.traversePrepared
has the same type signature as a composition oftraverse
andmanipulateParams
but provides an optimization by preparing the statement withprepare
and then traversing aTraversable
container withexecPrepared
. The temporary prepared statement is then deallocated.forPrepared
is a flippedtraversePrepared
traversePrepared_
is liketraversePrepared
but works onFoldable
containers and returns unit.forPrepared_
is a flippedtraversePrepared_
.liftPQ
lets you lift actions fromLibPQ
that require a connection into your monad.
To define an instance, you can minimally define only manipulateParams
,
traversePrepared
, traversePrepared_
and liftPQ
. Monad transformers get
a default instance.
:: ToParams x params | |
=> Manipulation schema params ys | |
-> x | |
-> pq (K Result ys) |
:: (MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) | |
=> ToParams x params | |
=> Manipulation schema params ys | |
-> x | |
-> pq (K Result ys) |
manipulate :: Manipulation schema '[] ys -> pq (K Result ys) Source #
:: (ToParams x params, Traversable list) | |
=> Manipulation schema params ys |
|
-> list x | |
-> pq (list (K Result ys)) |
:: (MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) | |
=> (ToParams x params, Traversable list) | |
=> Manipulation schema params ys |
|
-> list x | |
-> pq (list (K Result ys)) |
:: (ToParams x params, Traversable list) | |
=> list x | |
-> Manipulation schema params ys | |
-> pq (list (K Result ys)) |
:: (ToParams x params, Foldable list) | |
=> Manipulation schema params '[] | |
-> list x | |
-> pq () |
:: (MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) | |
=> (ToParams x params, Foldable list) | |
=> Manipulation schema params '[] | |
-> list x | |
-> pq () |
:: (ToParams x params, Foldable list) | |
=> list x | |
-> Manipulation schema params '[] | |
-> pq () |
liftPQ :: (Connection -> IO a) -> pq a Source #
liftPQ :: (MonadTrans t, MonadPQ schema pq1, pq ~ t pq1) => (Connection -> IO a) -> pq a Source #
MonadPQ schema m => MonadPQ schema (ListT m) Source # | |
MonadPQ schema m => MonadPQ schema (MaybeT m) Source # | |
MonadPQ schema m => MonadPQ schema (ExceptT e m) Source # | |
(Monoid w, MonadPQ schema m) => MonadPQ schema (WriterT w m) Source # | |
(Monoid w, MonadPQ schema m) => MonadPQ schema (WriterT w m) Source # | |
MonadPQ schema m => MonadPQ schema (StateT s m) Source # | |
MonadPQ schema m => MonadPQ schema (StateT s m) Source # | |
MonadPQ schema m => MonadPQ schema (IdentityT * m) Source # | |
MonadPQ schema m => MonadPQ schema (ContT * r m) Source # | |
MonadPQ schema m => MonadPQ schema (ReaderT * r m) Source # | |
(MonadBase IO io, (~) TablesType schema0 schema, (~) TablesType schema1 schema) => MonadPQ schema (PQ schema0 schema1 io) Source # | |
MonadBaseControl IO io => MonadPQ schema (PoolPQ * schema io) Source # | |
(Monoid w, MonadPQ schema m) => MonadPQ schema (RWST r w s m) Source # | |
(Monoid w, MonadPQ schema m) => MonadPQ schema (RWST r w s m) Source # | |
type PQRun schema = forall m x. Monad m => PQ schema schema m x -> m (K x schema) Source #
A snapshot of the state of a PQ
computation.
pqliftWith :: Functor m => (PQRun schema -> m a) -> PQ schema schema m a Source #
Helper function in defining MonadBaseControl
instance for PQ
.
Result
ntuples :: MonadBase IO io => K Result columns -> io Row Source #
Returns the number of rows (tuples) in the query result.
Get a row corresponding to a given row number from a Result
,
throwing an exception if the row number is out of bounds.
Get all rows from a Result
.
Get the first row if possible from a Result
.
liftResult :: MonadBase IO io => (Result -> IO x) -> K Result results -> io x Source #
Lifts actions on results from LibPQ
.
data ExecStatus :: * #
EmptyQuery | The string sent to the server was empty. |
CommandOk | Successful completion of a command returning no data. |
TuplesOk | Successful completion of a command returning data (such as a SELECT or SHOW). |
CopyOut | Copy Out (from server) data transfer started. |
CopyIn | Copy In (to server) data transfer started. |
CopyBoth | Copy In/Out data transfer started. |
BadResponse | The server's response was not understood. |
NonfatalError | A nonfatal error (a notice or warning) occurred. |
FatalError | A fatal error occurred. |
SingleTuple | The PGresult contains a single result tuple from the current command. This status occurs only when single-row mode has been selected for the query. |
resultStatus :: MonadBase IO io => K Result results -> io ExecStatus Source #
Returns the result status of the command.
resultErrorMessage :: MonadBase IO io => K Result results -> io (Maybe ByteString) Source #
Returns the error message most recently generated by an operation on the connection.