{-# language FlexibleContexts #-}

module Rel8.Query.Rebind
  ( rebind
  )
where

-- base
import Prelude
import Control.Arrow ((<<<))

-- opaleye
import qualified Opaleye.Internal.Rebind as Opaleye

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Query ( Query )
import Rel8.Table ( Table )
import Rel8.Table.Opaleye ( unpackspec )
import Rel8.Query.Opaleye (fromOpaleye)


-- | 'rebind' takes a variable name, some expressions, and binds each of them
-- to a new variable in the SQL. The @a@ returned consists only of these
-- variables. It's essentially a @let@ binding for Postgres expressions.
rebind :: Table Expr a => String -> a -> Query a
rebind :: String -> a -> Query a
rebind String
prefix a
a = Select a -> Query a
forall a. Select a -> Query a
fromOpaleye (String -> Unpackspec a a -> SelectArr a a
forall a b. String -> Unpackspec a b -> SelectArr a b
Opaleye.rebindExplicitPrefix String
prefix Unpackspec a a
forall a. Table Expr a => Unpackspec a a
unpackspec SelectArr a a -> Select a -> Select a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< a -> Select a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)