groundhog 0.4.0.3 → 0.4.1
raw patch · 8 files changed
+52/−11 lines, 8 files
Files
- Database/Groundhog.hs +1/−0
- Database/Groundhog/Core.hs +7/−3
- Database/Groundhog/Expression.hs +3/−2
- Database/Groundhog/Generic.hs +5/−0
- Database/Groundhog/Generic/PersistBackendHelpers.hs +29/−3
- Database/Groundhog/Generic/Sql/Functions.hs +2/−0
- Database/Groundhog/Instances.hs +3/−1
- groundhog.cabal +2/−2
Database/Groundhog.hs view
@@ -20,6 +20,7 @@ , limitTo , offsetBy , orderBy+ , deleteByKey -- * Expressions , (=.) , (&&.), (||.)
Database/Groundhog/Core.hs view
@@ -273,10 +273,12 @@ insertByAll :: PersistEntity v => v -> m (Either (AutoKey v) (AutoKey v)) -- | Replace a record with the given autogenerated key. Result is undefined if the record does not exist. replace :: (PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => Key v BackendSpecific -> v -> m ()+ -- | Replace a record. The unique key marker defines what unique key of the entity is used.+ replaceBy :: (PersistEntity v, IsUniqueKey (Key v (Unique u))) => u (UniqueMarker v) -> v -> m () -- | Return a list of the records satisfying the condition. Example: @select $ (FirstField ==. \"abc\" &&. SecondField >. \"def\") \`orderBy\` [Asc ThirdField] \`limitTo\` 100@ select :: (PersistEntity v, EntityConstr v c, HasSelectOptions opts (PhantomDb m) (RestrictionHolder v c)) => opts -> m [v]- -- | Return a list of all records. Order is undefined. It is useful for datatypes with multiple constructors.+ -- | Return a list of all records. Order is undefined. It can be useful for datatypes with multiple constructors. selectAll :: PersistEntity v => m [(AutoKey v, v)] -- | Fetch an entity from a database get :: (PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => Key v BackendSpecific -> m (Maybe v)@@ -287,10 +289,12 @@ -- | Remove the records satisfying the condition delete :: (PersistEntity v, EntityConstr v c) => Cond (PhantomDb m) (RestrictionHolder v c) -> m () -- | Remove the record with given key. No-op if the record does not exist- deleteByKey :: (PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => Key v BackendSpecific -> m ()+ deleteBy :: (PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => Key v BackendSpecific -> m ()+ -- | Remove all records. The entity parameter is used only for type inference.+ deleteAll :: PersistEntity v => v -> m () -- | Count total number of records satisfying the condition count :: (PersistEntity v, EntityConstr v c) => Cond (PhantomDb m) (RestrictionHolder v c) -> m Int- -- | Count total number of records with all constructors+ -- | Count total number of records with all constructors. The entity parameter is used only for type inference countAll :: PersistEntity v => v -> m Int -- | Fetch projection of some fields. Example: @project (SecondField, ThirdField) $ (FirstField ==. \"abc\" &&. SecondField >. \"def\") \`orderBy\` [Asc ThirdField] \`offsetBy\` 100@ project :: (PersistEntity v, EntityConstr v c, Projection p (PhantomDb m) (RestrictionHolder v c) a, HasSelectOptions opts (PhantomDb m) (RestrictionHolder v c))
Database/Groundhog/Expression.hs view
@@ -8,7 +8,8 @@ -- StringField ==. \"abc\" &&. NumberField >. (0 :: Int) ||. MaybeField ==. (Nothing :: Maybe String) ||. MaybeField ==. Just \"def\" -- @ -- --- Note that polymorphic values like numbers or Nothing must have a type annotation +-- Note that polymorphic values like numbers or Nothing must have a type annotation. +-- Comparison operators specific for SQL such as IN and LIKE are defined in "Database.Groundhog.Generic.Sql.Functions". module Database.Groundhog.Expression ( Expression(..) @@ -142,4 +143,4 @@ isFieldNothing :: (Expression db r f, FieldLike f db r (Maybe a), PrimitivePersistField (Maybe a), Unifiable f (Maybe a)) => f -> Cond db r isFieldNothing a = a `eq` Nothing where eq :: (Expression db r f, Expression db r a, FieldLike f db r a, Unifiable f a) => f -> a -> Cond db r - eq = (==.)+ eq = (==.)
Database/Groundhog/Generic.hs view
@@ -51,6 +51,7 @@ , mapAllRows , phantomDb , isSimple+ , deleteByKey ) where import Database.Groundhog.Core@@ -319,3 +320,7 @@ -- | It helps to run 'withConnSavepoint' within a monad. withSavepoint :: (HasConn m cm conn, SingleConnectionManager cm conn, Savepoint conn) => String -> m a -> m a withSavepoint name m = ask >>= withConnNoTransaction (withConnSavepoint name m)++{-# DEPRECATED deleteByKey "Use deleteBy instead" #-}+deleteByKey :: (PersistBackend m, PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => Key v BackendSpecific -> m ()+deleteByKey = deleteBy
Database/Groundhog/Generic/PersistBackendHelpers.hs view
@@ -10,10 +10,12 @@ , project , count , replace+ , replaceBy , update , delete+ , deleteBy+ , deleteAll , insertByAll- , deleteByKey , countAll , insertBy ) where@@ -196,6 +198,23 @@ execFunc updateDiscrQuery [head vals, toPrimitivePersistValue proxy k] Nothing -> return () +replaceBy :: forall m v u . (PersistBackend m, PersistEntity v, IsUniqueKey (Key v (Unique u)))+ => (Utf8 -> Utf8) -- ^ escape+ -> (Utf8 -> [PersistValue] -> m ()) -- ^ function to execute query+ -> u (UniqueMarker v)+ -> v+ -> m ()+replaceBy escape execFunc u v = do+ uniques <- toPersistValues $ (extractUnique v `asTypeOf` ((undefined :: u (UniqueMarker v) -> Key v (Unique u)) u))+ vals <- toEntityPersistValues v+ let e = entityDef (undefined :: v)+ uFields = renderChain escape (fieldChain u) []+ RenderS cond condVals = intercalateS " AND " $ mkUniqueCond uFields uniques+ constr = head $ constructors e+ upds = renderFields (\f -> escape f <> "=?") $ constrParams constr+ updateQuery = "UPDATE " <> tableName escape e constr <> " SET " <> upds <> " WHERE " <> cond+ execFunc updateQuery (tail . vals . condVals $ [])+ update :: forall m db r v c . (SqlDb db, QueryRaw db ~ Snippet db, db ~ PhantomDb m, r ~ RestrictionHolder v c, PersistBackend m, PersistEntity v, EntityConstr v c) => (Utf8 -> Utf8) -> (Utf8 -> [PersistValue] -> m ()) -> (Cond db r -> Maybe (RenderS db r)) -> [Update db r] -> Cond db r -> m () update escape execFunc renderCond' upds cond = do@@ -247,9 +266,9 @@ Nothing -> liftM Right $ Core.insert v Just xs -> return $ Left $ fst $ fromPurePersistValues proxy xs -deleteByKey :: forall m v . (PersistBackend m, PersistEntity v, PrimitivePersistField (Key v BackendSpecific))+deleteBy :: forall m v . (PersistBackend m, PersistEntity v, PrimitivePersistField (Key v BackendSpecific)) => (Utf8 -> Utf8) -> (Utf8 -> [PersistValue] -> m ()) -> Key v BackendSpecific -> m ()-deleteByKey escape execFunc k = execFunc query [toPrimitivePersistValue proxy k] where+deleteBy escape execFunc k = execFunc query [toPrimitivePersistValue proxy k] where e = entityDef ((undefined :: Key v u -> v) k) proxy = undefined :: Proxy (PhantomDb m) constr = head $ constructors e@@ -258,6 +277,13 @@ else "id" -- the entries in the constructor table are deleted because of the reference on delete cascade query = "DELETE FROM " <> mainTableName escape e <> " WHERE " <> idName <> "=?"++deleteAll :: forall m v . (PersistBackend m, PersistEntity v)+ => (Utf8 -> Utf8) -> (Utf8 -> [PersistValue] -> m ()) -> v -> m ()+deleteAll escape execFunc (_ :: v) = do+ let e = entityDef (undefined :: v)+ query = "DELETE FROM " <> mainTableName escape e+ execFunc query [] countAll :: forall m v . (PersistBackend m, PersistEntity v) => (Utf8 -> Utf8) -> (forall a . Utf8 -> [DbType] -> [PersistValue] -> (RowPopper m -> m a) -> m a) -> v -> m Int
Database/Groundhog/Generic/Sql/Functions.hs view
@@ -18,10 +18,12 @@ in_ :: (SqlDb db, QueryRaw db ~ Snippet db, Expression db r a, Expression db r b, PrimitivePersistField b, Unifiable a b) => a -> [b] -> Cond db r+in_ _ [] = CondEmpty in_ a bs = CondRaw $ Snippet $ \esc p -> [parens 45 p $ renderExpr esc (toExpr a) <> " IN (" <> commasJoin (map (renderExpr esc . toExpr) bs) <> ")"] notIn_ :: (SqlDb db, QueryRaw db ~ Snippet db, Expression db r a, Expression db r b, PrimitivePersistField b, Unifiable a b) => a -> [b] -> Cond db r+notIn_ _ [] = CondEmpty notIn_ a bs = CondRaw $ Snippet $ \esc p -> [parens 45 p $ renderExpr esc (toExpr a) <> " NOT IN (" <> commasJoin (map (renderExpr esc . toExpr) bs) <> ")"] like :: (SqlDb db, QueryRaw db ~ Snippet db, ExpressionOf db r a String) => a -> String -> Cond db r
Database/Groundhog/Instances.hs view
@@ -12,7 +12,7 @@ import Data.ByteString.Char8 (ByteString, unpack) import Data.Int (Int8, Int16, Int32, Int64) import Data.Time (Day, TimeOfDay, UTCTime)-import Data.Time.LocalTime (ZonedTime)+import Data.Time.LocalTime (ZonedTime, zonedTimeToUTC, utc, utcToZonedTime) import Data.Word (Word8, Word16, Word32, Word64) instance (PersistField a', PersistField b') => Embedded (a', b') where@@ -187,11 +187,13 @@ instance PrimitivePersistField UTCTime where toPrimitivePersistValue _ a = PersistUTCTime a fromPrimitivePersistValue _ (PersistUTCTime a) = a+ fromPrimitivePersistValue _ (PersistZonedTime (ZT a)) = zonedTimeToUTC a fromPrimitivePersistValue _ x = readHelper x ("Expected UTCTime, received: " ++ show x) instance PrimitivePersistField ZonedTime where toPrimitivePersistValue _ a = PersistZonedTime (ZT a) fromPrimitivePersistValue _ (PersistZonedTime (ZT a)) = a+ fromPrimitivePersistValue _ (PersistUTCTime a) = utcToZonedTime utc a fromPrimitivePersistValue _ x = readHelper x ("Expected ZonedTime, received: " ++ show x) instance (PrimitivePersistField a, NeverNull a) => PrimitivePersistField (Maybe a) where
groundhog.cabal view
@@ -1,11 +1,11 @@ name: groundhog-version: 0.4.0.3+version: 0.4.1 license: BSD3 license-file: LICENSE author: Boris Lykah <lykahb@gmail.com> maintainer: Boris Lykah <lykahb@gmail.com> synopsis: Type-safe datatype-database mapping library.-description: This library maps your datatypes to a relational model, in a way similar to what ORM libraries do in OOP. The schema can be configured flexibly which makes integration with existing databases easy. Groundhog supports schema migrations, composite keys, advanced expressions in queries, and much more. See examples folder on GitHub.+description: This library maps your datatypes to a relational model, in a way similar to what ORM libraries do in OOP. The schema can be configured flexibly which makes integration with existing databases easy. Groundhog supports schema migrations, composite keys, advanced expressions in queries, and much more. See tutorial <https://www.fpcomplete.com/user/lykahb/groundhog> and examples <https://github.com/lykahb/groundhog/tree/master/examples> on GitHub. category: Database stability: Stable cabal-version: >= 1.6