Avoid double-closing the connection

This commit is contained in:
2025-07-15 23:22:52 +02:00
parent d17865265a
commit 9a2dbbd3cc
3 changed files with 27 additions and 14 deletions
+19 -8
View File
@@ -1,4 +1,5 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
module Database.PostgreSQL.Opium.Connection
( Connection
@@ -8,24 +9,28 @@ module Database.PostgreSQL.Opium.Connection
, close
) where
import Control.Concurrent.MVar (MVar, newMVar, modifyMVar_, withMVar)
import Data.ByteString (ByteString)
import GHC.Stack (HasCallStack)
import qualified Database.PostgreSQL.LibPQ as LibPQ
newtype Connection = Connection LibPQ.Connection
newtype Connection = Connection
{ rawConnection :: MVar (Maybe LibPQ.Connection)
}
withRawConnection
:: (Maybe LibPQ.Connection -> m a)
:: HasCallStack
=> (Maybe LibPQ.Connection -> IO a)
-> Connection
-> m a
withRawConnection f (Connection rawConn) = f (Just rawConn)
-> IO a
withRawConnection f conn = withMVar conn.rawConnection f
unsafeWithRawConnection
:: HasCallStack
=> (LibPQ.Connection -> m a)
=> (LibPQ.Connection -> IO a)
-> Connection
-> m a
-> IO a
unsafeWithRawConnection f = withRawConnection $ \case
Nothing -> error "raw connection is missing! perhaps the connection was already closed."
Just rawConn -> f rawConn
@@ -33,7 +38,13 @@ unsafeWithRawConnection f = withRawConnection $ \case
connect :: ByteString -> IO Connection
connect connectionString = do
rawConn <- LibPQ.connectdb connectionString
pure $ Connection rawConn
Connection <$> newMVar (Just rawConn)
close :: Connection -> IO ()
close (Connection rawConn) = LibPQ.finish rawConn
close conn = modifyMVar_ conn.rawConnection $ \case
Just rawConn -> do
LibPQ.finish rawConn
pure Nothing
Nothing ->
pure Nothing