{-# LANGUAGE FlexibleContexts #-}

module Opaleye.Internal.Rebind where

import Data.Profunctor.Product.Default (Default, def)
import Opaleye.Internal.Unpackspec (Unpackspec, runUnpackspec)
import Opaleye.Internal.QueryArr (SelectArr(QueryArr))
import qualified Opaleye.Internal.PackMap as PM
import qualified Opaleye.Internal.PrimQuery as PQ
import qualified Opaleye.Internal.Tag as Tag

rebind :: Default Unpackspec a a => SelectArr a a
rebind :: SelectArr a a
rebind = Unpackspec a a -> SelectArr a a
forall a b. Unpackspec a b -> SelectArr a b
rebindExplicit Unpackspec a a
forall (p :: * -> * -> *) a b. Default p a b => p a b
def

rebindExplicit :: Unpackspec a b -> SelectArr a b
rebindExplicit :: Unpackspec a b -> SelectArr a b
rebindExplicit Unpackspec a b
u = ((a, Tag) -> (b, Lateral -> PrimQuery -> PrimQuery, Tag))
-> SelectArr a b
forall a b.
((a, Tag) -> (b, Lateral -> PrimQuery -> PrimQuery, Tag))
-> SelectArr a b
QueryArr (\(a
a, Tag
tag) ->
                     let (b
b, [(Symbol, PrimExpr)]
bindings) = PM [(Symbol, PrimExpr)] b -> (b, [(Symbol, PrimExpr)])
forall a r. PM [a] r -> (r, [a])
PM.run (Unpackspec a b
-> (PrimExpr
    -> StateT ([(Symbol, PrimExpr)], Int) Identity PrimExpr)
-> a
-> PM [(Symbol, PrimExpr)] b
forall (f :: * -> *) columns b.
Applicative f =>
Unpackspec columns b -> (PrimExpr -> f PrimExpr) -> columns -> f b
runUnpackspec Unpackspec a b
u (String
-> Tag
-> PrimExpr
-> StateT ([(Symbol, PrimExpr)], Int) Identity PrimExpr
forall primExpr.
String -> Tag -> primExpr -> PM [(Symbol, primExpr)] PrimExpr
PM.extractAttr String
"rebind" Tag
tag) a
a)
                     in (b
b, \Lateral
_ -> Bool -> [(Symbol, PrimExpr)] -> PrimQuery -> PrimQuery
forall a.
Bool -> [(Symbol, PrimExpr)] -> PrimQuery' a -> PrimQuery' a
PQ.Rebind Bool
True [(Symbol, PrimExpr)]
bindings, Tag -> Tag
Tag.next Tag
tag))