packages feed

composite-opaleye 0.4.2.0 → 0.5.0.0

raw patch · 6 files changed

+127/−5 lines, 6 filesdep +QuickCheckdep +composite-opaleyedep +hspecPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, composite-opaleye, hspec

API changes (from Hackage documentation)

+ Composite.Opaleye.Update: class RecordToUpdate (rs :: [*]) (ss :: [*])
+ Composite.Opaleye.Update: instance Composite.Opaleye.Update.RecordToUpdate '[] '[]
+ Composite.Opaleye.Update: instance Composite.Opaleye.Update.RecordToUpdate rs ss => Composite.Opaleye.Update.RecordToUpdate (r : rs) (r : ss)
+ Composite.Opaleye.Update: instance Composite.Opaleye.Update.RecordToUpdate rs ss => Composite.Opaleye.Update.RecordToUpdate (s Composite.Record.:-> a : rs) (s Composite.Record.:-> GHC.Base.Maybe a : ss)
+ Composite.Opaleye.Update: recordToUpdate :: RecordToUpdate rs ss => Record rs -> Record ss

Files

composite-opaleye.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.18.1. -- -- see: https://github.com/sol/hpack  name:           composite-opaleye-version:        0.4.2.0+version:        0.5.0.0 synopsis:       Opaleye SQL for Frames records description:    Integration between Frames records and Opaleye SQL, allowing records to be stored, retrieved, and queried from PostgreSQL. category:       Records@@ -18,7 +18,7 @@ library   hs-source-dirs:       src-  default-extensions: DataKinds FlexibleContexts FlexibleInstances LambdaCase MultiParamTypeClasses OverloadedStrings PolyKinds ScopedTypeVariables StrictData TemplateHaskell TypeFamilies TypeOperators ViewPatterns+  default-extensions: DataKinds FlexibleContexts FlexibleInstances LambdaCase MultiParamTypeClasses OverloadedStrings PatternSynonyms PolyKinds ScopedTypeVariables StrictData TemplateHaskell TypeFamilies TypeOperators ViewPatterns   ghc-options: -Wall -O2   build-depends:       base >= 4.7 && < 5@@ -37,5 +37,34 @@       Composite.Opaleye.ProductProfunctors       Composite.Opaleye.RecordTable       Composite.Opaleye.TH+      Composite.Opaleye.Update       Composite.Opaleye.Util+  other-modules:+      Paths_composite_opaleye+  default-language: Haskell2010++test-suite composite-opaleye-test+  type: exitcode-stdio-1.0+  main-is: Main.hs+  hs-source-dirs:+      test+  default-extensions: DataKinds FlexibleContexts FlexibleInstances LambdaCase MultiParamTypeClasses OverloadedStrings PatternSynonyms PolyKinds ScopedTypeVariables StrictData TemplateHaskell TypeFamilies TypeOperators ViewPatterns+  ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N -fno-warn-orphans+  build-depends:+      base >= 4.7 && < 5+    , bytestring+    , composite-base+    , lens+    , opaleye+    , postgresql-simple+    , product-profunctors+    , profunctors+    , template-haskell+    , text+    , vinyl+    , QuickCheck+    , composite-opaleye+    , hspec+  other-modules:+      UpdateSpec   default-language: Haskell2010
src/Composite/Opaleye.hs view
@@ -1,7 +1,9 @@ module Composite.Opaleye   ( module Composite.Opaleye.ProductProfunctors   , module Composite.Opaleye.RecordTable+  , module Composite.Opaleye.Update   ) where  import Composite.Opaleye.ProductProfunctors import Composite.Opaleye.RecordTable+import Composite.Opaleye.Update
src/Composite/Opaleye/RecordTable.hs view
@@ -36,10 +36,10 @@ -- -- Is equivalent to: ----- > pReq (optional "id" &: required "name" &: Nil)+-- > pRec (optional "id" &: required "name" &: Nil) -- ----- Alternately, use 'Composite.Opaleye.ProductProfunctors.pReq' and the usual Opaleye 'required' and 'optional'.+-- Alternately, use 'Composite.Opaleye.ProductProfunctors.pRec' and the usual Opaleye 'required' and 'optional'. class DefaultRecTable write read where   defaultRecTable :: TableProperties (Rec Identity write) (Rec Identity read) 
+ src/Composite/Opaleye/Update.hs view
@@ -0,0 +1,34 @@+-- |Module which provides utilities for processing updates using Opaleye and Composite+module Composite.Opaleye.Update+  ( RecordToUpdate, recordToUpdate+  ) where++import Composite.Record ((:->)(Val), Rec((:&), RNil), Record)+import Data.Functor.Identity (Identity(Identity))++-- |Typeclass which allows transformation of a record from its select form to neutral update form, which boils down to wrapping fields that have defaults+-- with 'Just'.+class RecordToUpdate (rs :: [*]) (ss :: [*]) where+  -- |Transform a @'Record' rs@ obtained from the database to a @'Record' ss@ representing an updated version of the row.+  --+  -- Opaleye's @runUpdate@ family of functions all take an update function of the type @columnsR -> columnsW@, which this function implements generically+  -- for a no-op update.+  --+  -- Typically this function is composed with one or more lens @set@s which update the fields after the transformation.+  recordToUpdate :: Record rs -> Record ss++-- |For an empty record, just act as 'id'.+instance RecordToUpdate '[] '[] where+  recordToUpdate RNil = RNil+  {-# INLINE recordToUpdate #-}++-- |For a field whose type doesn't change between selection and update, just pass the field unchanged and then recurse.+instance RecordToUpdate rs ss => RecordToUpdate (r ': rs) (r ': ss) where+  recordToUpdate (r :& rs) = r :& recordToUpdate rs+  {-# INLINE recordToUpdate #-}++-- |For a field whose type at selection is @s :-> a@ but at update is @s :-> Maybe a@ (a field which has a default value) add in a 'Just' and recurse.+instance RecordToUpdate rs ss => RecordToUpdate (s :-> a ': rs) (s :-> Maybe a ': ss) where+  recordToUpdate (Identity (Val a) :& rs) = Identity (Val (Just a)) :& recordToUpdate rs+  {-# INLINE recordToUpdate #-}+
+ test/Main.hs view
@@ -0,0 +1,7 @@+import Test.Hspec (hspec)++import UpdateSpec (updateSuite)++main :: IO ()+main = hspec $ do+  updateSuite
+ test/UpdateSpec.hs view
@@ -0,0 +1,50 @@+module UpdateSpec where++import Composite.Opaleye.Update (recordToUpdate)+import Composite.Record ((:->), Rec(RNil), Record, pattern (:*:))+import Composite.TH (withLensesAndProxies)+import Test.Hspec (Spec, describe, it, shouldBe)++withLensesAndProxies [d|+  type FFoo    = "foo" :-> Int+  type FFooMay = "foo" :-> Maybe Int+  type FBar    = "bar" :-> String+  type FBaz    = "baz" :-> Maybe Double+  type FBazMay = "baz" :-> Maybe (Maybe Double)+  type FQux    = "qux" :-> Maybe Bool+  |]++type ForSelect1 = '[]+type ForUpdate1 = '[]++type ForSelect2 = '[FBar]+type ForUpdate2 = '[FBar]++type ForSelect3 = '[FFoo]+type ForUpdate3 = '[FFooMay]++type ForSelect4 = '[FFoo   , FBar, FBaz   , FQux]+type ForUpdate4 = '[FFooMay, FBar, FBazMay, FQux]++type ForSelect5 = '[FBar, FFoo   , FQux, FBaz   ]+type ForUpdate5 = '[FBar, FFooMay, FQux, FBazMay]++updateSuite :: Spec+updateSuite = do+  describe "Composite.Opaleye.Update" $ do+    it "should compute the update version of an empty record" $ do+      recordToUpdate (                                                     RNil :: Record ForSelect1)+        `shouldBe`   (                                                     RNil :: Record ForUpdate1)+    it "should compute the update version of a record with no defaulted fields" $ do+      recordToUpdate ("hi"                                             :*: RNil :: Record ForSelect2)+        `shouldBe`   ("hi"                                             :*: RNil :: Record ForUpdate2)+    it "should compute the update version of a record with a defaulted field" $ do+      recordToUpdate (     123                                         :*: RNil :: Record ForSelect3)+        `shouldBe`   (Just 123                                         :*: RNil :: Record ForUpdate3)+    it "should compute the update version of a record with mixed fields" $ do+      recordToUpdate (     123 :*: "hi" :*:      Nothing :*: Just True :*: RNil :: Record ForSelect4)+        `shouldBe`   (Just 123 :*: "hi" :*: Just Nothing :*: Just True :*: RNil :: Record ForUpdate4)+    it "should compute the update version of a record with mixed fields and different ordering" $ do+      recordToUpdate ("hi" :*:      123 :*: Just True :*:      Nothing :*: RNil :: Record ForSelect5)+        `shouldBe`   ("hi" :*: Just 123 :*: Just True :*: Just Nothing :*: RNil :: Record ForUpdate5)+