Add missing instances to (:&) (#291)

* Add missing instances to (:&)

The (:&) operator has an instance for `SqlSelect`, but none
for `ToAlias` and `ToAliasReference`. Adding those for parity.

* Updates based on review.

* Update test/Common/Test.hs

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>

* Update test/Common/Test.hs

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>
This commit is contained in:
m4dc4p 2021-09-30 10:43:04 -07:00 committed by GitHub
parent 2a44844f75
commit ed4e98f96b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 3 deletions

View File

@ -1,9 +1,15 @@
3.5.2.3
3.5.3.0
=======
- @m4dc4p
- [#291](https://github.com/bitemyapp/esqueleto/pull/291)
- Added `ToAlias` and `ToAliasReference` instaces to the `:&` type, mirroring
the tuple instances for the same classes. See [Issue #290](https://github.com/bitemyapp/esqueleto/issues/290)
for discussion.
- @NikitaRazmakhnin
- [#284](https://github.com/bitemyapp/esqueleto/pull/284)
- Add PostgreSQL-specific support of VALUES(..) literals
3.5.2.2
=======
- @NikitaRazmakhnin

View File

@ -1,7 +1,7 @@
cabal-version: 1.12
name: esqueleto
version: 3.5.2.3
version: 3.5.3.0
synopsis: Type-safe EDSL for SQL queries on persistent backends.
description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime.
.

View File

@ -61,6 +61,18 @@ instance (SqlSelect a ra, SqlSelect b rb) => SqlSelect (a :& b) (ra :& rb) where
toTuple = const Proxy
sqlSelectProcessRow = fmap (uncurry (:&)) . sqlSelectProcessRow
-- | Identical to the tuple instance and provided for convenience.
--
-- @since 3.5.3.0
instance (ToAlias a, ToAlias b) => ToAlias (a :& b) where
toAlias (a :& b) = (:&) <$> toAlias a <*> toAlias b
-- | Identical to the tuple instance and provided for convenience.
--
-- @since 3.5.3.0
instance (ToAliasReference a, ToAliasReference b) => ToAliasReference (a :& b) where
toAliasReference ident (a :& b) = (:&) <$> (toAliasReference ident a) <*> (toAliasReference ident b)
-- | An @ON@ clause that describes how two tables are related. This should be
-- used as an infix operator after a 'JOIN'. For example,
--

View File

@ -2275,7 +2275,6 @@ testExperimentalFrom = do
, (l2e, l2e)
]
itDb "compiles" $ do
let q = do
(persons :& profiles :& posts) <-
@ -2300,6 +2299,24 @@ testExperimentalFrom = do
asserting $ upperNames `shouldMatchList` [ Value "JOHN"
, Value "MIKE"
]
itDb "allows re-using (:&) joined tables" $ do
let q = do
result@(persons :& profiles :& posts) <-
Experimental.from $ Table @Person
`InnerJoin` Table @Profile
`Experimental.on` (\(people :& profiles) ->
people ^. PersonId ==. profiles ^. ProfilePerson)
`InnerJoin` Table @BlogPost
`Experimental.on` (\(people :& _ :& posts) ->
people ^. PersonId ==. posts ^. BlogPostAuthorId)
pure result
rows <- select $ do
(persons :& profiles :& posts) <- Experimental.from $ q
pure (persons ^. PersonId, profiles ^. ProfileId, posts ^. BlogPostId)
let result = coerce rows :: [(PersonId, ProfileId, BlogPostId)]
-- We don't care about eh result of the query, only that it
-- rendered & executed.
asserting noExceptions
listsEqualOn :: (HasCallStack, Show a1, Eq a1) => [a2] -> [a2] -> (a2 -> a1) -> Expectation
listsEqualOn a b f = map f a `shouldBe` map f b