@@ -1,26 +1,22 @@
1{-# LANGUAGE
1{-# LANGUAGE
3− , DeriveFunctor
2+ DeriveFunctor
4 , FlexibleContexts
3 , FlexibleContexts
5 , FlexibleInstances
4 , FlexibleInstances
6 , MultiParamTypeClasses
5 , MultiParamTypeClasses
8 , RankNTypes
6 , RankNTypes
10 , ScopedTypeVariables
7 , ScopedTypeVariables
11 , TypeApplications
8 , TypeApplications
12 , TypeFamilies
9 , TypeFamilies
13 , TypeOperators
11 , TypeOperators
14 , UndecidableInstances
12 , UndecidableInstances
17module Squeel.PostgreSQL.PQ where
15module Squeel.PostgreSQL.PQ where
20import Control.Exception.Lifted
17import Control.Exception.Lifted
21import Control.Monad.Base
18import Control.Monad.Base
22−import Control.Monad.Indexed
19+import Control.Monad.Trans
23−import Control.Monad.Indexed.Trans
24import Control.Monad.Trans.Control
20import Control.Monad.Trans.Control
25import Data.ByteString (ByteString)
21import Data.ByteString (ByteString)
26import Data.Proxy
22import Data.Proxy
@@ -36,57 +32,118 @@ import Squeel.PostgreSQL.Type
37newtype Connection db = Connection { unConnection :: LibPQ.Connection }
33newtype Connection db = Connection { unConnection :: LibPQ.Connection }
39−newtype PQ m db0 db1 x = PQ
35+newtype PQ (db0 :: [Table]) (db1 :: [Table]) m x = PQ
40 { runPQ :: Connection db0 -> m (x, Connection db1) }
36 { runPQ :: Connection db0 -> m (x, Connection db1) }
41 deriving Functor
37 deriving Functor
43−evalPQ :: Functor m => PQ m db0 db1 x -> Connection db0 -> m x
39+evalPQ :: Functor m => PQ db0 db1 m x -> Connection db0 -> m x
44evalPQ (PQ pq) = fmap fst . pq
40evalPQ (PQ pq) = fmap fst . pq
46−execPQ :: Functor m => PQ m db0 db1 x -> Connection db0 -> m (Connection db1)
42+execPQ :: Functor m => PQ db0 db1 m x -> Connection db0 -> m (Connection db1)
47execPQ (PQ pq) = fmap snd . pq
43execPQ (PQ pq) = fmap snd . pq
49−instance Functor m => IxFunctor (PQ m) where
45+class MonadPQ pq where
50− imap f (PQ g) = PQ $ fmap (first f) . g
46+
52−instance Applicative m => IxPointed (PQ m) where
48+ :: Monad m
53− ireturn x = PQ $ \ conn -> pure (x, conn)
49+ => pq db0 db1 m (x -> y)
55−instance Monad m => IxApplicative (PQ m) where
51+ -> pq db0 db2 m y
55+ => (x -> pq db1 db2 m y)
61+ => Query db0 db1 '[] xs
62+ -> pq db0 db1 io (Maybe (Result xs))
65+ :: (MonadBase IO io, ToValues xs ps, ToOids ps)
66+ => Query db0 db1 ps ys
68+ -> pq db0 db1 io (Maybe (Result ys))
71+ :: (MonadBase IO io, ToOids ps)
73+ -> Query db0 db1 ps xs
74+ -> pq db0 db1 io (Maybe (Result []), PreparedQuery db0 db1 ps xs)
77+ :: (MonadBase IO io, ToValues xs ps)
78+ => PreparedQuery db0 db1 ps ys
80+ -> pq db0 db1 io (Maybe (Result ys))
82+instance MonadPQ PQ where
56− iap (PQ f) (PQ x) = PQ $ \ conn -> do
84+ pqAp (PQ f) (PQ x) = PQ $ \ conn -> do
57 (f', conn') <- f conn
85 (f', conn') <- f conn
58 (x', conn'') <- x conn'
86 (x', conn'') <- x conn'
59 return (f' x', conn'')
87 return (f' x', conn'')
61−instance Monad m => Applicative (PQ m db db) where
65−instance Monad m => IxMonad (PQ m) where
66− ibind f (PQ x) = PQ $ \ conn -> do
89+ pqBind f (PQ x) = PQ $ \ conn -> do
67 (x', conn') <- x conn
90 (x', conn') <- x conn
68 runPQ (f x') conn'
91 runPQ (f x') conn'
70−instance Monad m => Monad (PQ m db db) where
93+ pqExec (Query q) = PQ $ \ (Connection conn) -> do
71− return = ireturn
94+ result <- liftBase $ LibPQ.exec conn q
72− (>>=) = flip ibind
95+ return (Result <$> result, Connection conn)
97+ pqExecParams (Query q :: Query db0 db1 ps ys) params =
98+ PQ $ \ (Connection conn) -> do
101+ [ Just (oid, param, LibPQ.Binary)
103+ zip (toOids (Proxy @ps)) (toValues (Proxy @ps) params)
105+ result <- liftBase $ LibPQ.execParams conn q params' LibPQ.Binary
106+ return (Result <$> result, Connection conn)
108+ pqPrepare statementName (Query q :: Query db0 db1 ps ys) =
109+ PQ $ \ (Connection conn) -> do
110+ result <- liftBase $
111+ LibPQ.prepare conn statementName q (Just (toOids (Proxy @ps)))
112+ return ((Result <$> result,PreparedQuery statementName), Connection conn)
114+ pqExecPrepared (PreparedQuery q :: PreparedQuery db0 db1 ps ys) params =
115+ PQ $ \ (Connection conn) -> do
118+ [Just (param, LibPQ.Binary) | param <- toValues (Proxy @ps) params]
119+ result <- liftBase $
120+ LibPQ.execPrepared conn q params' LibPQ.Binary
121+ return (Result <$> result, Connection conn)
123+instance Monad m => Applicative (PQ db db m) where
124+ pure x = PQ $ \ conn -> pure (x, conn)
74−instance IxMonadTrans PQ where
127+instance Monad m => Monad (PQ db db m) where
131+instance MonadTrans (PQ db db) where
75− ilift m = PQ $ \ conn -> do
132+ lift m = PQ $ \ conn -> do
77 return (x, conn)
134 return (x, conn)
79−instance MonadBase b m => MonadBase b (PQ m db db) where
136+instance MonadBase b m => MonadBase b (PQ db db m) where
80− liftBase = ilift . liftBase
137+ liftBase = lift . liftBase
82−type PQRun db = forall m x. Monad m => PQ m db db x -> m (x, Connection db)
139+type PQRun db = forall m x. Monad m => PQ db db m x -> m (x, Connection db)
84−pqliftWith :: Functor m => (PQRun db -> m a) -> PQ m db db a
141+pqliftWith :: Functor m => (PQRun db -> m a) -> PQ db db m a
85pqliftWith f = PQ $ \ conn ->
142pqliftWith f = PQ $ \ conn ->
86 fmap (\ x -> (x, conn)) (f $ \ pq -> runPQ pq conn)
143 fmap (\ x -> (x, conn)) (f $ \ pq -> runPQ pq conn)
88−instance MonadBaseControl b m => MonadBaseControl b (PQ m db db) where
145+instance MonadBaseControl b m => MonadBaseControl b (PQ db db m) where
89− type StM (PQ m db db) x = StM m (x, Connection db)
146+ type StM (PQ db db m) x = StM m (x, Connection db)
90 liftBaseWith f =
147 liftBaseWith f =
91 pqliftWith $ \ run -> liftBaseWith $ \ runInBase -> f $ runInBase . run
148 pqliftWith $ \ run -> liftBaseWith $ \ runInBase -> f $ runInBase . run
92 restoreM = PQ . const . restoreM
149 restoreM = PQ . const . restoreM
@@ -107,55 +164,6 @@ withConnection connString action =
108newtype Result xs = Result { unResult :: LibPQ.Result }
165newtype Result xs = Result { unResult :: LibPQ.Result }
112− => Query db0 db1 '[] xs
113− -> PQ io db0 db1 (Maybe (Result xs))
114−exec (Query q) = PQ $ \ (Connection conn) -> do
115− result <- liftBase $ LibPQ.exec conn q
116− return (Result <$> result, Connection conn)
119− :: (MonadBase IO io, ToValues xs ps, ToOids ps)
120− => Query db0 db1 ps ys
122− -> PQ io db0 db1 (Maybe (Result ys))
123−execParams (Query q :: Query db0 db1 ps ys) params =
124− PQ $ \ (Connection conn) -> do
127− [ Just (oid, param, LibPQ.Binary)
129− zip (toOids (Proxy @ps)) (toValues (Proxy @ps) params)
131− result <- liftBase $ LibPQ.execParams conn q params' LibPQ.Binary
132− return (Result <$> result, Connection conn)
135− :: (MonadBase IO io, ToOids ps)
137− -> Query db0 db1 ps xs
138− -> PQ io db0 db0 (Maybe (Result []), PreparedQuery db0 db1 ps xs)
139−prepare statementName (Query q :: Query db0 db1 ps ys) =
140− PQ $ \ (Connection conn) -> do
141− result <- liftBase $
142− LibPQ.prepare conn statementName q (Just (toOids (Proxy @ps)))
143− return ((Result <$> result,PreparedQuery statementName), Connection conn)
146− :: (MonadBase IO io, ToValues xs ps)
147− => PreparedQuery db0 db1 ps ys
149− -> PQ io db0 db1 (Maybe (Result ys))
150−execPrepared (PreparedQuery q :: PreparedQuery db0 db1 ps ys) params =
151− PQ $ \ (Connection conn) -> do
154− [Just (param, LibPQ.Binary) | param <- toValues (Proxy @ps) params]
155− result <- liftBase $
156− LibPQ.execPrepared conn q params' LibPQ.Binary
157− return (Result <$> result, Connection conn)
159newtype RowNumber = RowNumber { unRowNumber :: LibPQ.Row }
167newtype RowNumber = RowNumber { unRowNumber :: LibPQ.Row }
161newtype ColumnNumber cs c = ColumnNumber { unColumnNumber :: LibPQ.Column }
169newtype ColumnNumber cs c = ColumnNumber { unColumnNumber :: LibPQ.Column }