4
4
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5
5
{-# LANGUAGE MultiParamTypeClasses #-}
6
6
7
- module Database.PostgreSQL.TransactionalStore
7
+ module Database.PostgreSQL.Transaction
8
8
( PGTransaction
9
- , runPGTransaction
10
- , runPGTransaction '
9
+ , runPGTransactionT
10
+ , runPGTransactionT '
11
11
, runPGTransactionIO
12
12
, query
13
13
, query_
@@ -16,6 +16,7 @@ module Database.PostgreSQL.TransactionalStore
16
16
, executeMany
17
17
, returning
18
18
, queryHead
19
+ , queryOnly
19
20
, formatQuery
20
21
) where
21
22
@@ -26,6 +27,7 @@ import Control.Monad.Reader
26
27
import Control.Monad.Trans.Control
27
28
import Data.Int
28
29
import qualified Database.PostgreSQL.Simple as Postgres
30
+ import Database.PostgreSQL.Simple.FromField
29
31
import Database.PostgreSQL.Simple.FromRow
30
32
import Database.PostgreSQL.Simple.ToRow
31
33
import qualified Database.PostgreSQL.Simple.Transaction as Postgres.Transaction
@@ -43,36 +45,41 @@ newtype PGTransactionT m a =
43
45
44
46
type PGTransaction = PGTransactionT IO
45
47
46
- runPGTransaction' :: MonadBaseControl IO m
47
- => Postgres.Transaction. IsolationLevel
48
- -> PGTransactionT m a
49
- -> Postgres. Connection -> m a
50
- runPGTransaction' isolation (PGTransactionT pgTrans) conn =
48
+ runPGTransactionT' :: MonadBaseControl IO m
49
+ => Postgres.Transaction. IsolationLevel
50
+ -> PGTransactionT m a
51
+ -> Postgres. Connection
52
+ -> m a
53
+ runPGTransactionT' isolation (PGTransactionT pgTrans) conn =
51
54
let runTransaction run =
52
55
Postgres.Transaction. withTransactionLevel isolation conn (run pgTrans)
53
56
in control runTransaction `runReaderT` conn
54
57
55
- runPGTransaction :: MonadBaseControl IO m
56
- => PGTransactionT m a
57
- -> Postgres. Connection
58
- -> m a
59
- runPGTransaction = runPGTransaction ' Postgres.Transaction. DefaultIsolationLevel
58
+ runPGTransactionT :: MonadBaseControl IO m
59
+ => PGTransactionT m a
60
+ -> Postgres. Connection
61
+ -> m a
62
+ runPGTransactionT = runPGTransactionT ' Postgres.Transaction. DefaultIsolationLevel
60
63
61
64
62
65
-- | Convenience function when there are no embedded monadic effects, only IO.
63
66
runPGTransactionIO :: MonadIO m
64
67
=> PGTransaction a
65
68
-> Postgres. Connection
66
69
-> m a
67
- runPGTransactionIO = (liftIO . ) . runPGTransaction
70
+ runPGTransactionIO = (liftIO . ) . runPGTransactionT
68
71
69
72
70
73
-- | Issue an SQL query, taking a 'ToRow' input and yielding 'FromRow' outputs.
74
+ -- Please note that the parameter order is different from that in the parent
75
+ -- postgresql-simple library; this is an intentional choice to improve the aesthetics
76
+ -- when using the SQL quasiquoter (making the query parameters come first means that
77
+ -- there is more room for the query string).
71
78
query :: (ToRow input , FromRow output , MonadIO m )
72
- => Postgres. Query
73
- -> input
79
+ => input
80
+ -> Postgres. Query
74
81
-> PGTransactionT m [output ]
75
- query q params = ask >>= (\ conn -> liftIO $ Postgres. query conn q params)
82
+ query params q = ask >>= (\ conn -> liftIO $ Postgres. query conn q params)
76
83
77
84
-- | As 'query', but for queries that take no arguments.
78
85
query_ :: (FromRow output , MonadIO m )
@@ -82,30 +89,30 @@ query_ q = ask >>= liftIO . (`Postgres.query_` q)
82
89
83
90
-- | Run a single SQL action and return success.
84
91
execute :: (ToRow input , MonadIO m )
85
- => Postgres. Query
86
- -> input
92
+ => input
93
+ -> Postgres. Query
87
94
-> PGTransactionT m Int64
88
- execute q params = ask >>= (\ conn -> liftIO $ Postgres. execute conn q params)
95
+ execute params q = ask >>= (\ conn -> liftIO $ Postgres. execute conn q params)
89
96
90
97
executeMany :: (ToRow input , MonadIO m )
91
- => Postgres. Query
92
- -> [ input ]
98
+ => [ input ]
99
+ -> Postgres. Query
93
100
-> PGTransactionT m Int64
94
- executeMany q params = ask >>= (\ conn -> liftIO $ Postgres. executeMany conn q params)
101
+ executeMany params q = ask >>= (\ conn -> liftIO $ Postgres. executeMany conn q params)
95
102
96
103
returning :: (ToRow input , FromRow output , MonadIO m )
97
- => Postgres. Query
98
- -> [ input ]
104
+ => [ input ]
105
+ -> Postgres. Query
99
106
-> PGTransactionT m [output ]
100
- returning q params = ask >>= (\ conn -> liftIO $ Postgres. returning conn q params)
107
+ returning params q = ask >>= (\ conn -> liftIO $ Postgres. returning conn q params)
101
108
102
109
-- | Run a query and return 'Just' the first result found or 'Nothing'.
103
110
queryHead :: (ToRow input , FromRow output , MonadIO m )
104
111
=> input
105
112
-> Postgres. Query
106
113
-> PGTransactionT m (Maybe output )
107
114
queryHead params q = do
108
- results <- query q params
115
+ results <- query params q
109
116
return $ case results of
110
117
(a: _) -> Just a
111
118
_ -> Nothing
@@ -115,14 +122,19 @@ executeOne :: (ToRow input, MonadIO m)
115
122
=> input
116
123
-> Postgres. Query
117
124
-> PGTransactionT m Bool
118
- executeOne params q = do
119
- results <- execute q params
120
- return (results == 1 )
125
+ executeOne params q = (== 1 ) <$> execute params q
126
+
127
+ -- | Lookup a single FromField value. This takes care of handling 'Only' for you.
128
+ queryOnly :: (ToRow input , FromField f , MonadIO m )
129
+ => input
130
+ -> Postgres. Query
131
+ -> PGTransactionT m (Maybe f )
132
+ queryOnly params q = fmap Postgres. fromOnly <$> queryHead params q
121
133
122
- formatQuery :: (ToRow q , MonadIO m )
123
- => Postgres. Query
124
- -> q
134
+ formatQuery :: (ToRow input , MonadIO m )
135
+ => input
136
+ -> Postgres. Query
125
137
-> PGTransactionT m Postgres. Query
126
- formatQuery q params = do
138
+ formatQuery params q = do
127
139
conn <- ask
128
140
liftIO (PGTypes. Query <$> Postgres. formatQuery conn q params)
0 commit comments