Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add MonadSql, MonadSqlTx #128

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.10.2.0...main)
## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.10.3.0...main)

## [v1.10.3.0](https://github.com/freckle/freckle-app/compare/v1.10.2.0...v1.10.3.0)

- Add classes `MonadSqlBackend` and `MonadSqlTx` for being quite nonspecific about the
context in which you interact with a SQL database.

chris-martin marked this conversation as resolved.
Show resolved Hide resolved
## [v1.10.2.0](https://github.com/freckle/freckle-app/compare/v1.10.1.0...v1.10.2.0)

Expand Down
2 changes: 1 addition & 1 deletion freckle-app.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cabal-version: 1.18
-- see: https://github.com/sol/hpack

name: freckle-app
version: 1.10.2.0
version: 1.10.3.0
synopsis: Haskell application toolkit used at Freckle
description: Please see README.md
category: Utils
Expand Down
6 changes: 6 additions & 0 deletions library/Freckle/App.hs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ instance (Monad m, HasTracer app) => MonadTracer (AppT app m) where
instance Applicative m => XRay.MonadTracer (AppT app m) where
getVaultData = pure Nothing

instance
(MonadUnliftIO m, HasSqlPool app, HasStatsClient app, HasTracer app)
=> MonadSqlTx (ReaderT SqlBackend (AppT app m)) (AppT app m)
where
runSqlTx = runDB

runAppT :: (MonadUnliftIO m, HasLogger app) => AppT app m a -> app -> m a
runAppT action app =
runResourceT $ runLoggerLoggingT app $ runReaderT (unAppT action) app
47 changes: 44 additions & 3 deletions library/Freckle/App/Database.hs
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TypeOperators #-}

-- | Database access for your @App@
module Freckle.App.Database
( MonadTracer
( -- * Running transactions
MonadSqlTx (..)
, runDB
, runDBSimple

-- * Running queries
, SqlBackend
, HasSqlBackend (..)
, MonadSqlBackend (..)
, liftSql

-- * Telemetry
, MonadTracer
, HasStatsClient

-- * Connection pools
, HasSqlPool (..)
, SqlPool
, makePostgresPool
, makePostgresPoolWith
, runDB
, runDBSimple

-- * Setup
, PostgresConnectionConf (..)
, PostgresPasswordSource (..)
, PostgresPassword (..)
Expand Down Expand Up @@ -60,6 +75,32 @@ import UnliftIO.Exception (displayException)
import UnliftIO.IORef
import Yesod.Core.Types (HandlerData (..), RunHandlerEnv (..))

-- | A monadic context in which a SQL backend is available
-- for running database queries
class MonadIO m => MonadSqlBackend m where
getSqlBackendM :: m SqlBackend

instance (HasSqlBackend r, MonadIO m) => MonadSqlBackend (ReaderT r m) where
getSqlBackendM = asks getSqlBackend

-- | Generalize from 'SqlPersistT' to 'MonadSqlBackend'
liftSql :: MonadSqlBackend m => ReaderT SqlBackend m a -> m a
liftSql (ReaderT f) = getSqlBackendM >>= f

-- | The constraint @'MonadSqlTx' db m@ indicates that @m@ is a monadic
-- context that can run @db@ actions, usually as a SQL transaction.
-- Typically, this means that @db@ needs a connection and @m@ can
-- provide one, e.g. from a connection pool.
class (MonadSqlBackend db, MonadUnliftIO m) => MonadSqlTx db m | m -> db where
-- | Runs the action in a SQL transaction
runSqlTx :: HasCallStack => db a -> m a

class HasSqlBackend a where
getSqlBackend :: a -> SqlBackend

instance HasSqlBackend SqlBackend where
getSqlBackend = id
chris-martin marked this conversation as resolved.
Show resolved Hide resolved

type SqlPool = Pool SqlBackend

class HasSqlPool app where
Expand Down
27 changes: 18 additions & 9 deletions library/Freckle/App/Database/XRay.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,28 @@

-- | Legacy version of "Freckle.App.Database" that still uses XRay
module Freckle.App.Database.XRay
( MonadTracer (..)
( -- * Running transactions
MonadSqlTx (..)
, runDB
, runDBSimple

-- * Running queries
, SqlBackend
, HasSqlBackend (..)
, MonadSqlBackend (..)
, liftSql

-- * Telemetry
, MonadTracer (..)
, HasStatsClient

-- * Connection pools
, HasSqlPool (..)
, SqlPool
, makePostgresPool
, makePostgresPoolWith
, runDB
, runDBSimple

-- * Setup
, PostgresConnectionConf (..)
, PostgresPasswordSource (..)
, PostgresPassword (..)
Expand All @@ -25,12 +39,7 @@ import Freckle.App.Prelude
import Control.Monad.IO.Unlift (MonadUnliftIO (..))
import Control.Monad.Reader
import Data.Pool
import Database.Persist.Postgresql
( SqlBackend
, SqlPersistT
, runSqlConn
, runSqlPool
)
import Database.Persist.Postgresql (SqlPersistT, runSqlConn, runSqlPool)
import Freckle.App.Database hiding (MonadTracer, runDB)
import qualified Freckle.App.Stats as Stats
import Network.AWS.XRayClient.Persistent
Expand Down
13 changes: 12 additions & 1 deletion library/Freckle/App/Test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ import Control.Monad.Random (MonadRandom (..))
import Control.Monad.Reader
import Control.Monad.Trans.Control
import Database.Persist.Sql (SqlPersistT, runSqlPool)
import Freckle.App.Database (HasSqlPool (..))
import Freckle.App.Database
( HasSqlPool (..)
, HasStatsClient
, MonadSqlTx (..)
, runDB
)
import qualified Freckle.App.Database.XRay as XRay
import qualified Freckle.App.Dotenv as Dotenv
import Freckle.App.OpenTelemetry
Expand Down Expand Up @@ -125,6 +130,12 @@ instance HasTracer app => MonadTracer (AppExample app) where
instance XRay.MonadTracer (AppExample app) where
getVaultData = pure Nothing

instance
(HasSqlPool app, HasStatsClient app, HasTracer app)
=> MonadSqlTx (SqlPersistT (AppExample app)) (AppExample app)
where
runSqlTx = runDB

-- | A type restricted version of id
--
-- Like 'example', which forces the expectation to 'IO', this can be used to
Expand Down
2 changes: 1 addition & 1 deletion package.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: freckle-app
version: 1.10.2.0
version: 1.10.3.0
maintainer: Freckle Education
category: Utils
github: freckle/freckle-app
Expand Down
Loading