git.iko.soy/typeable/postgresql-simple
on master help sign in
Remove a layer of indirection
efb67baLeon P Smith
postgresql-simple.cabal+1−1
@@ -39,7 +39,7 @@ Library
39 blaze-textual,
39 blaze-textual,
40 bytestring >= 0.9,
40 bytestring >= 0.9,
41 containers,
41 containers,
42− postgresql-libpq >= 0.6,
42+ postgresql-libpq >= 0.6.2,
43 pcre-light,
43 pcre-light,
44 old-locale,
44 old-locale,
45 template-haskell,
45 template-haskell,
src/Database/PostgreSQL/Simple/Internal.hs+15−14
@@ -15,6 +15,8 @@ import Data.Word
15import Database.PostgreSQL.LibPQ(Oid(..))
15import Database.PostgreSQL.LibPQ(Oid(..))
16import qualified Database.PostgreSQL.LibPQ as PQ
16import qualified Database.PostgreSQL.LibPQ as PQ
17import Database.PostgreSQL.Simple.BuiltinTypes (BuiltinType)
17import Database.PostgreSQL.Simple.BuiltinTypes (BuiltinType)
18+import Foreign.ForeignPtr (newForeignPtr_, unsafeForeignPtrToPtr)
19+import Foreign.Ptr (nullPtr)
18import System.IO.Unsafe (unsafePerformIO)
20import System.IO.Unsafe (unsafePerformIO)
19
21
20-- | A Field represents metadata about a particular field
22-- | A Field represents metadata about a particular field
@@ -49,7 +51,7 @@ typeOid Field{..} = unsafePerformIO (PQ.ftype result column)
49
51
50
52
51data Connection = Connection {
53data Connection = Connection {
52− connectionHandle :: MVar (Maybe PQ.Connection)
54+ connectionHandle :: MVar PQ.Connection
53 , connectionObjects :: MVar (IntMap.IntMap ByteString)
55 , connectionObjects :: MVar (IntMap.IntMap ByteString)
54 }
56 }
55
57
@@ -93,7 +95,7 @@ connectPostgreSQL connstr = do
93 stat <- PQ.status conn
95 stat <- PQ.status conn
94 case stat of
96 case stat of
95 PQ.ConnectionOk -> do
97 PQ.ConnectionOk -> do
96− connectionHandle <- newMVar (Just conn)
98+ connectionHandle <- newMVar conn
97 connectionObjects <- newMVar (IntMap.empty)
99 connectionObjects <- newMVar (IntMap.empty)
98 return Connection{..}
100 return Connection{..}
99 _ -> do
101 _ -> do
@@ -159,22 +161,21 @@ disconnectedError = SqlError {
159 sqlState = ""
161 sqlState = ""
160 }
162 }
161
163
162−
163-- | Atomically perform an action with the database handle, if there is one.
164-- | Atomically perform an action with the database handle, if there is one.
164withConnection :: Connection -> (PQ.Connection -> IO a) -> IO a
165withConnection :: Connection -> (PQ.Connection -> IO a) -> IO a
165withConnection Connection{..} m = do
166withConnection Connection{..} m = do
166− withMVar connectionHandle $ \h -> do
167+ withMVar connectionHandle $ \conn -> do
167− case h of
168+ if PQ.isNullConnection conn
168− Just h -> m h
169− -- TODO: Use extensible exceptions.
170− Nothing -> throwIO disconnectedError
169+ then throwIO disconnectedError
170+ else m conn
171
171
172close :: Connection -> IO ()
172close :: Connection -> IO ()
173−close Connection{..} = do
173+close Connection{..} =
174+ mask $ \restore -> (do
174− mconn <- takeMVar connectionHandle
175+ conn <- takeMVar connectionHandle
175− case mconn of
176− Just conn -> PQ.finish conn
176+ restore (PQ.finish conn)
177− Nothing -> return ()
177+ `finally` do
178− `finally` putMVar connectionHandle Nothing
178+ putMVar connectionHandle =<< PQ.newNullConnection
179+ )
179
180
180data RawResult = RawResult { rawField :: Field, rawData :: Maybe ByteString }
181data RawResult = RawResult { rawField :: Field, rawData :: Maybe ByteString }