{-# language TupleSections #-}

module Rel8.Query.Opaleye
  ( fromOpaleye
  , toOpaleye
  , mapOpaleye
  , zipOpaleyeWith
  , unsafePeekQuery
  )
where

-- base
import Control.Applicative ( liftA2 )
import Prelude

-- opaleye
import qualified Opaleye.Internal.QueryArr as Opaleye
import qualified Opaleye.Internal.Tag as Opaleye

-- rel8
import {-# SOURCE #-} Rel8.Query ( Query( Query ) )


fromOpaleye :: Opaleye.Select a -> Query a
fromOpaleye :: Select a -> Query a
fromOpaleye = ([PrimExpr] -> Select (Any, a)) -> Query a
forall a. ([PrimExpr] -> Select (Any, a)) -> Query a
Query (([PrimExpr] -> Select (Any, a)) -> Query a)
-> (Select a -> [PrimExpr] -> Select (Any, a))
-> Select a
-> Query a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Select (Any, a) -> [PrimExpr] -> Select (Any, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Select (Any, a) -> [PrimExpr] -> Select (Any, a))
-> (Select a -> Select (Any, a))
-> Select a
-> [PrimExpr]
-> Select (Any, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (Any, a)) -> Select a -> Select (Any, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> (Any, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure


toOpaleye :: Query a -> Opaleye.Select a
toOpaleye :: Query a -> Select a
toOpaleye (Query [PrimExpr] -> Select (Any, a)
a) = (Any, a) -> a
forall a b. (a, b) -> b
snd ((Any, a) -> a) -> Select (Any, a) -> Select a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PrimExpr] -> Select (Any, a)
a [PrimExpr]
forall a. Monoid a => a
mempty


mapOpaleye :: (Opaleye.Select a -> Opaleye.Select b) -> Query a -> Query b
mapOpaleye :: (Select a -> Select b) -> Query a -> Query b
mapOpaleye Select a -> Select b
f (Query [PrimExpr] -> Select (Any, a)
a) = ([PrimExpr] -> Select (Any, b)) -> Query b
forall a. ([PrimExpr] -> Select (Any, a)) -> Query a
Query ((Select (Any, a) -> Select (Any, b))
-> ([PrimExpr] -> Select (Any, a)) -> [PrimExpr] -> Select (Any, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Select a -> Select b) -> Select (Any, a) -> Select (Any, b)
forall a b m.
(Select a -> Select b) -> Select (m, a) -> Select (m, b)
mapping Select a -> Select b
f) [PrimExpr] -> Select (Any, a)
a)


zipOpaleyeWith :: ()
  => (Opaleye.Select a -> Opaleye.Select b -> Opaleye.Select c)
  -> Query a -> Query b -> Query c
zipOpaleyeWith :: (Select a -> Select b -> Select c) -> Query a -> Query b -> Query c
zipOpaleyeWith Select a -> Select b -> Select c
f (Query [PrimExpr] -> Select (Any, a)
a) (Query [PrimExpr] -> Select (Any, b)
b) = ([PrimExpr] -> Select (Any, c)) -> Query c
forall a. ([PrimExpr] -> Select (Any, a)) -> Query a
Query (([PrimExpr] -> Select (Any, c)) -> Query c)
-> ([PrimExpr] -> Select (Any, c)) -> Query c
forall a b. (a -> b) -> a -> b
$ (Select (Any, a) -> Select (Any, b) -> Select (Any, c))
-> ([PrimExpr] -> Select (Any, a))
-> ([PrimExpr] -> Select (Any, b))
-> [PrimExpr]
-> Select (Any, c)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((Select a -> Select b -> Select c)
-> Select (Any, a) -> Select (Any, b) -> Select (Any, c)
forall m a b c.
Semigroup m =>
(Select a -> Select b -> Select c)
-> Select (m, a) -> Select (m, b) -> Select (m, c)
zipping Select a -> Select b -> Select c
f) [PrimExpr] -> Select (Any, a)
a [PrimExpr] -> Select (Any, b)
b


unsafePeekQuery :: Query a -> a
unsafePeekQuery :: Query a -> a
unsafePeekQuery (Query [PrimExpr] -> Select (Any, a)
q) = case [PrimExpr] -> Select (Any, a)
q [PrimExpr]
forall a. Monoid a => a
mempty of
  Opaleye.QueryArr ((), Tag) -> ((Any, a), Lateral -> PrimQuery -> PrimQuery, Tag)
f -> case ((), Tag) -> ((Any, a), Lateral -> PrimQuery -> PrimQuery, Tag)
f ((), Tag
Opaleye.start) of
    ((Any
_, a
a), Lateral -> PrimQuery -> PrimQuery
_, Tag
_) -> a
a


mapping :: ()
  => (Opaleye.Select a -> Opaleye.Select b)
  -> Opaleye.Select (m, a) -> Opaleye.Select (m, b)
mapping :: (Select a -> Select b) -> Select (m, a) -> Select (m, b)
mapping Select a -> Select b
f q :: Select (m, a)
q@(Opaleye.QueryArr ((), Tag) -> ((m, a), Lateral -> PrimQuery -> PrimQuery, Tag)
qa) = (((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag))
-> Select (m, b)
forall a b.
((a, Tag) -> (b, Lateral -> PrimQuery -> PrimQuery, Tag))
-> SelectArr a b
Opaleye.QueryArr ((((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag))
 -> Select (m, b))
-> (((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag))
-> Select (m, b)
forall a b. (a -> b) -> a -> b
$ \(()
_, Tag
tag) ->
  let
    ((m
m, a
_), Lateral -> PrimQuery -> PrimQuery
_, Tag
_) = ((), Tag) -> ((m, a), Lateral -> PrimQuery -> PrimQuery, Tag)
qa ((), Tag
tag)
    Opaleye.QueryArr ((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag)
qa' = (m
m,) (b -> (m, b)) -> Select b -> Select (m, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select a -> Select b
f ((m, a) -> a
forall a b. (a, b) -> b
snd ((m, a) -> a) -> Select (m, a) -> Select a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select (m, a)
q)
  in
    ((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag)
qa' ((), Tag
tag)


zipping :: Semigroup m
  => (Opaleye.Select a -> Opaleye.Select b -> Opaleye.Select c)
  -> Opaleye.Select (m, a) -> Opaleye.Select (m, b) -> Opaleye.Select (m, c)
zipping :: (Select a -> Select b -> Select c)
-> Select (m, a) -> Select (m, b) -> Select (m, c)
zipping Select a -> Select b -> Select c
f q :: Select (m, a)
q@(Opaleye.QueryArr ((), Tag) -> ((m, a), Lateral -> PrimQuery -> PrimQuery, Tag)
qa) q' :: Select (m, b)
q'@(Opaleye.QueryArr ((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag)
qa') =
  (((), Tag) -> ((m, c), Lateral -> PrimQuery -> PrimQuery, Tag))
-> Select (m, c)
forall a b.
((a, Tag) -> (b, Lateral -> PrimQuery -> PrimQuery, Tag))
-> SelectArr a b
Opaleye.QueryArr ((((), Tag) -> ((m, c), Lateral -> PrimQuery -> PrimQuery, Tag))
 -> Select (m, c))
-> (((), Tag) -> ((m, c), Lateral -> PrimQuery -> PrimQuery, Tag))
-> Select (m, c)
forall a b. (a -> b) -> a -> b
$ \(()
_, Tag
tag) ->
    let
      ((m
m, a
_), Lateral -> PrimQuery -> PrimQuery
_, Tag
_) = ((), Tag) -> ((m, a), Lateral -> PrimQuery -> PrimQuery, Tag)
qa ((), Tag
tag)
      ((m
m', b
_), Lateral -> PrimQuery -> PrimQuery
_, Tag
_) = ((), Tag) -> ((m, b), Lateral -> PrimQuery -> PrimQuery, Tag)
qa' ((), Tag
tag)
      m'' :: m
m'' = m
m m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
m'
      Opaleye.QueryArr ((), Tag) -> ((m, c), Lateral -> PrimQuery -> PrimQuery, Tag)
qa'' = (m
m'',) (c -> (m, c)) -> Select c -> Select (m, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select a -> Select b -> Select c
f ((m, a) -> a
forall a b. (a, b) -> b
snd ((m, a) -> a) -> Select (m, a) -> Select a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select (m, a)
q) ((m, b) -> b
forall a b. (a, b) -> b
snd ((m, b) -> b) -> Select (m, b) -> Select b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select (m, b)
q')
    in
      ((), Tag) -> ((m, c), Lateral -> PrimQuery -> PrimQuery, Tag)
qa'' ((), Tag
tag)