@@ -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)
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)
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)
@@ -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{..}
@@ -159,22 +161,21 @@ disconnectedError = SqlError {
159 sqlState = ""
161 sqlState = ""
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
169− -- TODO: Use extensible exceptions.
170− Nothing -> throwIO disconnectedError
169+ then throwIO disconnectedError
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
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
180data RawResult = RawResult { rawField :: Field, rawData :: Maybe ByteString }
181data RawResult = RawResult { rawField :: Field, rawData :: Maybe ByteString }