persistent-typed-db 0.0.1.1 → 0.1.0.0
raw patch · 5 files changed
+44/−25 lines, 5 filesdep ~persistentdep ~persistent-templatePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: persistent, persistent-template
API changes (from Hackage documentation)
Files
- CHANGELOG.md +3/−1
- README.md +7/−7
- persistent-typed-db.cabal +4/−4
- src/Database/Persist/Typed.hs +25/−9
- test/EsqueletoSpec.hs +5/−4
CHANGELOG.md view
@@ -1,6 +1,8 @@ # CHANGELOG -# Upcoming+# v0.1.0.0++- Add support for `persistent` v2.10.0 and `persistent-template` 2.7.0 # v0.0.1.1
README.md view
@@ -135,21 +135,21 @@ ``` This changes the type of the `PersistEntityBackend record` for each entity defined in the QuasiQuoter.-The previous type of `PersistEntityBackend User` was `SqlBackend`, but with this change, it is now `SqlBackendFor MainDb`.-Likewise, the type of `PersistEntityBackend AuxRecord` has become `SqlBackendFor AuxDb`.+The previous type of `PersistEntityBackend User` was `SqlBackend`, but with this change, it is now `SqlFor MainDb`.+Likewise, the type of `PersistEntityBackend AuxRecord` has become `SqlFor AuxDb`. ## Using the Schema Let's look at the new type of `get` for these two records: ```haskell-get :: (MonadIO m, PersistEntityBackend User ~ SqlBackendFor MainDb)+get :: (MonadIO m, PersistEntityBackend User ~ SqlFor MainDb) => Key record- -> ReaderT (SqlBackendFor MainDb) m (Maybe User)+ -> ReaderT (SqlFor MainDb) m (Maybe User) -get :: (MonadIO m, PersistEntityBackend AuxRecord ~ SqlBackendFor AuxDb)+get :: (MonadIO m, PersistEntityBackend AuxRecord ~ SqlFor AuxDb) => Key record- -> ReaderT (SqlBackendFor AuxDb) m (Maybe AuxRecord)+ -> ReaderT (SqlFor AuxDb) m (Maybe AuxRecord) ``` Now that the monad type is different, we can't use them in the same query.@@ -160,7 +160,7 @@ ```haskell type SqlPersistT = ReaderT SqlBackend-type SqlPersistTFor db = ReaderT (SqlBackendFor db)+type SqlPersistTFor db = ReaderT (SqlFor db) ``` When using this library, it is a good idea to define a type snynonym for your databases as well.
persistent-typed-db.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 3ae9dc27e1c8f46a8a8113bb14311522ef631291dc5ae951b1f8082a83789c00+-- hash: 13035f38c6a20d1aee4b5221bf6a76a86992a9aa8b015559769254324aeecd16 name: persistent-typed-db-version: 0.0.1.1+version: 0.1.0.0 synopsis: Type safe access to multiple database schemata. description: See README.md for more details, examples, and fun. category: Web@@ -43,8 +43,8 @@ , http-api-data , monad-logger , path-pieces- , persistent >=2.8.0- , persistent-template+ , persistent >=2.10.0+ , persistent-template >=2.7.0 , resource-pool , resourcet >=1.2.0 , template-haskell
src/Database/Persist/Typed.hs view
@@ -530,7 +530,7 @@ [] -> withReaderT SqlFor $ defaultUpsert record updates _:_ -> do let upds = Text.intercalate "," $ map (go' . go) updates- sql = upsertSql t upds+ sql = upsertSql t (pure (onlyOneUniqueDef (Just record))) upds vals = map toPersistValue (toPersistFields record) ++ map updatePersistValue updates ++ unqs uniqueKey@@ -844,8 +844,11 @@ fromPersistList (PersistList xs) = xs fromPersistList other = error $ "expected PersistList but found " ++ show other - filterValueToPersistValues :: forall a. PersistField a => Either a [a] -> [PersistValue]- filterValueToPersistValues v = map toPersistValue $ either return id v+ filterValueToPersistValues :: forall a. PersistField a => FilterValue a -> [PersistValue]+ filterValueToPersistValues v = case v of+ FilterValue a -> map toPersistValue [a]+ FilterValues as -> map toPersistValue as+ UnsafeValue a -> map toPersistValue [a] orNullSuffix = case orNull of@@ -863,10 +866,10 @@ else id) $ connEscapeName conn $ fieldName field qmarks = case value of- Left _ -> "?"- Right x ->+ FilterValues x -> let x' = filter (/= PersistNull) $ map toPersistValue x in "(" <> Text.intercalate "," (map (const "?") x') <> ")"+ _ -> "?" showSqlFilter Eq = "=" showSqlFilter Ne = "<>" showSqlFilter Gt = ">"@@ -913,10 +916,11 @@ $ connEscapeName conn $ fieldName x defaultUpsert- :: (MonadIO m- ,PersistEntity record- ,PersistUniqueWrite backend- ,PersistEntityBackend record ~ BaseBackend backend)+ :: ( MonadIO m+ , PersistEntity record+ , PersistUniqueWrite backend+ , PersistEntityBackend record ~ BaseBackend backend+ , OnlyOneUniqueKey record) => record -> [Update record] -> ReaderT backend m (Entity record) defaultUpsert record updates = do uniqueKey <- onlyUnique record@@ -951,3 +955,15 @@ chunksOf _ [] = [] chunksOf size xs = let (chunk, rest) = splitAt size xs in chunk : chunksOf size rest +-- | Given a proxy for a 'PersistEntity' record, this returns the sole+-- 'UniqueDef' for that entity.+--+-- @since 2.10.0+onlyOneUniqueDef+ :: (OnlyOneUniqueKey record, Monad proxy)+ => proxy record+ -> UniqueDef+onlyOneUniqueDef prxy =+ case entityUniques (entityDef prxy) of+ [uniq] -> uniq+ _ -> error "impossible due to OnlyOneUniqueKey constraint"
test/EsqueletoSpec.hs view
@@ -10,13 +10,14 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} module EsqueletoSpec where -import Database.Persist.Typed-import Database.Esqueleto-import Database.Persist.TH-import Test.Hspec+import Database.Esqueleto+import Database.Persist.TH+import Database.Persist.Typed+import Test.Hspec data TestDb