Piggy is a tiny little Haskell library that makes Database.PostgreSQL.Simple just a tiny bit easier to work with. It also facilitates easier unit testing.
It uses the Operational monad and a simple typeclass:
classMonadm=>MonadPGmwhereinterpret::PGDSLa->mawithTransaction::ma->ma
withTransaction t = tA default interpreter — interpg — that talks to a Postgres database is provided, as is PG, a default implementation of MonadPG that actually talks to a database using interpg.
instanceMonadPGPGwhere interpret = interpg
withTransaction transact = withPostgresTransaction $flip withPG transact In unit tests, it's relatively straightforward to replace actual database access with stubs.
getPatients::MonadPGm=>m [Patient]
getPatients = interpret $ singleton (Query_"SELECT * FROM patients")
patients:: [Patient]
-- etc.interstubs::Monadm=>PGDSLa->ma
interstubs m =case view m of
(Query_"SELECT * FROM patients") :>>= k ->return patients >>= interstubs . k
-- etc.newtypePGStuba=PGStubaderiving (Functor, Applicative, Monad)
-- If `getPatients` is called with `PGStub`, it will be interpreted with-- interstubs and no actual database access will occur. In fact, the-- function is actually pure because it does not require `MonadIO`.instanceMonadPGPGStubwhere
interpret = interstubs