2022-01-14 17:08:17 +03:00
|
|
|
-- | MSSQL Connection Pooling
|
|
|
|
module Database.MSSQL.Pool
|
|
|
|
( -- * Types
|
|
|
|
ConnectionString (..),
|
|
|
|
ConnectionOptions (..),
|
|
|
|
MSSQLPool (..),
|
|
|
|
|
|
|
|
-- * Functions
|
|
|
|
initMSSQLPool,
|
|
|
|
drainMSSQLPool,
|
|
|
|
withMSSQLPool,
|
2022-10-17 11:04:54 +03:00
|
|
|
resizePool,
|
|
|
|
getInUseConnections,
|
2022-01-14 17:08:17 +03:00
|
|
|
)
|
|
|
|
where
|
|
|
|
|
2022-10-12 19:28:51 +03:00
|
|
|
import Autodocodec (HasCodec (codec), dimapCodec)
|
2022-01-14 17:08:17 +03:00
|
|
|
import Control.Exception.Lifted
|
|
|
|
import Control.Monad.Trans.Control
|
|
|
|
import Data.Aeson
|
|
|
|
import Data.Pool qualified as Pool
|
|
|
|
import Database.ODBC.SQLServer qualified as ODBC
|
|
|
|
import Hasura.Prelude (Generic, Text)
|
|
|
|
import Prelude
|
|
|
|
|
|
|
|
-- | ODBC connection string for MSSQL server
|
|
|
|
newtype ConnectionString = ConnectionString {unConnectionString :: Text}
|
|
|
|
deriving (Show, Eq, ToJSON, FromJSON, Generic)
|
|
|
|
|
2022-10-12 19:28:51 +03:00
|
|
|
instance HasCodec ConnectionString where
|
|
|
|
codec = dimapCodec ConnectionString unConnectionString codec
|
|
|
|
|
2022-01-14 17:08:17 +03:00
|
|
|
data ConnectionOptions = ConnectionOptions
|
|
|
|
{ _coConnections :: Int,
|
|
|
|
_coStripes :: Int,
|
|
|
|
_coIdleTime :: Int
|
|
|
|
}
|
|
|
|
deriving (Show, Eq)
|
|
|
|
|
|
|
|
-- | ODBC connection pool
|
|
|
|
newtype MSSQLPool = MSSQLPool (Pool.Pool ODBC.Connection)
|
|
|
|
|
|
|
|
-- | Initialize an MSSQL pool with given connection configuration
|
|
|
|
initMSSQLPool ::
|
|
|
|
ConnectionString ->
|
|
|
|
ConnectionOptions ->
|
|
|
|
IO MSSQLPool
|
|
|
|
initMSSQLPool (ConnectionString connString) ConnectionOptions {..} = do
|
|
|
|
MSSQLPool
|
|
|
|
<$> Pool.createPool
|
|
|
|
(ODBC.connect connString)
|
|
|
|
ODBC.close
|
|
|
|
_coStripes
|
|
|
|
(fromIntegral _coIdleTime)
|
|
|
|
_coConnections
|
|
|
|
|
|
|
|
-- | Destroy all pool resources
|
|
|
|
drainMSSQLPool :: MSSQLPool -> IO ()
|
|
|
|
drainMSSQLPool (MSSQLPool pool) =
|
|
|
|
Pool.destroyAllResources pool
|
|
|
|
|
|
|
|
withMSSQLPool ::
|
|
|
|
(MonadBaseControl IO m) =>
|
|
|
|
MSSQLPool ->
|
|
|
|
(ODBC.Connection -> m a) ->
|
|
|
|
m (Either ODBC.ODBCException a)
|
|
|
|
withMSSQLPool (MSSQLPool pool) action = do
|
|
|
|
try $ Pool.withResource pool action
|
2022-10-17 11:04:54 +03:00
|
|
|
|
|
|
|
-- | Resize a pool
|
|
|
|
resizePool :: MSSQLPool -> Int -> IO ()
|
|
|
|
resizePool (MSSQLPool pool) resizeTo = do
|
|
|
|
-- Resize the pool max resources
|
|
|
|
Pool.resizePool pool resizeTo
|
|
|
|
-- Trim pool by destroying excess resources, if any
|
|
|
|
Pool.tryTrimPool pool
|
|
|
|
|
|
|
|
getInUseConnections :: MSSQLPool -> IO Int
|
|
|
|
getInUseConnections (MSSQLPool pool) = Pool.getInUseResourceCount $ pool
|