Check whether connection succeeded and set encoding in connect

This commit is contained in:
2025-07-20 02:48:14 +02:00
parent 2fddc958b9
commit 3379fa9df7
4 changed files with 25 additions and 9 deletions
+21 -6
View File
@@ -1,8 +1,10 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
module Database.PostgreSQL.Opium.Connection
( Connection
, ConnectionError
, unsafeWithRawConnection
, withRawConnection
, connect
@@ -10,14 +12,20 @@ module Database.PostgreSQL.Opium.Connection
) where
import Control.Concurrent.MVar (MVar, newMVar, modifyMVar_, withMVar)
import Data.ByteString (ByteString)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import Database.PostgreSQL.LibPQ (ConnStatus (..))
import GHC.Stack (HasCallStack)
import qualified Data.Text.Encoding as Encoding
import qualified Database.PostgreSQL.LibPQ as LibPQ
newtype Connection = Connection
{ rawConnection :: MVar (Maybe LibPQ.Connection)
}
}
newtype ConnectionError = ConnectionError Text
deriving (Show)
withRawConnection
:: HasCallStack
@@ -35,11 +43,18 @@ unsafeWithRawConnection f = withRawConnection $ \case
Nothing -> error "raw connection is missing! perhaps the connection was already closed."
Just rawConn -> f rawConn
connect :: ByteString -> IO Connection
connect :: Text -> IO (Either ConnectionError Connection)
connect connectionString = do
rawConn <- LibPQ.connectdb connectionString
Connection <$> newMVar (Just rawConn)
-- Appending the client_encoding setting overrides any previous setting in the connection string.
-- We set the client encoding here to make sure we can use it below for decoding connection
-- error messages.
rawConn <- LibPQ.connectdb $ Encoding.encodeUtf8 $ connectionString <> " client_encoding=UTF8"
status <- LibPQ.status rawConn
if status == ConnectionOk then
Right . Connection <$> newMVar (Just rawConn)
else do
rawError <- fromMaybe "" <$> LibPQ.errorMessage rawConn
pure $ Left $ ConnectionError $ Encoding.decodeUtf8Lenient rawError
close :: Connection -> IO ()
close conn = modifyMVar_ conn.rawConnection $ \case