{-# 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, 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 = forall a b. Unpackspec a b -> SelectArr a b
rebindExplicit 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 = 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 = forall a b. State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
selectArr forall a b. (a -> b) -> a -> b
$ do
  Tag
tag <- State Tag Tag
Tag.fresh
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ \a
a ->
    let (b
b, [(Symbol, PrimExpr)]
bindings) = forall a r. PM [a] r -> (r, [a])
PM.run (forall (f :: * -> *) columns b.
Applicative f =>
Unpackspec columns b -> (PrimExpr -> f PrimExpr) -> columns -> f b
runUnpackspec Unpackspec a b
u (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)