-- |
-- This module defines the internal state of a database connection.
module Hasql.Engine.Structures.ConnectionState
  ( ConnectionState (..),
    toStatementCache,
    fromConnection,
    setPreparedStatements,
    setStatementCache,
    setConnection,
    setOidCache,
    mapStatementCache,
    mapOidCache,
    traverseStatementCache,
    resetPreparedStatementsCache,
  )
where

import Hasql.Engine.Structures.OidCache qualified as OidCache
import Hasql.Engine.Structures.StatementCache qualified as StatementCache
import Hasql.Platform.Prelude
import Hasql.Pq qualified as Pq

-- |
-- The internal state of a database connection.
data ConnectionState = ConnectionState
  { -- | Whether prepared statements are enabled.
    ConnectionState -> Bool
preparedStatements :: Bool,
    -- | The statement cache for prepared statements.
    ConnectionState -> StatementCache
statementCache :: StatementCache.StatementCache,
    -- | The OID cache for type name to OID mapping.
    ConnectionState -> OidCache
oidCache :: OidCache.OidCache,
    -- | The underlying database connection.
    ConnectionState -> Connection
connection :: Pq.Connection
  }

toStatementCache :: ConnectionState -> StatementCache.StatementCache
toStatementCache :: ConnectionState -> StatementCache
toStatementCache ConnectionState {Bool
Connection
OidCache
StatementCache
preparedStatements :: ConnectionState -> Bool
statementCache :: ConnectionState -> StatementCache
oidCache :: ConnectionState -> OidCache
connection :: ConnectionState -> Connection
preparedStatements :: Bool
statementCache :: StatementCache
oidCache :: OidCache
connection :: Connection
..} = StatementCache
statementCache

fromConnection :: Pq.Connection -> ConnectionState
fromConnection :: Connection -> ConnectionState
fromConnection Connection
connection =
  ConnectionState
    { preparedStatements :: Bool
preparedStatements = Bool
False,
      statementCache :: StatementCache
statementCache = StatementCache
StatementCache.empty,
      oidCache :: OidCache
oidCache = OidCache
OidCache.empty,
      connection :: Connection
connection = Connection
connection
    }

setPreparedStatements :: Bool -> ConnectionState -> ConnectionState
setPreparedStatements :: Bool -> ConnectionState -> ConnectionState
setPreparedStatements Bool
preparedStatements ConnectionState
connectionState =
  ConnectionState
connectionState {preparedStatements = preparedStatements}

setStatementCache :: StatementCache.StatementCache -> ConnectionState -> ConnectionState
setStatementCache :: StatementCache -> ConnectionState -> ConnectionState
setStatementCache StatementCache
statementCache ConnectionState
connectionState =
  ConnectionState
connectionState {statementCache = statementCache}

setConnection :: Pq.Connection -> ConnectionState -> ConnectionState
setConnection :: Connection -> ConnectionState -> ConnectionState
setConnection Connection
connection ConnectionState
connectionState =
  ConnectionState
connectionState {connection = connection}

setOidCache :: OidCache.OidCache -> ConnectionState -> ConnectionState
setOidCache :: OidCache -> ConnectionState -> ConnectionState
setOidCache OidCache
oidCache ConnectionState
connectionState =
  ConnectionState
connectionState {oidCache}

mapStatementCache ::
  (StatementCache.StatementCache -> StatementCache.StatementCache) ->
  (ConnectionState -> ConnectionState)
mapStatementCache :: (StatementCache -> StatementCache)
-> ConnectionState -> ConnectionState
mapStatementCache StatementCache -> StatementCache
f ConnectionState {Bool
Connection
OidCache
StatementCache
preparedStatements :: ConnectionState -> Bool
statementCache :: ConnectionState -> StatementCache
oidCache :: ConnectionState -> OidCache
connection :: ConnectionState -> Connection
preparedStatements :: Bool
statementCache :: StatementCache
oidCache :: OidCache
connection :: Connection
..} =
  ConnectionState
    { statementCache :: StatementCache
statementCache = StatementCache -> StatementCache
f StatementCache
statementCache,
      Bool
Connection
OidCache
preparedStatements :: Bool
oidCache :: OidCache
connection :: Connection
preparedStatements :: Bool
oidCache :: OidCache
connection :: Connection
..
    }

mapOidCache ::
  (OidCache.OidCache -> OidCache.OidCache) ->
  (ConnectionState -> ConnectionState)
mapOidCache :: (OidCache -> OidCache) -> ConnectionState -> ConnectionState
mapOidCache OidCache -> OidCache
f ConnectionState {Bool
Connection
OidCache
StatementCache
preparedStatements :: ConnectionState -> Bool
statementCache :: ConnectionState -> StatementCache
oidCache :: ConnectionState -> OidCache
connection :: ConnectionState -> Connection
preparedStatements :: Bool
statementCache :: StatementCache
oidCache :: OidCache
connection :: Connection
..} =
  ConnectionState
    { oidCache :: OidCache
oidCache = OidCache -> OidCache
f OidCache
oidCache,
      Bool
Connection
StatementCache
preparedStatements :: Bool
statementCache :: StatementCache
connection :: Connection
preparedStatements :: Bool
statementCache :: StatementCache
connection :: Connection
..
    }

traverseStatementCache ::
  (Functor f) =>
  (StatementCache.StatementCache -> f StatementCache.StatementCache) ->
  (ConnectionState -> f ConnectionState)
traverseStatementCache :: forall (f :: * -> *).
Functor f =>
(StatementCache -> f StatementCache)
-> ConnectionState -> f ConnectionState
traverseStatementCache StatementCache -> f StatementCache
f ConnectionState {Bool
Connection
OidCache
StatementCache
preparedStatements :: ConnectionState -> Bool
statementCache :: ConnectionState -> StatementCache
oidCache :: ConnectionState -> OidCache
connection :: ConnectionState -> Connection
preparedStatements :: Bool
statementCache :: StatementCache
oidCache :: OidCache
connection :: Connection
..} =
  (StatementCache -> ConnectionState)
-> f StatementCache -> f ConnectionState
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
    ( \StatementCache
newStatementCache ->
        ConnectionState
          { statementCache :: StatementCache
statementCache = StatementCache
newStatementCache,
            Bool
Connection
OidCache
preparedStatements :: Bool
oidCache :: OidCache
connection :: Connection
preparedStatements :: Bool
oidCache :: OidCache
connection :: Connection
..
          }
    )
    (StatementCache -> f StatementCache
f StatementCache
statementCache)

resetPreparedStatementsCache :: ConnectionState -> ConnectionState
resetPreparedStatementsCache :: ConnectionState -> ConnectionState
resetPreparedStatementsCache =
  (StatementCache -> StatementCache)
-> ConnectionState -> ConnectionState
mapStatementCache (StatementCache -> StatementCache -> StatementCache
forall a b. a -> b -> a
const StatementCache
StatementCache.empty)