module Database.Beam.Query.Internal where
import Database.Beam.Backend.Types
import Database.Beam.Backend.SQL
import Database.Beam.Schema.Tables
import Data.String
import qualified Data.Text as T
import qualified Data.DList as DList
import Data.Typeable
import Data.Vector.Sized (Vector)
import Control.Monad.Free.Church
import Control.Monad.State
import Control.Monad.Writer
import GHC.TypeLits
import GHC.Types
type ProjectibleInSelectSyntax syntax a =
( IsSql92SelectSyntax syntax
, Eq (Sql92SelectExpressionSyntax syntax)
, Sql92ProjectionExpressionSyntax (Sql92SelectProjectionSyntax syntax) ~ Sql92SelectExpressionSyntax syntax
, Sql92TableSourceSelectSyntax (Sql92FromTableSourceSyntax (Sql92SelectFromSyntax syntax)) ~ syntax
, Projectible (Sql92ProjectionExpressionSyntax (Sql92SelectTableProjectionSyntax (Sql92SelectSelectTableSyntax syntax))) a
, ProjectibleValue (Sql92ProjectionExpressionSyntax (Sql92SelectTableProjectionSyntax (Sql92SelectSelectTableSyntax syntax))) a)
type TablePrefix = T.Text
data QF select (db :: (* -> *) -> *) s next where
QDistinct :: Projectible (Sql92SelectExpressionSyntax select) r
=> (r -> WithExprContext (Sql92SelectTableSetQuantifierSyntax (Sql92SelectSelectTableSyntax select)))
-> QM select db s r
-> (r -> next)
-> QF select db s next
QAll :: Beamable table
=> T.Text -> TableSettings table
-> (table (QExpr (Sql92SelectExpressionSyntax select) s) -> Maybe (WithExprContext (Sql92SelectExpressionSyntax select)))
-> (table (QExpr (Sql92SelectExpressionSyntax select) s) -> next) -> QF select db s next
QArbitraryJoin :: Projectible (Sql92SelectExpressionSyntax select) r
=> QM select db (QNested s) r
-> (Sql92SelectFromSyntax select -> Sql92SelectFromSyntax select ->
Maybe (Sql92FromExpressionSyntax (Sql92SelectFromSyntax select)) ->
Sql92SelectFromSyntax select)
-> (r -> Maybe (WithExprContext (Sql92SelectExpressionSyntax select)))
-> (r -> next)
-> QF select db s next
QTwoWayJoin :: ( Projectible (Sql92SelectExpressionSyntax select) a
, Projectible (Sql92SelectExpressionSyntax select) b )
=> QM select db (QNested s) a
-> QM select db (QNested s) b
-> (Sql92SelectFromSyntax select -> Sql92SelectFromSyntax select ->
Maybe (Sql92FromExpressionSyntax (Sql92SelectFromSyntax select)) ->
Sql92SelectFromSyntax select)
-> ((a, b) -> Maybe (WithExprContext (Sql92SelectExpressionSyntax select)))
-> ((a, b) -> next)
-> QF select db s next
QSubSelect :: Projectible (Sql92SelectExpressionSyntax select) r =>
QM select db (QNested s) r -> (r -> next) -> QF select db s next
QGuard :: WithExprContext (Sql92SelectExpressionSyntax select) -> next -> QF select db s next
QLimit :: Projectible (Sql92SelectExpressionSyntax select) r => Integer -> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QOffset :: Projectible (Sql92SelectExpressionSyntax select) r => Integer -> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QUnion ::Projectible (Sql92SelectExpressionSyntax select) r => Bool -> QM select db (QNested s) r -> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QIntersect :: Projectible (Sql92SelectExpressionSyntax select) r => Bool -> QM select db (QNested s) r -> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QExcept :: Projectible (Sql92SelectExpressionSyntax select) r => Bool -> QM select db (QNested s) r -> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QOrderBy :: Projectible (Sql92SelectExpressionSyntax select) r =>
(r -> WithExprContext [ Sql92SelectOrderingSyntax select ])
-> QM select db (QNested s) r -> (r -> next) -> QF select db s next
QWindowOver :: ( ProjectibleWithPredicate WindowFrameContext (Sql2003ExpressionWindowFrameSyntax (Sql92SelectExpressionSyntax select)) window
, Projectible (Sql92SelectExpressionSyntax select) r
, Projectible (Sql92SelectExpressionSyntax select) a )
=> (r -> window) -> (r -> window -> a)
-> QM select db (QNested s) r -> (a -> next) -> QF select db s next
QAggregate :: ( Projectible (Sql92SelectExpressionSyntax select) grouping
, Projectible (Sql92SelectExpressionSyntax select) a ) =>
(a -> TablePrefix -> (Maybe (Sql92SelectGroupingSyntax select), grouping)) ->
QM select db (QNested s) a ->
(grouping -> next) -> QF select db s next
deriving instance Functor (QF select db s)
type QM select db s = F (QF select db s)
newtype Q syntax (db :: (* -> *) -> *) s a
= Q { runQ :: QM syntax db s a }
deriving (Monad, Applicative, Functor)
data QInternal
data QNested s
data QField s ty
= QField
{ qFieldTblName :: T.Text
, qFieldName :: T.Text }
deriving (Show, Eq, Ord)
data QAssignment fieldName expr s
= QAssignment [(fieldName, expr)]
deriving (Show, Eq, Ord)
data QAggregateContext
data QGroupingContext
data QValueContext
data QOrderingContext
data QWindowingContext
data QWindowFrameContext
newtype QGenExpr context syntax s t = QExpr (TablePrefix -> syntax)
type WithExprContext a = TablePrefix -> a
type QExpr = QGenExpr QValueContext
type QAgg = QGenExpr QAggregateContext
type QOrd = QGenExpr QOrderingContext
type QWindowExpr = QGenExpr QWindowingContext
type QWindowFrame = QGenExpr QWindowFrameContext
type QGroupExpr = QGenExpr QGroupingContext
instance Eq syntax => Eq (QGenExpr context syntax s t) where
QExpr a == QExpr b = a "" == b ""
instance Retaggable (QGenExpr ctxt expr s) (QGenExpr ctxt expr s t) where
type Retag tag (QGenExpr ctxt expr s t) = Columnar (tag (QGenExpr ctxt expr s)) t
retag f e = case f (Columnar' e) of
Columnar' a -> a
newtype QWindow syntax s = QWindow (WithExprContext syntax)
newtype QFrameBounds syntax = QFrameBounds (Maybe syntax)
newtype QFrameBound syntax = QFrameBound syntax
qBinOpE :: forall syntax context s a b c. IsSql92ExpressionSyntax syntax =>
(syntax -> syntax -> syntax)
-> QGenExpr context syntax s a -> QGenExpr context syntax s b
-> QGenExpr context syntax s c
qBinOpE mkOpE (QExpr a) (QExpr b) = QExpr (mkOpE <$> a <*> b)
unsafeRetype :: QGenExpr ctxt syntax s a -> QGenExpr ctxt syntax s a'
unsafeRetype (QExpr v) = QExpr v
instance ( IsSql92ExpressionSyntax syntax
, HasSqlValueSyntax (Sql92ExpressionValueSyntax syntax) [Char] ) =>
IsString (QGenExpr context syntax s T.Text) where
fromString = QExpr . pure . valueE . sqlValueSyntax
instance (Num a
, IsSql92ExpressionSyntax syntax
, HasSqlValueSyntax (Sql92ExpressionValueSyntax syntax) a) =>
Num (QGenExpr context syntax s a) where
fromInteger x = let res :: QGenExpr context syntax s a
res = QExpr (pure (valueE (sqlValueSyntax (fromIntegral x :: a))))
in res
QExpr a + QExpr b = QExpr (addE <$> a <*> b)
QExpr a QExpr b = QExpr (subE <$> a <*> b)
QExpr a * QExpr b = QExpr (mulE <$> a <*> b)
negate (QExpr a) = QExpr (negateE <$> a)
abs (QExpr x) = QExpr (absE <$> x)
signum _ = error "signum: not defined for QExpr. Use CASE...WHEN"
instance ( Fractional a
, IsSql92ExpressionSyntax syntax
, HasSqlValueSyntax (Sql92ExpressionValueSyntax syntax) a ) =>
Fractional (QGenExpr context syntax s a) where
QExpr a / QExpr b = QExpr (divE <$> a <*> b)
recip = (1.0 /)
fromRational = QExpr . pure . valueE . sqlValueSyntax . (id :: a -> a) . fromRational
data Aggregation syntax s a
= GroupAgg syntax
| ProjectAgg syntax
class Typeable context => AggregateContext context
instance (IsAggregateContext a, Typeable a) => AggregateContext a
type family ContextName a :: Symbol
type instance ContextName QValueContext = "a value"
type instance ContextName QWindowingContext = "a window expression"
type instance ContextName QWindowFrameContext = "a window frame"
type instance ContextName QOrderingContext = "an ordering expression"
type instance ContextName QAggregateContext = "an aggregate"
type instance ContextName QGroupingContext = "an aggregate grouping"
type family IsAggregateContext a :: Constraint where
IsAggregateContext QAggregateContext = ()
IsAggregateContext QGroupingContext = ()
IsAggregateContext a = TypeError ('Text "Non-aggregate expression where aggregate expected." :$$:
('Text "Got " :<>: 'Text (ContextName a) :<>: 'Text ". Expected an aggregate or a grouping") :$$:
AggregateContextSuggestion a)
type family AggregateContextSuggestion a :: ErrorMessage where
AggregateContextSuggestion QValueContext = 'Text "Perhaps you forgot to wrap a value expression with 'group_'"
AggregateContextSuggestion QWindowingContext = 'Text "Perhaps you meant to use 'window_' instead of 'aggregate_'"
AggregateContextSuggestion QOrderingContext = 'Text "You cannot use an ordering in an aggregate"
AggregateContextSuggestion b = 'Text ""
class Typeable context => ValueContext context
instance (IsValueContext a, Typeable a, a ~ QValueContext) => ValueContext a
class Typeable context => WindowFrameContext context
instance (Typeable context, IsWindowFrameContext context, context ~ QWindowFrameContext) =>
WindowFrameContext context
type family IsWindowFrameContext a :: Constraint where
IsWindowFrameContext QWindowFrameContext = ()
IsWindowFrameContext a = TypeError ('Text "Expected window frame." :$$:
('Text "Got " :<>: 'Text (ContextName a) :<>: 'Text ". Expected a window frame"))
class AnyType a
instance AnyType a
type family IsValueContext a :: Constraint where
IsValueContext QValueContext = ()
IsValueContext a = TypeError ('Text "Non-scalar context in projection" :$$:
('Text "Got " :<>: 'Text (ContextName a) :<>: 'Text ". Expected a value") :$$:
ValueContextSuggestion a)
type family ValueContextSuggestion a :: ErrorMessage where
ValueContextSuggestion QWindowingContext = 'Text "Use 'window_' to projecct aggregate expressions to the value level"
ValueContextSuggestion QOrderingContext = 'Text "An ordering context cannot be used in a projection. Try removing the 'asc_' or 'desc_', or use 'orderBy_' to sort the result set"
ValueContextSuggestion QAggregateContext = ('Text "Aggregate functions and groupings cannot be contained in value expressions." :$$:
'Text "Use 'aggregate_' to compute aggregations at the value level.")
ValueContextSuggestion QGroupingContext = ValueContextSuggestion QAggregateContext
ValueContextSuggestion _ = 'Text ""
type Projectible = ProjectibleWithPredicate AnyType
type ProjectibleValue = ProjectibleWithPredicate ValueContext
class ThreadRewritable (s :: *) (a :: *) | a -> s where
type WithRewrittenThread s (s' :: *) a :: *
rewriteThread :: Proxy s' -> a -> WithRewrittenThread s s' a
instance Beamable tbl => ThreadRewritable s (tbl (QGenExpr ctxt syntax s)) where
type WithRewrittenThread s s' (tbl (QGenExpr ctxt syntax s)) = tbl (QGenExpr ctxt syntax s')
rewriteThread _ = changeBeamRep (\(Columnar' (QExpr a)) -> Columnar' (QExpr a))
instance Beamable tbl => ThreadRewritable s (tbl (Nullable (QGenExpr ctxt syntax s))) where
type WithRewrittenThread s s' (tbl (Nullable (QGenExpr ctxt syntax s))) = tbl (Nullable (QGenExpr ctxt syntax s'))
rewriteThread _ = changeBeamRep (\(Columnar' (QExpr a)) -> Columnar' (QExpr a))
instance ThreadRewritable s (QGenExpr ctxt syntax s a) where
type WithRewrittenThread s s' (QGenExpr ctxt syntax s a) = QGenExpr ctxt syntax s' a
rewriteThread _ (QExpr a) = QExpr a
instance ThreadRewritable s a => ThreadRewritable s [a] where
type WithRewrittenThread s s' [a] = [WithRewrittenThread s s' a]
rewriteThread s' qs = map (rewriteThread s') qs
instance (ThreadRewritable s a, KnownNat n) => ThreadRewritable s (Vector n a) where
type WithRewrittenThread s s' (Vector n a) = Vector n (WithRewrittenThread s s' a)
rewriteThread s' qs = fmap (rewriteThread s') qs
instance ( ThreadRewritable s a, ThreadRewritable s b ) =>
ThreadRewritable s (a, b) where
type WithRewrittenThread s s' (a, b) = (WithRewrittenThread s s' a, WithRewrittenThread s s' b)
rewriteThread s' (a, b) = (rewriteThread s' a, rewriteThread s' b)
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c ) =>
ThreadRewritable s (a, b, c) where
type WithRewrittenThread s s' (a, b, c) =
(WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c)
rewriteThread s' (a, b, c) = (rewriteThread s' a, rewriteThread s' b, rewriteThread s' c)
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c, ThreadRewritable s d ) =>
ThreadRewritable s (a, b, c, d) where
type WithRewrittenThread s s' (a, b, c, d) =
(WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c, WithRewrittenThread s s' d)
rewriteThread s' (a, b, c, d) =
(rewriteThread s' a, rewriteThread s' b, rewriteThread s' c, rewriteThread s' d)
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c, ThreadRewritable s d
, ThreadRewritable s e ) =>
ThreadRewritable s (a, b, c, d, e) where
type WithRewrittenThread s s' (a, b, c, d, e) =
( WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c, WithRewrittenThread s s' d
, WithRewrittenThread s s' e )
rewriteThread s' (a, b, c, d, e) =
( rewriteThread s' a, rewriteThread s' b, rewriteThread s' c, rewriteThread s' d
, rewriteThread s' e)
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c, ThreadRewritable s d
, ThreadRewritable s e, ThreadRewritable s f ) =>
ThreadRewritable s (a, b, c, d, e, f) where
type WithRewrittenThread s s' (a, b, c, d, e, f) =
( WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c, WithRewrittenThread s s' d
, WithRewrittenThread s s' e, WithRewrittenThread s s' f )
rewriteThread s' (a, b, c, d, e, f) =
( rewriteThread s' a, rewriteThread s' b, rewriteThread s' c, rewriteThread s' d
, rewriteThread s' e, rewriteThread s' f)
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c, ThreadRewritable s d
, ThreadRewritable s e, ThreadRewritable s f, ThreadRewritable s g ) =>
ThreadRewritable s (a, b, c, d, e, f, g) where
type WithRewrittenThread s s' (a, b, c, d, e, f, g) =
( WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c, WithRewrittenThread s s' d
, WithRewrittenThread s s' e, WithRewrittenThread s s' f, WithRewrittenThread s s' g)
rewriteThread s' (a, b, c, d, e, f, g) =
( rewriteThread s' a, rewriteThread s' b, rewriteThread s' c, rewriteThread s' d
, rewriteThread s' e, rewriteThread s' f, rewriteThread s' g )
instance ( ThreadRewritable s a, ThreadRewritable s b, ThreadRewritable s c, ThreadRewritable s d
, ThreadRewritable s e, ThreadRewritable s f, ThreadRewritable s g, ThreadRewritable s h ) =>
ThreadRewritable s (a, b, c, d, e, f, g, h) where
type WithRewrittenThread s s' (a, b, c, d, e, f, g, h) =
( WithRewrittenThread s s' a, WithRewrittenThread s s' b, WithRewrittenThread s s' c, WithRewrittenThread s s' d
, WithRewrittenThread s s' e, WithRewrittenThread s s' f, WithRewrittenThread s s' g, WithRewrittenThread s s' h)
rewriteThread s' (a, b, c, d, e, f, g, h) =
( rewriteThread s' a, rewriteThread s' b, rewriteThread s' c, rewriteThread s' d
, rewriteThread s' e, rewriteThread s' f, rewriteThread s' g, rewriteThread s' h )
class ContextRewritable a where
type WithRewrittenContext a ctxt :: *
rewriteContext :: Proxy ctxt -> a -> WithRewrittenContext a ctxt
instance Beamable tbl => ContextRewritable (tbl (QGenExpr old syntax s)) where
type WithRewrittenContext (tbl (QGenExpr old syntax s)) ctxt = tbl (QGenExpr ctxt syntax s)
rewriteContext _ = changeBeamRep (\(Columnar' (QExpr a)) -> Columnar' (QExpr a))
instance Beamable tbl => ContextRewritable (tbl (Nullable (QGenExpr old syntax s))) where
type WithRewrittenContext (tbl (Nullable (QGenExpr old syntax s))) ctxt = tbl (Nullable (QGenExpr ctxt syntax s))
rewriteContext _ = changeBeamRep (\(Columnar' (QExpr a)) -> Columnar' (QExpr a))
instance ContextRewritable (QGenExpr old syntax s a) where
type WithRewrittenContext (QGenExpr old syntax s a) ctxt = QGenExpr ctxt syntax s a
rewriteContext _ (QExpr a) = QExpr a
instance ContextRewritable a => ContextRewritable [a] where
type WithRewrittenContext [a] ctxt = [ WithRewrittenContext a ctxt ]
rewriteContext p as = map (rewriteContext p) as
instance (ContextRewritable a, KnownNat n) => ContextRewritable (Vector n a) where
type WithRewrittenContext (Vector n a) ctxt = Vector n (WithRewrittenContext a ctxt)
rewriteContext p as = fmap (rewriteContext p) as
instance (ContextRewritable a, ContextRewritable b) => ContextRewritable (a, b) where
type WithRewrittenContext (a, b) ctxt = (WithRewrittenContext a ctxt, WithRewrittenContext b ctxt)
rewriteContext p (a, b) = (rewriteContext p a, rewriteContext p b)
instance (ContextRewritable a, ContextRewritable b, ContextRewritable c) => ContextRewritable (a, b, c) where
type WithRewrittenContext (a, b, c) ctxt = (WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt)
rewriteContext p (a, b, c) = (rewriteContext p a, rewriteContext p b, rewriteContext p c)
instance ( ContextRewritable a, ContextRewritable b, ContextRewritable c
, ContextRewritable d ) => ContextRewritable (a, b, c, d) where
type WithRewrittenContext (a, b, c, d) ctxt =
( WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt
, WithRewrittenContext d ctxt )
rewriteContext p (a, b, c, d) = ( rewriteContext p a, rewriteContext p b, rewriteContext p c
, rewriteContext p d )
instance ( ContextRewritable a, ContextRewritable b, ContextRewritable c
, ContextRewritable d, ContextRewritable e ) =>
ContextRewritable (a, b, c, d, e) where
type WithRewrittenContext (a, b, c, d, e) ctxt =
( WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt
, WithRewrittenContext d ctxt, WithRewrittenContext e ctxt )
rewriteContext p (a, b, c, d, e) = ( rewriteContext p a, rewriteContext p b, rewriteContext p c
, rewriteContext p d, rewriteContext p e )
instance ( ContextRewritable a, ContextRewritable b, ContextRewritable c
, ContextRewritable d, ContextRewritable e, ContextRewritable f ) =>
ContextRewritable (a, b, c, d, e, f) where
type WithRewrittenContext (a, b, c, d, e, f) ctxt =
( WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt
, WithRewrittenContext d ctxt, WithRewrittenContext e ctxt, WithRewrittenContext f ctxt )
rewriteContext p (a, b, c, d, e, f) = ( rewriteContext p a, rewriteContext p b, rewriteContext p c
, rewriteContext p d, rewriteContext p e, rewriteContext p f )
instance ( ContextRewritable a, ContextRewritable b, ContextRewritable c
, ContextRewritable d, ContextRewritable e, ContextRewritable f
, ContextRewritable g ) =>
ContextRewritable (a, b, c, d, e, f, g) where
type WithRewrittenContext (a, b, c, d, e, f, g) ctxt =
( WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt
, WithRewrittenContext d ctxt, WithRewrittenContext e ctxt, WithRewrittenContext f ctxt
, WithRewrittenContext g ctxt )
rewriteContext p (a, b, c, d, e, f, g) =
( rewriteContext p a, rewriteContext p b, rewriteContext p c
, rewriteContext p d, rewriteContext p e, rewriteContext p f
, rewriteContext p g )
instance ( ContextRewritable a, ContextRewritable b, ContextRewritable c
, ContextRewritable d, ContextRewritable e, ContextRewritable f
, ContextRewritable g, ContextRewritable h ) =>
ContextRewritable (a, b, c, d, e, f, g, h) where
type WithRewrittenContext (a, b, c, d, e, f, g, h) ctxt =
( WithRewrittenContext a ctxt, WithRewrittenContext b ctxt, WithRewrittenContext c ctxt
, WithRewrittenContext d ctxt, WithRewrittenContext e ctxt, WithRewrittenContext f ctxt
, WithRewrittenContext g ctxt, WithRewrittenContext h ctxt )
rewriteContext p (a, b, c, d, e, f, g, h) =
( rewriteContext p a, rewriteContext p b, rewriteContext p c
, rewriteContext p d, rewriteContext p e, rewriteContext p f
, rewriteContext p g, rewriteContext p h )
class ProjectibleWithPredicate (contextPredicate :: * -> Constraint) syntax a | a -> syntax where
project' :: Monad m => Proxy contextPredicate
-> (forall context. contextPredicate context => Proxy context -> WithExprContext syntax -> m (WithExprContext syntax))
-> a -> m a
instance (Beamable t, contextPredicate context) => ProjectibleWithPredicate contextPredicate syntax (t (QGenExpr context syntax s)) where
project' _ mutateM a =
zipBeamFieldsM (\(Columnar' (QExpr e)) _ ->
Columnar' . QExpr <$> mutateM (Proxy @context) e) a a
instance (Beamable t, contextPredicate context) => ProjectibleWithPredicate contextPredicate syntax (t (Nullable (QGenExpr context syntax s))) where
project' _ mutateM a =
zipBeamFieldsM (\(Columnar' (QExpr e)) _ ->
Columnar' . QExpr <$> mutateM (Proxy @context) e) a a
instance ProjectibleWithPredicate WindowFrameContext syntax (QWindow syntax s) where
project' _ mutateM (QWindow a) =
QWindow <$> mutateM (Proxy @QWindowFrameContext) a
instance contextPredicate context => ProjectibleWithPredicate contextPredicate syntax (QGenExpr context syntax s a) where
project' _ mkE (QExpr a) = QExpr <$> mkE (Proxy @context) a
instance ProjectibleWithPredicate contextPredicate syntax a => ProjectibleWithPredicate contextPredicate syntax [a] where
project' p mkE as = traverse (project' p mkE) as
instance (ProjectibleWithPredicate contextPredicate syntax a, KnownNat n) => ProjectibleWithPredicate contextPredicate syntax (Vector n a) where
project' p mkE as = traverse (project' p mkE) as
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b) where
project' p mkE (a, b) = (,) <$> project' p mkE a <*> project' p mkE b
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c) where
project' p mkE (a, b, c) = (,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c
, ProjectibleWithPredicate contextPredicate syntax d ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c, d) where
project' p mkE (a, b, c, d) = (,,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
<*> project' p mkE d
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c
, ProjectibleWithPredicate contextPredicate syntax d, ProjectibleWithPredicate contextPredicate syntax e ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c, d, e) where
project' p mkE (a, b, c, d, e) = (,,,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
<*> project' p mkE d <*> project' p mkE e
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c
, ProjectibleWithPredicate contextPredicate syntax d, ProjectibleWithPredicate contextPredicate syntax e, ProjectibleWithPredicate contextPredicate syntax f ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c, d, e, f) where
project' p mkE (a, b, c, d, e, f) = (,,,,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
<*> project' p mkE d <*> project' p mkE e <*> project' p mkE f
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c
, ProjectibleWithPredicate contextPredicate syntax d, ProjectibleWithPredicate contextPredicate syntax e, ProjectibleWithPredicate contextPredicate syntax f
, ProjectibleWithPredicate contextPredicate syntax g ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c, d, e, f, g) where
project' p mkE (a, b, c, d, e, f, g) =
(,,,,,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
<*> project' p mkE d <*> project' p mkE e <*> project' p mkE f
<*> project' p mkE g
instance ( ProjectibleWithPredicate contextPredicate syntax a, ProjectibleWithPredicate contextPredicate syntax b, ProjectibleWithPredicate contextPredicate syntax c
, ProjectibleWithPredicate contextPredicate syntax d, ProjectibleWithPredicate contextPredicate syntax e, ProjectibleWithPredicate contextPredicate syntax f
, ProjectibleWithPredicate contextPredicate syntax g, ProjectibleWithPredicate contextPredicate syntax h ) =>
ProjectibleWithPredicate contextPredicate syntax (a, b, c, d, e, f, g, h) where
project' p mkE (a, b, c, d, e, f, g, h) =
(,,,,,,,) <$> project' p mkE a <*> project' p mkE b <*> project' p mkE c
<*> project' p mkE d <*> project' p mkE e <*> project' p mkE f
<*> project' p mkE g <*> project' p mkE h
project :: Projectible syntax a => a -> WithExprContext [ syntax ]
project = sequenceA . DList.toList . execWriter . project' (Proxy @AnyType) (\_ e -> tell (DList.singleton e) >> pure e)
reproject :: (IsSql92ExpressionSyntax syntax, Projectible syntax a) =>
(Int -> syntax) -> a -> a
reproject mkField a =
evalState (project' (Proxy @AnyType) (\_ _ -> state (\i -> (i, i + 1)) >>= pure . pure . mkField) a) 0