packages feed

pg-entity 0.0.5.1 → 0.0.6.0

raw patch · 6 files changed

+52/−130 lines, 6 filesdep −colouristadep ~bytestringdep ~resource-pooldep ~template-haskellPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: colourista

Dependency ranges changed: bytestring, resource-pool, template-haskell, time

API changes (from Hackage documentation)

- Database.PostgreSQL.Entity.DBT: Delete :: QueryNature
- Database.PostgreSQL.Entity.DBT: Insert :: QueryNature
- Database.PostgreSQL.Entity.DBT: Select :: QueryNature
- Database.PostgreSQL.Entity.DBT: Update :: QueryNature
- Database.PostgreSQL.Entity.DBT: data QueryNature
- Database.PostgreSQL.Entity.DBT: instance GHC.Classes.Eq Database.PostgreSQL.Entity.DBT.QueryNature
- Database.PostgreSQL.Entity.DBT: instance GHC.Internal.Show.Show Database.PostgreSQL.Entity.DBT.QueryNature
+ Database.PostgreSQL.Entity.DBT: data DBT (m :: Type -> Type) a
- Database.PostgreSQL.Entity.DBT: execute :: forall params (m :: Type -> Type). (ToRow params, MonadIO m) => QueryNature -> Query -> params -> DBT m Int64
+ Database.PostgreSQL.Entity.DBT: execute :: forall params (m :: Type -> Type). (HasCallStack, ToRow params, MonadIO m) => Query -> params -> DBT m Int64
- Database.PostgreSQL.Entity.DBT: executeMany :: forall params (m :: Type -> Type). (ToRow params, MonadIO m) => QueryNature -> Query -> [params] -> DBT m Int64
+ Database.PostgreSQL.Entity.DBT: executeMany :: forall params (m :: Type -> Type). (HasCallStack, ToRow params, MonadIO m) => Query -> [params] -> DBT m Int64
- Database.PostgreSQL.Entity.DBT: mkPool :: ConnectInfo -> Int -> NominalDiffTime -> Int -> IO (Pool Connection)
+ Database.PostgreSQL.Entity.DBT: mkPool :: HasCallStack => ConnectInfo -> Int -> NominalDiffTime -> Int -> IO (Pool Connection)
- Database.PostgreSQL.Entity.DBT: query :: forall params result (m :: Type -> Type). (ToRow params, FromRow result, MonadIO m) => QueryNature -> Query -> params -> DBT m (Vector result)
+ Database.PostgreSQL.Entity.DBT: query :: forall params result (m :: Type -> Type). (HasCallStack, ToRow params, FromRow result, MonadIO m) => Query -> params -> DBT m (Vector result)
- Database.PostgreSQL.Entity.DBT: queryOne :: forall params result (m :: Type -> Type). (ToRow params, FromRow result, MonadIO m) => QueryNature -> Query -> params -> DBT m (Maybe result)
+ Database.PostgreSQL.Entity.DBT: queryOne :: forall params result (m :: Type -> Type). (HasCallStack, ToRow params, FromRow result, MonadIO m) => Query -> params -> DBT m (Maybe result)
- Database.PostgreSQL.Entity.DBT: queryOne_ :: forall result (m :: Type -> Type). (FromRow result, MonadIO m) => QueryNature -> Query -> DBT m (Maybe result)
+ Database.PostgreSQL.Entity.DBT: queryOne_ :: forall result (m :: Type -> Type). (HasCallStack, FromRow result, MonadIO m) => Query -> DBT m (Maybe result)
- Database.PostgreSQL.Entity.DBT: query_ :: forall result (m :: Type -> Type). (FromRow result, MonadIO m) => QueryNature -> Query -> DBT m (Vector result)
+ Database.PostgreSQL.Entity.DBT: query_ :: forall result (m :: Type -> Type). (HasCallStack, FromRow result, MonadIO m) => Query -> DBT m (Vector result)
- Database.PostgreSQL.Entity.DBT: withPool :: MonadIO m => Pool Connection -> DBT IO a -> m a
+ Database.PostgreSQL.Entity.DBT: withPool :: (HasCallStack, MonadIO m) => Pool Connection -> DBT IO a -> m a

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for Entity +## 0.0.6.0 -- 2025-05-20++* The `prod` flag is removed, end of the experiment. End-users should be in charge of logging the queries.+ ## 0.0.5.1 -- 2025-04-23  * Update dependencies
docs/src/Tutorial.hs view
@@ -25,7 +25,6 @@ import Database.PostgreSQL.Simple import Database.PostgreSQL.Simple.FromField import Database.PostgreSQL.Simple.ToField-import Database.PostgreSQL.Transact (DBT) import GHC.Generics  import Control.Monad.IO.Class (MonadIO (..))
pg-entity.cabal view
@@ -5,7 +5,7 @@   A PostgreSQL layer to safely expand your SQL queries with a lightweight eDSL.   Read the tutorial at https://hackage.haskell.org/package/pg-entity/src/docs/book/index.html -version:            0.0.5.1+version:            0.0.6.0 homepage:   https://hackage.haskell.org/package/pg-entity/src/docs/book/index.html @@ -15,7 +15,7 @@ category:           Database license:            MIT build-type:         Simple-tested-with:        GHC ==9.2.8 || ==9.4.8 || ==9.6.7 || ==9.8.4 || ==9.10.1+tested-with:        GHC ==9.2.8 || ==9.4.8 || ==9.6.7 || ==9.8.4 || ==9.10.2 extra-source-files:   CHANGELOG.md   LICENSE.md@@ -34,13 +34,6 @@   ./docs/book/fonts/*.woff2   ./docs/book/searchindex.json -flag prod-  description:-    This flag enables features for production usage, like disabling logs--  default:     False-  manual:      True- flag book   description: Enable the generation of the book   default:     False@@ -103,8 +96,6 @@   hs-source-dirs:  src   build-depends:     , base               >=4.12     && <5.0-    , bytestring         ^>=0.12-    , colourista         ^>=0.1     , parsec             ^>=3.1     , pg-transact        ^>=0.3     , postgresql-simple  ^>=0.7@@ -113,11 +104,8 @@     , text               ^>=2.1     , text-display       ^>=1.0     , text-manipulate    ^>=0.3-    , time               ^>=1.14+    , time               >=1.12 && <1.16     , vector             ^>=0.13--  if flag(prod)-    cpp-options: -DPROD  executable book   import:         common-extensions
src/Database/PostgreSQL/Entity.hs view
@@ -22,6 +22,8 @@      -- * High-level API     -- $highlevel+ +    -- ** Selection   , selectById   , selectOneByField   , selectManyByField@@ -93,7 +95,7 @@ import Database.PostgreSQL.Transact (DBT)  import Data.Text (Text)-import Database.PostgreSQL.Entity.DBT (QueryNature (..), execute, executeMany, query, queryOne, queryOne_, query_)+import Database.PostgreSQL.Entity.DBT (execute, executeMany, query, queryOne, queryOne_, query_) import Database.PostgreSQL.Entity.Internal import Database.PostgreSQL.Entity.Types @@ -174,7 +176,7 @@   => Field   -> value   -> DBT m (Maybe e)-selectOneByField f value = queryOne Select (_selectWhere @e [f]) value+selectOneByField f value = queryOne (_selectWhere @e [f]) value  {-| Select potentially many entities by a provided field. @@ -186,7 +188,7 @@   => Field   -> value   -> DBT m (Vector e)-selectManyByField f value = query Select (_selectWhere @e [f]) value+selectManyByField f value = query (_selectWhere @e [f]) value  {-| Select statement with a non-null condition @@ -199,7 +201,7 @@    . (Entity e, FromRow e, MonadIO m)   => Vector Field   -> DBT m (Vector e)-selectWhereNotNull fs = query_ Select (_selectWhereNotNull @e fs)+selectWhereNotNull fs = query_ (_selectWhereNotNull @e fs)  {-| Select statement with a null condition @@ -212,7 +214,7 @@    . (Entity e, FromRow e, MonadIO m)   => Vector Field   -> DBT m (Vector e)-selectWhereNull fs = query_ Select (_selectWhereNull @e fs)+selectWhereNull fs = query_ (_selectWhereNull @e fs)  {-| Select statement when for an entity where the field is one of the options passed @@ -224,7 +226,7 @@   => Field   -> Vector Text   -> DBT m (Maybe e)-selectOneWhereIn f values = queryOne_ Select (_selectWhereIn @e f values)+selectOneWhereIn f values = queryOne_ (_selectWhereIn @e f values)  {-| Perform a INNER JOIN between two entities @@ -234,7 +236,7 @@   :: forall e1 e2 m    . (Entity e1, Entity e2, FromRow e1, MonadIO m)   => DBT m (Vector e1)-joinSelectById = query_ Select (_joinSelect @e1 @e2)+joinSelectById = query_ (_joinSelect @e1 @e2)  {-| Perform a @INNER JOIN ON field1 WHERE field2 = value@ between two entities @@ -251,7 +253,7 @@   -- ^ The value of the where clause   -> DBT m (Vector e1) joinSelectOneByField pivot whereClause value =-  query Select (_joinSelectOneByField @e1 @e2 pivot whereClause) (Only value)+  query (_joinSelectOneByField @e1 @e2 pivot whereClause) (Only value)  -- @@ -264,7 +266,7 @@    . (Entity e, FromRow e, MonadIO m)   => Vector (Field, SortKeyword)   -> DBT m (Vector e)-selectOrderBy sortSpec = query_ Select (_select @e <> _orderByMany sortSpec)+selectOrderBy sortSpec = query_ (_select @e <> _orderByMany sortSpec)  {-| Insert an entity. @@ -275,7 +277,7 @@    . (Entity e, ToRow values, MonadIO m)   => values   -> DBT m ()-insert fs = void $ execute Insert (_insert @e) fs+insert fs = void $ execute (_insert @e) fs  {-| Insert an entity with a "ON CONFLICT DO UPDATE" clause on the primary key as the conflict target @@ -289,7 +291,7 @@   -> Vector Field   -- ^ Fields to replace in case of conflict   -> DBT m ()-upsert entity fieldsToReplace = void $ execute Insert (_insert @e <> _onConflictDoUpdate conflictTarget fieldsToReplace) entity+upsert entity fieldsToReplace = void $ execute (_insert @e <> _onConflictDoUpdate conflictTarget fieldsToReplace) entity   where     conflictTarget = V.singleton $ primaryKey @e @@ -302,7 +304,7 @@    . (Entity e, ToRow values, MonadIO m)   => [values]   -> DBT m ()-insertMany values = void $ executeMany Insert (_insert @e) values+insertMany values = void $ executeMany (_insert @e) values  {-| Update an entity. @@ -319,7 +321,7 @@    . (Entity e, ToRow newValue, MonadIO m)   => newValue   -> DBT m ()-update fs = void $ execute Update (_update @e) (UpdateRow fs)+update fs = void $ execute (_update @e) (UpdateRow fs)  {-| Update rows of an entity matching the given value @@ -341,7 +343,7 @@   -> v2   -- ^ New values of those fields   -> DBT m Int64-updateFieldsBy fs (f, oldValue) newValue = execute Update (_updateFieldsBy @e fs f) (toRow newValue ++ toRow (Only oldValue))+updateFieldsBy fs (f, oldValue) newValue = execute (_updateFieldsBy @e fs f) (toRow newValue ++ toRow (Only oldValue))  {-| Delete an entity according to its primary key. @@ -368,7 +370,7 @@   => Vector Field   -> values   -> DBT m ()-deleteByField fs values = void $ execute Delete (_deleteWhere @e fs) values+deleteByField fs values = void $ execute (_deleteWhere @e fs) values  -- * SQL combinators API 
src/Database/PostgreSQL/Entity/DBT.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wno-redundant-constraints #-}  {-|   Module      : Database.PostgreSQL.Entity.DBT@@ -11,7 +12,8 @@   The 'Database.PostgreSQL.Transact.DBT' plumbing module to handle database queries and pools -} module Database.PostgreSQL.Entity.DBT-  ( mkPool+  ( PGT.DBT+  , mkPool   , withPool   , execute   , executeMany@@ -19,32 +21,19 @@   , query_   , queryOne   , queryOne_-  , QueryNature (..)   ) where -#ifdef PROD-#else-import Colourista (cyan, red, yellow, formatWith)-import Data.ByteString (ByteString)-import qualified Database.PostgreSQL.Simple as Simple-import System.IO (stdout)-import qualified Data.ByteString.Char8 as BS-#endif  import Control.Monad.IO.Class-#if MIN_VERSION_resource_pool(0,3,0)-#else-import Control.Monad.Trans.Control-#endif import Data.Int import Data.Maybe (listToMaybe) import Data.Pool (Pool, createPool, withResource) import Data.Time (NominalDiffTime) import Data.Vector (Vector)-import qualified Data.Vector as V- import Database.PostgreSQL.Simple as PG (ConnectInfo, Connection, FromRow, Query, ToRow, close, connect)+import GHC.Stack+import qualified Data.Vector as V import qualified Database.PostgreSQL.Transact as PGT  {-| Create a Pool Connection with the appropriate parameters@@ -52,7 +41,8 @@  @since 0.0.1.0 -} mkPool-  :: ConnectInfo -- Database access information+  :: HasCallStack+  => ConnectInfo -- Database access information   -> Int -- Number of sub-pools   -> NominalDiffTime -- Allowed timeout   -> Int -- Number of connections@@ -78,26 +68,19 @@   @since 0.0.1.0 -}-#if MIN_VERSION_resource_pool(0,3,0)-withPool :: (MonadIO m) => Pool Connection -> PGT.DBT IO a -> m a+withPool :: (HasCallStack, MonadIO m) => Pool Connection -> PGT.DBT IO a -> m a withPool pool action = liftIO $ withResource pool (\conn -> PGT.runDBTSerializable action conn)-#else-withPool :: (MonadBaseControl IO m) => Pool Connection -> PGT.DBT m a -> m a-withPool pool action = withResource pool (\conn -> PGT.runDBTSerializable action conn)-#endif  {-| Query wrapper that returns a 'Vector' of results   @since 0.0.1.0 -} query-  :: (ToRow params, FromRow result, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, ToRow params, FromRow result, MonadIO m)+  => Query   -> params   -> PGT.DBT m (Vector result)-query queryNature q params = do-  logQueryFormat queryNature q params+query q params = do   V.fromList <$> PGT.query q params  {-| Query wrapper that returns a 'Vector' of results and does not take an argument@@ -105,12 +88,10 @@  @since 0.0.1.0 -} query_-  :: (FromRow result, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, FromRow result, MonadIO m)+  => Query   -> PGT.DBT m (Vector result)-query_ queryNature q = do-  logQueryFormat queryNature q ()+query_ q = do   V.fromList <$> PGT.query_ q  {-| Query wrapper that returns one result.@@ -118,13 +99,11 @@  @since 0.0.1.0 -} queryOne-  :: (ToRow params, FromRow result, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, ToRow params, FromRow result, MonadIO m)+  => Query   -> params   -> PGT.DBT m (Maybe result)-queryOne queryNature q params = do-  logQueryFormat queryNature q params+queryOne q params = do   listToMaybe <$> PGT.query q params  --@@ -134,12 +113,10 @@  @since 0.0.2.0 -} queryOne_-  :: (FromRow result, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, FromRow result, MonadIO m)+  => Query   -> PGT.DBT m (Maybe result)-queryOne_ queryNature q = do-  logQueryFormat queryNature q ()+queryOne_ q = do   listToMaybe <$> PGT.query_ q  {-| Query wrapper for SQL statements which do not return.@@ -147,13 +124,11 @@  @since 0.0.1.0 -} execute-  :: (ToRow params, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, ToRow params, MonadIO m)+  => Query   -> params   -> PGT.DBT m Int64-execute queryNature q params = do-  logQueryFormat queryNature q params+execute q params = do   PGT.execute q params  {-| Query wrapper for SQL statements that operate on multiple rows which do not return.@@ -161,55 +136,9 @@  @since 0.0.2.0 -} executeMany-  :: (ToRow params, MonadIO m)-  => QueryNature-  -> Query+  :: (HasCallStack, ToRow params, MonadIO m)+  => Query   -> [params]   -> PGT.DBT m Int64-executeMany queryNature q params = do-  logQueryFormatMany queryNature q params+executeMany q params = do   PGT.executeMany q params--#ifndef PROD-displayColoured :: (MonadIO m) => ByteString -> ByteString -> PGT.DBT m ()-displayColoured colour text = liftIO $ BS.hPutStrLn stdout (formatWith [colour] text)-#endif--#ifdef PROD-logQueryFormat :: (Monad m) => QueryNature -> Query -> params -> PGT.DBT m ()-logQueryFormat _ _ _ = pure ()-#else-logQueryFormat :: (ToRow params, MonadIO m)-               => QueryNature -> Query -> params -> PGT.DBT m ()-logQueryFormat queryNature q params = do-  msg <- PGT.formatQuery q params-  case queryNature of-    Select -> displayColoured cyan msg-    Update -> displayColoured yellow msg-    Insert -> displayColoured yellow msg-    Delete -> displayColoured red msg-#endif--#ifdef PROD-logQueryFormatMany :: (Monad m) => QueryNature -> Query -> [params] -> PGT.DBT m ()-logQueryFormatMany _ _ _ = pure ()-#else-logQueryFormatMany :: (ToRow params, MonadIO m) => QueryNature -> Query -> [params] -> PGT.DBT m ()-logQueryFormatMany queryNature q params = do-  msg <- formatMany q params-  case queryNature of-    Select -> displayColoured cyan msg-    Update -> displayColoured yellow msg-    Insert -> displayColoured yellow msg-    Delete -> displayColoured red msg--formatMany :: (ToRow q, MonadIO m) => Query -> [q] -> PGT.DBT m ByteString-formatMany q xs = PGT.getConnection >>= \conn -> liftIO $ Simple.formatMany conn q xs-#endif--{-| This sum type is given to the 'query', 'queryOne' and 'execute' functions to help- with logging.-- @since 0.0.1.0--}-data QueryNature = Select | Insert | Update | Delete deriving (Eq, Show)
test/EntitySpec.hs view
@@ -35,7 +35,7 @@   , _joinSelectWithFields   , _where   )-import Database.PostgreSQL.Entity.DBT (QueryNature (..), query)+import Database.PostgreSQL.Entity.DBT (query) import Database.PostgreSQL.Simple (Only (Only)) import Database.PostgreSQL.Transact (DBT) @@ -133,7 +133,7 @@   let q =         _joinSelectWithFields @BlogPost @Author [[field| title |]] [[field| name |]]           <> _where [[field| name |]]-  result <- liftDB (query Select q (Only ("Hansi Kürsch" :: Text)) :: MonadIO m => DBT m (Vector (Text, Text)))+  result <- liftDB (query q (Only ("Hansi Kürsch" :: Text)) :: MonadIO m => DBT m (Vector (Text, Text)))   let actualMap = Map.fromList $ Vector.toList result   let expectedMap = Map.fromList [("The Script for my requiem", "Hansi Kürsch"), ("Mordred's Song", "Hansi Kürsch")]   U.assertEqual