module Opaleye.Internal.Rebind where

import Data.Profunctor.Product.Default (Default, def)
import Opaleye.Internal.Unpackspec (Unpackspec, runUnpackspec)
import Opaleye.Internal.QueryArr (selectArr, SelectArr)
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 :: forall a. Default Unpackspec a a => 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 :: forall a b. Unpackspec a b -> SelectArr a b
rebindExplicit = String -> Unpackspec a b -> SelectArr a b
forall a b. String -> Unpackspec a b -> SelectArr a b
rebindExplicitPrefix String
"rebind"

rebindExplicitPrefix :: String -> Unpackspec a b -> SelectArr a b
rebindExplicitPrefix :: forall a b. String -> Unpackspec a b -> SelectArr a b
rebindExplicitPrefix String
prefix Unpackspec a b
u = State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
selectArr (State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b)
-> State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> b) -> a -> b
$ do
  Tag
tag <- State Tag Tag
Tag.fresh
  (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr)))
-> (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a b. (a -> b) -> a -> b
$ \a
a ->
    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
prefix Tag
tag) a
a)
    in (b
b, [(Symbol, PrimExpr)] -> PrimQueryArr
PQ.aRebind [(Symbol, PrimExpr)]
bindings)

rebindExplicitPrefixNoStar :: String -> Unpackspec a b -> SelectArr a b
rebindExplicitPrefixNoStar :: forall a b. String -> Unpackspec a b -> SelectArr a b
rebindExplicitPrefixNoStar String
prefix Unpackspec a b
u = State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
selectArr (State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b)
-> State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> b) -> a -> b
$ do
  Tag
tag <- State Tag Tag
Tag.fresh
  (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr)))
-> (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a b. (a -> b) -> a -> b
$ \a
a ->
    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
prefix Tag
tag) a
a)
    in (b
b, [(Symbol, PrimExpr)] -> PrimQueryArr
PQ.aRebindNoStar [(Symbol, PrimExpr)]
bindings)