mirror of
https://github.com/khibino/haskell-relational-record.git
synced 2024-12-15 06:43:04 +03:00
Apply query context tag types.
This commit is contained in:
parent
3dc3098378
commit
6885e3bb1a
@ -36,7 +36,6 @@ library
|
|||||||
Database.Relational.Query.Expr.Unsafe
|
Database.Relational.Query.Expr.Unsafe
|
||||||
Database.Relational.Query.Sub
|
Database.Relational.Query.Sub
|
||||||
Database.Relational.Query.Projection
|
Database.Relational.Query.Projection
|
||||||
Database.Relational.Query.Aggregation
|
|
||||||
Database.Relational.Query.Monad.Class
|
Database.Relational.Query.Monad.Class
|
||||||
Database.Relational.Query.Monad.Trans.Ordering
|
Database.Relational.Query.Monad.Trans.Ordering
|
||||||
Database.Relational.Query.Monad.Trans.Aggregating
|
Database.Relational.Query.Monad.Trans.Aggregating
|
||||||
|
@ -16,7 +16,6 @@ module Database.Relational.Query (
|
|||||||
module Database.Relational.Query.Expr,
|
module Database.Relational.Query.Expr,
|
||||||
module Database.Relational.Query.Sub,
|
module Database.Relational.Query.Sub,
|
||||||
module Database.Relational.Query.Projection,
|
module Database.Relational.Query.Projection,
|
||||||
module Database.Relational.Query.Aggregation,
|
|
||||||
module Database.Relational.Query.Projectable,
|
module Database.Relational.Query.Projectable,
|
||||||
module Database.Relational.Query.ProjectableExtended,
|
module Database.Relational.Query.ProjectableExtended,
|
||||||
module Database.Relational.Query.Monad.Class,
|
module Database.Relational.Query.Monad.Class,
|
||||||
@ -45,7 +44,6 @@ import Database.Relational.Query.Constraint
|
|||||||
import Database.Relational.Query.Expr hiding (fromJust, just)
|
import Database.Relational.Query.Expr hiding (fromJust, just)
|
||||||
import Database.Relational.Query.Sub (SubQuery, unitSQL, queryWidth)
|
import Database.Relational.Query.Sub (SubQuery, unitSQL, queryWidth)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import Database.Relational.Query.Projectable
|
import Database.Relational.Query.Projectable
|
||||||
import Database.Relational.Query.ProjectableExtended
|
import Database.Relational.Query.ProjectableExtended
|
||||||
import Database.Relational.Query.Monad.Class
|
import Database.Relational.Query.Monad.Class
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
|
||||||
|
|
||||||
-- |
|
|
||||||
-- Module : Database.Relational.Query.Aggregation
|
|
||||||
-- Copyright : 2013 Kei Hibino
|
|
||||||
-- License : BSD3
|
|
||||||
--
|
|
||||||
-- Maintainer : ex8k.hibino@gmail.com
|
|
||||||
-- Stability : experimental
|
|
||||||
-- Portability : unknown
|
|
||||||
--
|
|
||||||
-- This module defines aggregated query projection type structure and interfaces.
|
|
||||||
module Database.Relational.Query.Aggregation (
|
|
||||||
-- * Projection definition for Aggregated query
|
|
||||||
Aggregation,
|
|
||||||
unsafeProjection,
|
|
||||||
mapAggregation,
|
|
||||||
|
|
||||||
unsafeFromProjection,
|
|
||||||
|
|
||||||
-- * Aggregated Query Projections
|
|
||||||
compose,
|
|
||||||
|
|
||||||
pi, piMaybe, piMaybe',
|
|
||||||
|
|
||||||
flattenMaybe, just
|
|
||||||
) where
|
|
||||||
|
|
||||||
|
|
||||||
import Prelude hiding (pi)
|
|
||||||
|
|
||||||
import Database.Relational.Query.Projection (Projection)
|
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
|
||||||
import Database.Relational.Query.Pi (Pi)
|
|
||||||
|
|
||||||
|
|
||||||
-- | Projection for aggregated query.
|
|
||||||
newtype Aggregation r = Aggregation (Projection r)
|
|
||||||
|
|
||||||
-- | Get projection of normal query.
|
|
||||||
unsafeProjection :: Aggregation r -> Projection r
|
|
||||||
unsafeProjection (Aggregation p) = p
|
|
||||||
|
|
||||||
-- | Map from 'Projection' into 'Aggregation'.
|
|
||||||
mapAggregation :: (Projection a -> Projection b) -> Aggregation a -> Aggregation b
|
|
||||||
mapAggregation f = Aggregation . f . unsafeProjection
|
|
||||||
|
|
||||||
-- | Unsafely make 'Aggregation' from 'Projection'.
|
|
||||||
unsafeFromProjection :: Projection r -> Aggregation r
|
|
||||||
unsafeFromProjection = Aggregation
|
|
||||||
|
|
||||||
-- | Concatenate 'Aggregation'.
|
|
||||||
compose :: Aggregation a -> Aggregation b -> Aggregation (c a b)
|
|
||||||
compose (Aggregation a) (Aggregation b) = Aggregation $ a `Projection.compose` b
|
|
||||||
|
|
||||||
-- | Map Projection path into Aggregation.
|
|
||||||
definePi :: (Projection a -> Pi a' b' -> Projection b) -> Aggregation a -> Pi a' b' -> Aggregation b
|
|
||||||
definePi (!!!) p pi' = mapAggregation (!!! pi') p
|
|
||||||
|
|
||||||
-- | Trace projection path to get smaller 'Aggregation'.
|
|
||||||
pi :: Aggregation a -- ^ Source projection. 'Maybe' type
|
|
||||||
-> Pi a b -- ^ Projection path
|
|
||||||
-> Aggregation b -- ^ Narrower projection
|
|
||||||
pi = definePi Projection.pi
|
|
||||||
|
|
||||||
-- | Trace projection path to get smaller 'Aggregation'. From 'Maybe' type to 'Maybe' type.
|
|
||||||
piMaybe :: Aggregation (Maybe a) -- ^ Source projection. 'Maybe' type
|
|
||||||
-> Pi a b -- ^ Projection path
|
|
||||||
-> Aggregation (Maybe b) -- ^ Narrower projection. 'Maybe' type result
|
|
||||||
piMaybe = definePi Projection.piMaybe
|
|
||||||
|
|
||||||
-- | Trace projection path to get smaller 'Aggregation'. From 'Maybe' type to 'Maybe' type.
|
|
||||||
-- Projection path's leaf is 'Maybe' case.
|
|
||||||
piMaybe' :: Aggregation (Maybe a) -- ^ Source projection. 'Maybe' type
|
|
||||||
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
|
||||||
-> Aggregation (Maybe b) -- ^ Narrower projection. 'Maybe' type result
|
|
||||||
piMaybe' = definePi Projection.piMaybe'
|
|
||||||
|
|
||||||
-- | Composite nested 'Maybe' on projection phantom type.
|
|
||||||
flattenMaybe :: Aggregation (Maybe (Maybe a)) -> Aggregation (Maybe a)
|
|
||||||
flattenMaybe = mapAggregation Projection.flattenMaybe
|
|
||||||
|
|
||||||
-- | Cast into 'Maybe' on projection phantom type.
|
|
||||||
just :: Aggregation a -> Aggregation (Maybe a)
|
|
||||||
just = mapAggregation Projection.just
|
|
@ -1,5 +1,3 @@
|
|||||||
{-# LANGUAGE KindSignatures #-}
|
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
-- Module : Database.Relational.Query.Expr.Unsafe
|
-- Module : Database.Relational.Query.Expr.Unsafe
|
||||||
-- Copyright : 2013 Kei Hibino
|
-- Copyright : 2013 Kei Hibino
|
||||||
@ -17,7 +15,7 @@ module Database.Relational.Query.Expr.Unsafe (
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
-- | Phantom typed SQL expression object. Project from projection type 'p'.
|
-- | Phantom typed SQL expression object. Project from projection type 'p'.
|
||||||
newtype Expr (p :: * -> *) a = Expr (String)
|
newtype Expr p a = Expr String
|
||||||
|
|
||||||
-- | Get SQL expression from typed object.
|
-- | Get SQL expression from typed object.
|
||||||
showExpr :: Expr p t -> String
|
showExpr :: Expr p t -> String
|
||||||
|
@ -20,10 +20,10 @@ module Database.Relational.Query.Internal.Product (
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude hiding (and, product)
|
import Prelude hiding (and, product)
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Expr (fromTriBool, exprAnd)
|
import Database.Relational.Query.Expr (fromTriBool, exprAnd)
|
||||||
import qualified Database.Relational.Query.Expr as Expr
|
import qualified Database.Relational.Query.Expr as Expr
|
||||||
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
|
||||||
import Database.Relational.Query.Projectable (valueTrue)
|
import Database.Relational.Query.Projectable (valueTrue)
|
||||||
import Database.Relational.Query.Sub (SubQuery, Qualified)
|
import Database.Relational.Query.Sub (SubQuery, Qualified)
|
||||||
import qualified Database.Relational.Query.Sub as SubQuery
|
import qualified Database.Relational.Query.Sub as SubQuery
|
||||||
@ -37,7 +37,7 @@ import Data.Monoid ((<>))
|
|||||||
import Data.Foldable (Foldable (foldMap))
|
import Data.Foldable (Foldable (foldMap))
|
||||||
|
|
||||||
|
|
||||||
type Expr = Expr.Expr Projection
|
type Expr = Expr.Expr Flat
|
||||||
|
|
||||||
-- | node attribute for product.
|
-- | node attribute for product.
|
||||||
data NodeAttr = Just' | Maybe
|
data NodeAttr = Just' | Maybe
|
||||||
|
@ -22,10 +22,9 @@ module Database.Relational.Query.Monad.Aggregate (
|
|||||||
toSubQuery
|
toSubQuery
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat, Aggregated)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import qualified Database.Relational.Query.Aggregation as Aggregation
|
|
||||||
import Database.Relational.Query.SQL (selectSeedSQL)
|
import Database.Relational.Query.SQL (selectSeedSQL)
|
||||||
import Database.Relational.Query.Sub (SubQuery, subQuery)
|
import Database.Relational.Query.Sub (SubQuery, subQuery)
|
||||||
|
|
||||||
@ -43,28 +42,28 @@ import Database.Relational.Query.Monad.Type (QueryCore)
|
|||||||
|
|
||||||
|
|
||||||
-- | Aggregated query monad type.
|
-- | Aggregated query monad type.
|
||||||
type QueryAggregate = Orderings Aggregation (Aggregatings QueryCore)
|
type QueryAggregate = Orderings Aggregated (Aggregatings QueryCore)
|
||||||
|
|
||||||
-- | Aggregated query type. AggregatedQuery r == QueryAggregate (Aggregation r).
|
-- | Aggregated query type. AggregatedQuery r == QueryAggregate (Projection Aggregated r).
|
||||||
type AggregatedQuery r = OrderedQuery Aggregation (Aggregatings QueryCore) r
|
type AggregatedQuery r = OrderedQuery Aggregated (Aggregatings QueryCore) r
|
||||||
|
|
||||||
-- | Lift from qualified table forms into 'QueryAggregate'.
|
-- | Lift from qualified table forms into 'QueryAggregate'.
|
||||||
aggregatedQuery :: Qualify a -> QueryAggregate a
|
aggregatedQuery :: Qualify a -> QueryAggregate a
|
||||||
aggregatedQuery = orderings . aggregatings . restrictings . join'
|
aggregatedQuery = orderings . aggregatings . restrictings . join'
|
||||||
|
|
||||||
-- | Instance to lift from qualified table forms into 'QueryAggregate'.
|
-- | Instance to lift from qualified table forms into 'QueryAggregate'.
|
||||||
instance MonadQualify Qualify (Orderings Aggregation (Aggregatings QueryCore)) where
|
instance MonadQualify Qualify (Orderings Aggregated (Aggregatings QueryCore)) where
|
||||||
liftQualify = aggregatedQuery
|
liftQualify = aggregatedQuery
|
||||||
|
|
||||||
expandPrepend :: AggregatedQuery r
|
expandPrepend :: AggregatedQuery r
|
||||||
-> Qualify ((((Aggregation r, OrderByPrepend), GroupBysPrepend), WherePrepend), FromPrepend)
|
-> Qualify ((((Projection Aggregated r, OrderByPrepend), GroupBysPrepend), WherePrepend), FromPrepend)
|
||||||
expandPrepend = extractFrom . extractWheres . extractGroupBys . extractOrderBys
|
expandPrepend = extractFrom . extractWheres . extractGroupBys . extractOrderBys
|
||||||
|
|
||||||
-- | Run 'AggregatedQuery' to get SQL string.
|
-- | Run 'AggregatedQuery' to get SQL string.
|
||||||
expandSQL :: AggregatedQuery r -> Qualify (String, Projection r)
|
expandSQL :: AggregatedQuery r -> Qualify (String, Projection Flat r)
|
||||||
expandSQL q = do
|
expandSQL q = do
|
||||||
((((aggr, ao), ag), aw), af) <- expandPrepend q
|
((((aggr, ao), ag), aw), af) <- expandPrepend q
|
||||||
let projection = Aggregation.unsafeProjection aggr
|
let projection = Projection.unsafeToFlat aggr
|
||||||
return (selectSeedSQL projection . prependFrom af . prependWhere aw
|
return (selectSeedSQL projection . prependFrom af . prependWhere aw
|
||||||
. prependGroupBys ag . prependOrderBy ao $ "",
|
. prependGroupBys ag . prependOrderBy ao $ "",
|
||||||
projection)
|
projection)
|
||||||
|
@ -20,9 +20,9 @@ module Database.Relational.Query.Monad.Class (
|
|||||||
groupBy, havingE, having
|
groupBy, havingE, having
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat, Aggregated)
|
||||||
import Database.Relational.Query.Expr (Expr)
|
import Database.Relational.Query.Expr (Expr)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import Database.Relational.Query.Projectable (expr)
|
import Database.Relational.Query.Projectable (expr)
|
||||||
import Database.Relational.Query.Sub (SubQuery, Qualified)
|
import Database.Relational.Query.Sub (SubQuery, Qualified)
|
||||||
|
|
||||||
@ -31,13 +31,13 @@ import Database.Relational.Query.Internal.Product (NodeAttr)
|
|||||||
-- | Restrict context interface
|
-- | Restrict context interface
|
||||||
class (Functor m, Monad m) => MonadRestrict m where
|
class (Functor m, Monad m) => MonadRestrict m where
|
||||||
-- | Add restriction to this context.
|
-- | Add restriction to this context.
|
||||||
restrictContext :: Expr Projection (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
restrictContext :: Expr Flat (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
||||||
-> m () -- ^ Restricted query context
|
-> m () -- ^ Restricted query context
|
||||||
|
|
||||||
-- | Query building interface.
|
-- | Query building interface.
|
||||||
class (Functor m, Monad m) => MonadQuery m where
|
class (Functor m, Monad m) => MonadQuery m where
|
||||||
-- | Add restriction to last join.
|
-- | Add restriction to last join.
|
||||||
restrictJoin :: Expr Projection (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
restrictJoin :: Expr Flat (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
||||||
-> m () -- ^ Restricted query context
|
-> m () -- ^ Restricted query context
|
||||||
-- -- | Add restriction to this query.
|
-- -- | Add restriction to this query.
|
||||||
-- restrictQuery :: Expr Projection (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
-- restrictQuery :: Expr Projection (Maybe Bool) -- ^ 'Expr' 'Projection' which represent restriction
|
||||||
@ -45,7 +45,7 @@ class (Functor m, Monad m) => MonadQuery m where
|
|||||||
-- | Unsafely join subquery with this query.
|
-- | Unsafely join subquery with this query.
|
||||||
unsafeSubQuery :: NodeAttr -- ^ Attribute maybe or just
|
unsafeSubQuery :: NodeAttr -- ^ Attribute maybe or just
|
||||||
-> Qualified SubQuery -- ^ 'SubQuery' to join
|
-> Qualified SubQuery -- ^ 'SubQuery' to join
|
||||||
-> m (Projection r) -- ^ Result joined context and 'SubQuery' result projection.
|
-> m (Projection Flat r) -- ^ Result joined context and 'SubQuery' result projection.
|
||||||
-- unsafeMergeAnotherQuery :: NodeAttr -> m (Projection r) -> m (Projection r)
|
-- unsafeMergeAnotherQuery :: NodeAttr -> m (Projection r) -> m (Projection r)
|
||||||
|
|
||||||
-- | Lift interface from base qualify monad.
|
-- | Lift interface from base qualify monad.
|
||||||
@ -57,38 +57,38 @@ class (Functor q, Monad q, MonadQuery m) => MonadQualify q m where
|
|||||||
-- | Aggregated query building interface extends 'MonadQuery'.
|
-- | Aggregated query building interface extends 'MonadQuery'.
|
||||||
class MonadQuery m => MonadAggregate m where
|
class MonadQuery m => MonadAggregate m where
|
||||||
-- | Add /group by/ term into context and get aggregated projection.
|
-- | Add /group by/ term into context and get aggregated projection.
|
||||||
aggregateKey :: Projection r -- ^ Projection to add into group by
|
aggregateKey :: Projection Flat r -- ^ Projection to add into group by
|
||||||
-> m (Aggregation r) -- ^ Result context and aggregated projection
|
-> m (Projection Aggregated r) -- ^ Result context and aggregated projection
|
||||||
-- | Add restriction to this aggregated query.
|
-- | Add restriction to this aggregated query.
|
||||||
restrictAggregatedQuery :: Expr Aggregation (Maybe Bool) -- ^ 'Expr' 'Aggregation' which represent restriction
|
restrictAggregatedQuery :: Expr Aggregated (Maybe Bool) -- ^ 'Expr' 'Aggregated' which represent restriction
|
||||||
-> m () -- ^ Restricted query context
|
-> m () -- ^ Restricted query context
|
||||||
|
|
||||||
-- | Add restriction to last join.
|
-- | Add restriction to last join.
|
||||||
onE :: MonadQuery m => Expr Projection (Maybe Bool) -> m ()
|
onE :: MonadQuery m => Expr Flat (Maybe Bool) -> m ()
|
||||||
onE = restrictJoin
|
onE = restrictJoin
|
||||||
|
|
||||||
-- | Add restriction to last join. Projection type version.
|
-- | Add restriction to last join. Projection type version.
|
||||||
on :: MonadQuery m => Projection (Maybe Bool) -> m ()
|
on :: MonadQuery m => Projection Flat (Maybe Bool) -> m ()
|
||||||
on = restrictJoin . expr
|
on = restrictJoin . expr
|
||||||
|
|
||||||
-- | Add restriction to this query.
|
-- | Add restriction to this query.
|
||||||
wheresE :: MonadRestrict m => Expr Projection (Maybe Bool) -> m ()
|
wheresE :: MonadRestrict m => Expr Flat (Maybe Bool) -> m ()
|
||||||
wheresE = restrictContext
|
wheresE = restrictContext
|
||||||
|
|
||||||
-- | Add restriction to this query. Projection type version.
|
-- | Add restriction to this query. Projection type version.
|
||||||
wheres :: MonadRestrict m => Projection (Maybe Bool) -> m ()
|
wheres :: MonadRestrict m => Projection Flat (Maybe Bool) -> m ()
|
||||||
wheres = restrictContext . expr
|
wheres = restrictContext . expr
|
||||||
|
|
||||||
-- | Add /group by/ term into context and get aggregated projection.
|
-- | Add /group by/ term into context and get aggregated projection.
|
||||||
groupBy :: MonadAggregate m
|
groupBy :: MonadAggregate m
|
||||||
=> Projection r -- ^ Projection to add into group by
|
=> Projection Flat r -- ^ Projection to add into group by
|
||||||
-> m (Aggregation r) -- ^ Result context and aggregated projection
|
-> m (Projection Aggregated r) -- ^ Result context and aggregated projection
|
||||||
groupBy = aggregateKey
|
groupBy = aggregateKey
|
||||||
|
|
||||||
-- | Add restriction to this aggregated query.
|
-- | Add restriction to this aggregated query.
|
||||||
havingE :: MonadAggregate m => Expr Aggregation (Maybe Bool) -> m ()
|
havingE :: MonadAggregate m => Expr Aggregated (Maybe Bool) -> m ()
|
||||||
havingE = restrictAggregatedQuery
|
havingE = restrictAggregatedQuery
|
||||||
|
|
||||||
-- | Add restriction to this aggregated query. Aggregation type version.
|
-- | Add restriction to this aggregated query. Aggregated Projection type version.
|
||||||
having :: MonadAggregate m => Aggregation (Maybe Bool) -> m ()
|
having :: MonadAggregate m => Projection Aggregated (Maybe Bool) -> m ()
|
||||||
having = restrictAggregatedQuery . expr
|
having = restrictAggregatedQuery . expr
|
||||||
|
@ -18,6 +18,7 @@ module Database.Relational.Query.Monad.Restrict (
|
|||||||
|
|
||||||
import Data.Functor.Identity (Identity (..), runIdentity)
|
import Data.Functor.Identity (Identity (..), runIdentity)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import Database.Relational.Query.Monad.Trans.Restricting
|
import Database.Relational.Query.Monad.Trans.Restricting
|
||||||
(Restrictings, WherePrepend, extractWheres)
|
(Restrictings, WherePrepend, extractWheres)
|
||||||
@ -29,7 +30,7 @@ type Restrict = Restrictings Identity
|
|||||||
-- | RestrictedStatement type synonym.
|
-- | RestrictedStatement type synonym.
|
||||||
-- Projection record type 'r' must be
|
-- Projection record type 'r' must be
|
||||||
-- the same as 'Restrictings' type parameter 'r'.
|
-- the same as 'Restrictings' type parameter 'r'.
|
||||||
type RestrictedStatement r a = Projection r -> Restrict a
|
type RestrictedStatement r a = Projection Flat r -> Restrict a
|
||||||
|
|
||||||
-- -- | 'return' of 'Restrict'
|
-- -- | 'return' of 'Restrict'
|
||||||
-- restricted :: a -> Restrict a
|
-- restricted :: a -> Restrict a
|
||||||
|
@ -22,6 +22,7 @@ module Database.Relational.Query.Monad.Simple (
|
|||||||
toSubQuery
|
toSubQuery
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.SQL (selectSeedSQL)
|
import Database.Relational.Query.SQL (selectSeedSQL)
|
||||||
@ -40,25 +41,25 @@ import Database.Relational.Query.Sub (SubQuery, subQuery)
|
|||||||
|
|
||||||
|
|
||||||
-- | Simple query (not-aggregated) monad type.
|
-- | Simple query (not-aggregated) monad type.
|
||||||
type QuerySimple = Orderings Projection QueryCore
|
type QuerySimple = Orderings Flat QueryCore
|
||||||
|
|
||||||
-- | Simple query (not-aggregated) query type. 'SimpleQuery' r == 'QuerySimple' ('Projection' r).
|
-- | Simple query (not-aggregated) query type. 'SimpleQuery' r == 'QuerySimple' ('Projection' r).
|
||||||
type SimpleQuery r = OrderedQuery Projection QueryCore r
|
type SimpleQuery r = OrderedQuery Flat QueryCore r
|
||||||
|
|
||||||
-- | Lift from qualified table forms into 'QuerySimple'.
|
-- | Lift from qualified table forms into 'QuerySimple'.
|
||||||
simple :: Qualify a -> QuerySimple a
|
simple :: Qualify a -> QuerySimple a
|
||||||
simple = orderings . restrictings . join'
|
simple = orderings . restrictings . join'
|
||||||
|
|
||||||
-- | Instance to lift from qualified table forms into 'QuerySimple'.
|
-- | Instance to lift from qualified table forms into 'QuerySimple'.
|
||||||
instance MonadQualify Qualify (Orderings Projection QueryCore) where
|
instance MonadQualify Qualify (Orderings Flat QueryCore) where
|
||||||
liftQualify = simple
|
liftQualify = simple
|
||||||
|
|
||||||
expandPrepend :: SimpleQuery r
|
expandPrepend :: SimpleQuery r
|
||||||
-> Qualify (((Projection r, OrderByPrepend), WherePrepend), FromPrepend)
|
-> Qualify (((Projection Flat r, OrderByPrepend), WherePrepend), FromPrepend)
|
||||||
expandPrepend = extractFrom . extractWheres . extractOrderBys
|
expandPrepend = extractFrom . extractWheres . extractOrderBys
|
||||||
|
|
||||||
-- | Run 'SimpleQuery' to get SQL string.
|
-- | Run 'SimpleQuery' to get SQL string.
|
||||||
expandSQL :: SimpleQuery r -> Qualify (String, Projection r)
|
expandSQL :: SimpleQuery r -> Qualify (String, Projection Flat r)
|
||||||
expandSQL q = do
|
expandSQL q = do
|
||||||
(((pj, ao), aw), af) <- expandPrepend q
|
(((pj, ao), aw), af) <- expandPrepend q
|
||||||
return (selectSeedSQL pj . prependFrom af . prependWhere aw . prependOrderBy ao $ "", pj)
|
return (selectSeedSQL pj . prependFrom af . prependWhere aw . prependOrderBy ao $ "", pj)
|
||||||
|
@ -15,6 +15,7 @@ module Database.Relational.Query.Monad.Target (
|
|||||||
expandPrepend
|
expandPrepend
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Table (Table)
|
import Database.Relational.Query.Table (Table)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import Database.Relational.Query.Monad.Restrict (Restrict, expandWhere)
|
import Database.Relational.Query.Monad.Restrict (Restrict, expandWhere)
|
||||||
@ -28,7 +29,7 @@ type Target r = Assignings r Restrict
|
|||||||
-- | TargetStatement type synonym.
|
-- | TargetStatement type synonym.
|
||||||
-- Table and projection record type must be
|
-- Table and projection record type must be
|
||||||
-- the same as 'Target' type parameter 'r'.
|
-- the same as 'Target' type parameter 'r'.
|
||||||
type TargetStatement r a = Table r -> Projection r -> Target r a
|
type TargetStatement r a = Table r -> Projection Flat r -> Target r a
|
||||||
|
|
||||||
-- -- | 'return' of 'Update'
|
-- -- | 'return' of 'Update'
|
||||||
-- updateStatement :: a -> Assignings r (Restrictings Identity) a
|
-- updateStatement :: a -> Assignings r (Restrictings Identity) a
|
||||||
|
@ -24,6 +24,7 @@ import Control.Monad.Trans.State (StateT, runStateT, modify)
|
|||||||
import Control.Applicative (Applicative, (<$>))
|
import Control.Applicative (Applicative, (<$>))
|
||||||
import Control.Arrow (second, (>>>))
|
import Control.Arrow (second, (>>>))
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat, Aggregated)
|
||||||
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
||||||
import Database.Relational.Query.Monad.Trans.AggregatingState
|
import Database.Relational.Query.Monad.Trans.AggregatingState
|
||||||
(AggregatingContext, primeAggregatingContext, addGroupBy, composeGroupBys)
|
(AggregatingContext, primeAggregatingContext, addGroupBy, composeGroupBys)
|
||||||
@ -31,8 +32,6 @@ import qualified Database.Relational.Query.Monad.Trans.AggregatingState as State
|
|||||||
import Database.Relational.Query.Expr (Expr)
|
import Database.Relational.Query.Expr (Expr)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import qualified Database.Relational.Query.Aggregation as Aggregation
|
|
||||||
|
|
||||||
import Database.Relational.Query.Monad.Class
|
import Database.Relational.Query.Monad.Class
|
||||||
(MonadRestrict(..), MonadQuery(..), MonadAggregate(..))
|
(MonadRestrict(..), MonadQuery(..), MonadAggregate(..))
|
||||||
@ -77,17 +76,17 @@ addGroupBys' gbs = updateAggregatingContext . foldr (>>>) id $ map addGroupBy gb
|
|||||||
|
|
||||||
-- | Add restrictions for aggregated query.
|
-- | Add restrictions for aggregated query.
|
||||||
addRestriction :: MonadQuery m
|
addRestriction :: MonadQuery m
|
||||||
=> Expr Aggregation (Maybe Bool) -- ^ Restriction to add
|
=> Expr Aggregated (Maybe Bool) -- ^ Restriction to add
|
||||||
-> Aggregatings m () -- ^ Result restricted context
|
-> Aggregatings m () -- ^ Result restricted context
|
||||||
addRestriction = updateAggregatingContext . State.addRestriction
|
addRestriction = updateAggregatingContext . State.addRestriction
|
||||||
|
|
||||||
-- | Add aggregating terms.
|
-- | Add aggregating terms.
|
||||||
addGroupBys :: MonadQuery m
|
addGroupBys :: MonadQuery m
|
||||||
=> Projection r -- ^ Group-by term to add
|
=> Projection Flat r -- ^ Group-by term to add
|
||||||
-> Aggregatings m (Aggregation r) -- ^ Result aggregated context
|
-> Aggregatings m (Projection Aggregated r) -- ^ Result aggregated context
|
||||||
addGroupBys p = do
|
addGroupBys p = do
|
||||||
addGroupBys' . Projection.columns $ p
|
addGroupBys' . Projection.columns $ p
|
||||||
return $ Aggregation.unsafeFromProjection p
|
return $ Projection.unsafeToAggregated p
|
||||||
|
|
||||||
-- | Aggregated query instance.
|
-- | Aggregated query instance.
|
||||||
instance MonadQuery m => MonadAggregate (Aggregatings m) where
|
instance MonadQuery m => MonadAggregate (Aggregatings m) where
|
||||||
|
@ -27,9 +27,9 @@ import qualified Data.DList as DList
|
|||||||
import Data.Monoid ((<>))
|
import Data.Monoid ((<>))
|
||||||
import Control.Applicative (pure)
|
import Control.Applicative (pure)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Aggregated)
|
||||||
import Database.Relational.Query.Expr (Expr, fromTriBool, exprAnd)
|
import Database.Relational.Query.Expr (Expr, fromTriBool, exprAnd)
|
||||||
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
|
|
||||||
import Language.SQL.Keyword (Keyword(..), unwordsSQL)
|
import Language.SQL.Keyword (Keyword(..), unwordsSQL)
|
||||||
import qualified Language.SQL.Keyword as SQL
|
import qualified Language.SQL.Keyword as SQL
|
||||||
@ -46,7 +46,7 @@ type GroupBys = DList GroupByTerm
|
|||||||
data AggregatingContext =
|
data AggregatingContext =
|
||||||
AggregatingContext
|
AggregatingContext
|
||||||
{ groupByTerms :: GroupBys
|
{ groupByTerms :: GroupBys
|
||||||
, restriction :: Maybe (Expr Aggregation Bool)
|
, restriction :: Maybe (Expr Aggregated Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Initial value of 'AggregatingContext'.
|
-- | Initial value of 'AggregatingContext'.
|
||||||
@ -58,7 +58,7 @@ addGroupBy :: String -> AggregatingContext -> AggregatingContext
|
|||||||
addGroupBy t c = c { groupByTerms = groupByTerms c <> pure t }
|
addGroupBy t c = c { groupByTerms = groupByTerms c <> pure t }
|
||||||
|
|
||||||
-- | Add having restriction into 'AggregatingContext'.
|
-- | Add having restriction into 'AggregatingContext'.
|
||||||
addRestriction :: Expr Aggregation (Maybe Bool) -> AggregatingContext -> AggregatingContext
|
addRestriction :: Expr Aggregated (Maybe Bool) -> AggregatingContext -> AggregatingContext
|
||||||
addRestriction e1 ctx =
|
addRestriction e1 ctx =
|
||||||
ctx { restriction = Just . uf . restriction $ ctx }
|
ctx { restriction = Just . uf . restriction $ ctx }
|
||||||
where uf Nothing = fromTriBool e1
|
where uf Nothing = fromTriBool e1
|
||||||
|
@ -23,6 +23,7 @@ module Database.Relational.Query.Monad.Trans.Assigning (
|
|||||||
SetPrepend, prependSet
|
SetPrepend, prependSet
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Control.Monad.Trans.Class (MonadTrans (lift))
|
import Control.Monad.Trans.Class (MonadTrans (lift))
|
||||||
import Control.Monad.Trans.State (StateT, runStateT, modify)
|
import Control.Monad.Trans.State (StateT, runStateT, modify)
|
||||||
import Control.Applicative (Applicative, (<$>))
|
import Control.Applicative (Applicative, (<$>))
|
||||||
@ -70,12 +71,12 @@ instance MonadRestrict m => MonadRestrict (Assignings r m) where
|
|||||||
-- | Target of assignment.
|
-- | Target of assignment.
|
||||||
newtype AssignTarget r v = AssignTarget (Table r, Pi r v)
|
newtype AssignTarget r v = AssignTarget (Table r, Pi r v)
|
||||||
|
|
||||||
targetProjection :: AssignTarget r v -> Projection v
|
targetProjection :: AssignTarget r v -> Projection Flat v
|
||||||
targetProjection (AssignTarget (tbl, pi')) =
|
targetProjection (AssignTarget (tbl, pi')) =
|
||||||
Projection.pi (Projection.unsafeFromTable tbl) pi'
|
Projection.pi (Projection.unsafeFromTable tbl) pi'
|
||||||
|
|
||||||
-- | Add an assignment.
|
-- | Add an assignment.
|
||||||
assignTo :: Monad m => Projection v -> AssignTarget r v -> Assignings r m ()
|
assignTo :: Monad m => Projection Flat v -> AssignTarget r v -> Assignings r m ()
|
||||||
assignTo vp target = updateAssigningContext . foldr (>>>) id
|
assignTo vp target = updateAssigningContext . foldr (>>>) id
|
||||||
$ zipWith updateAssignments lefts rights where
|
$ zipWith updateAssignments lefts rights where
|
||||||
lefts = Projection.columns $ targetProjection target
|
lefts = Projection.columns $ targetProjection target
|
||||||
@ -86,7 +87,7 @@ assignTo vp target = updateAssigningContext . foldr (>>>) id
|
|||||||
(!#) = curry AssignTarget
|
(!#) = curry AssignTarget
|
||||||
|
|
||||||
-- | Add and assginment.
|
-- | Add and assginment.
|
||||||
(<-#) :: Monad m => AssignTarget r v -> Projection v -> Assignings r m ()
|
(<-#) :: Monad m => AssignTarget r v -> Projection Flat v -> Assignings r m ()
|
||||||
(<-#) = flip assignTo
|
(<-#) = flip assignTo
|
||||||
|
|
||||||
infix 8 !#
|
infix 8 !#
|
||||||
|
@ -24,6 +24,7 @@ import Control.Monad.Trans.State (modify, StateT, runStateT)
|
|||||||
import Control.Applicative (Applicative, (<$>))
|
import Control.Applicative (Applicative, (<$>))
|
||||||
import Control.Arrow (second)
|
import Control.Arrow (second)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
||||||
import Database.Relational.Query.Monad.Trans.JoinState
|
import Database.Relational.Query.Monad.Trans.JoinState
|
||||||
(JoinContext, primeJoinContext, updateProduct, composeFrom)
|
(JoinContext, primeJoinContext, updateProduct, composeFrom)
|
||||||
@ -61,7 +62,7 @@ updateContext :: Monad m => (JoinContext -> JoinContext) -> QueryJoin m ()
|
|||||||
updateContext = QueryJoin . modify
|
updateContext = QueryJoin . modify
|
||||||
|
|
||||||
-- | Add last join product restriction.
|
-- | Add last join product restriction.
|
||||||
updateJoinRestriction :: Monad m => Expr Projection (Maybe Bool) -> QueryJoin m ()
|
updateJoinRestriction :: Monad m => Expr Flat (Maybe Bool) -> QueryJoin m ()
|
||||||
updateJoinRestriction e = updateContext (updateProduct d) where
|
updateJoinRestriction e = updateContext (updateProduct d) where
|
||||||
d Nothing = error "on: product is empty!"
|
d Nothing = error "on: product is empty!"
|
||||||
d (Just pt) = restrictProduct pt (fromTriBool e)
|
d (Just pt) = restrictProduct pt (fromTriBool e)
|
||||||
@ -84,7 +85,7 @@ instance (Monad q, Functor q) => MonadQuery (QueryJoin q) where
|
|||||||
unsafeSubQueryWithAttr :: Monad q
|
unsafeSubQueryWithAttr :: Monad q
|
||||||
=> NodeAttr -- ^ Attribute maybe or just
|
=> NodeAttr -- ^ Attribute maybe or just
|
||||||
-> Qualified SubQuery -- ^ 'SubQuery' to join
|
-> Qualified SubQuery -- ^ 'SubQuery' to join
|
||||||
-> QueryJoin q (Projection r) -- ^ Result joined context and 'SubQuery' result projection.
|
-> QueryJoin q (Projection Flat r) -- ^ Result joined context and 'SubQuery' result projection.
|
||||||
unsafeSubQueryWithAttr attr qsub = do
|
unsafeSubQueryWithAttr attr qsub = do
|
||||||
updateContext (updateProduct (`growProduct` (attr, qsub)))
|
updateContext (updateProduct (`growProduct` (attr, qsub)))
|
||||||
return $ Projection.unsafeFromQualifiedSubQuery qsub
|
return $ Projection.unsafeFromQualifiedSubQuery qsub
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{-# LANGUAGE KindSignatures #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
@ -34,8 +34,6 @@ import Database.Relational.Query.Monad.Trans.OrderingState
|
|||||||
(Order(Asc, Desc), OrderingContext, primeOrderingContext, updateOrderBy, composeOrderBys)
|
(Order(Asc, Desc), OrderingContext, primeOrderingContext, updateOrderBy, composeOrderBys)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import qualified Database.Relational.Query.Aggregation as Aggregation
|
|
||||||
|
|
||||||
import Database.Relational.Query.Monad.Class
|
import Database.Relational.Query.Monad.Class
|
||||||
(MonadRestrict(..), MonadQuery(..), MonadAggregate(..))
|
(MonadRestrict(..), MonadQuery(..), MonadAggregate(..))
|
||||||
@ -43,7 +41,7 @@ import Database.Relational.Query.Monad.Class
|
|||||||
|
|
||||||
-- | 'StateT' type to accumulate ordering context.
|
-- | 'StateT' type to accumulate ordering context.
|
||||||
-- Type 'p' is ordering term projection type.
|
-- Type 'p' is ordering term projection type.
|
||||||
newtype Orderings (p :: * -> *) m a =
|
newtype Orderings p m a =
|
||||||
Orderings { orderingState :: StateT OrderingContext m a }
|
Orderings { orderingState :: StateT OrderingContext m a }
|
||||||
deriving (MonadTrans, Monad, Functor, Applicative)
|
deriving (MonadTrans, Monad, Functor, Applicative)
|
||||||
|
|
||||||
@ -78,28 +76,24 @@ instance MonadAggregate m => MonadAggregate (Orderings p m) where
|
|||||||
restrictAggregatedQuery = orderings . restrictAggregatedQuery
|
restrictAggregatedQuery = orderings . restrictAggregatedQuery
|
||||||
|
|
||||||
-- | OrderedQuery type synonym. Projection must be the same as 'Orderings' type parameter 'p'
|
-- | OrderedQuery type synonym. Projection must be the same as 'Orderings' type parameter 'p'
|
||||||
type OrderedQuery p m r = Orderings p m (p r)
|
type OrderedQuery p m r = Orderings p m (Projection p r)
|
||||||
|
|
||||||
-- | Ordering term projection type interface.
|
-- | Ordering term projection type interface.
|
||||||
class OrderingTerms p where
|
class OrderingTerms p where
|
||||||
orderTerms :: p t -> [String]
|
orderTerms :: p t -> [String]
|
||||||
|
|
||||||
-- | 'Projection' is ordering term.
|
-- | 'Projection' is ordering term.
|
||||||
instance OrderingTerms Projection where
|
instance OrderingTerms (Projection c) where
|
||||||
orderTerms = Projection.columns
|
orderTerms = Projection.columns
|
||||||
|
|
||||||
-- | 'Aggregation' is ordering term.
|
|
||||||
instance OrderingTerms Aggregation where
|
|
||||||
orderTerms = Projection.columns . Aggregation.unsafeProjection
|
|
||||||
|
|
||||||
-- | Unsafely update ordering context.
|
-- | Unsafely update ordering context.
|
||||||
updateOrderingContext :: Monad m => (OrderingContext -> OrderingContext) -> Orderings p m ()
|
updateOrderingContext :: Monad m => (OrderingContext -> OrderingContext) -> Orderings p m ()
|
||||||
updateOrderingContext = Orderings . modify
|
updateOrderingContext = Orderings . modify
|
||||||
|
|
||||||
-- | Add ordering terms.
|
-- | Add ordering terms.
|
||||||
updateOrderBys :: (Monad m, OrderingTerms p)
|
updateOrderBys :: (Monad m, OrderingTerms (Projection p))
|
||||||
=> Order -- ^ Order direction
|
=> Order -- ^ Order direction
|
||||||
-> p t -- ^ Ordering terms to add
|
-> Projection p t -- ^ Ordering terms to add
|
||||||
-> Orderings p m () -- ^ Result context with ordering
|
-> Orderings p m () -- ^ Result context with ordering
|
||||||
updateOrderBys order p = updateOrderingContext . foldr (>>>) id $ updates where
|
updateOrderBys order p = updateOrderingContext . foldr (>>>) id $ updates where
|
||||||
updates = updateOrderBy order `map` orderTerms p
|
updates = updateOrderBy order `map` orderTerms p
|
||||||
@ -125,14 +119,14 @@ unsafeMergeAnotherOrderBys naR qR = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Add ascendant ordering term.
|
-- | Add ascendant ordering term.
|
||||||
asc :: (Monad m, OrderingTerms p)
|
asc :: (Monad m, OrderingTerms (Projection p))
|
||||||
=> p t -- ^ Ordering terms to add
|
=> Projection p t -- ^ Ordering terms to add
|
||||||
-> Orderings p m () -- ^ Result context with ordering
|
-> Orderings p m () -- ^ Result context with ordering
|
||||||
asc = updateOrderBys Asc
|
asc = updateOrderBys Asc
|
||||||
|
|
||||||
-- | Add descendant ordering term.
|
-- | Add descendant ordering term.
|
||||||
desc :: (Monad m, OrderingTerms p)
|
desc :: (Monad m, OrderingTerms (Projection p))
|
||||||
=> p t -- ^ Ordering terms to add
|
=> Projection p t -- ^ Ordering terms to add
|
||||||
-> Orderings p m () -- ^ Result context with ordering
|
-> Orderings p m () -- ^ Result context with ordering
|
||||||
desc = updateOrderBys Desc
|
desc = updateOrderBys Desc
|
||||||
|
|
||||||
|
@ -24,10 +24,10 @@ import Control.Monad.Trans.State (modify, StateT, runStateT)
|
|||||||
import Control.Applicative (Applicative, (<$>))
|
import Control.Applicative (Applicative, (<$>))
|
||||||
import Control.Arrow (second)
|
import Control.Arrow (second)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
import Database.Relational.Query.Monad.Trans.StatePrepend (Prepend, prepend, liftToString)
|
||||||
import Database.Relational.Query.Monad.Trans.RestrictingState
|
import Database.Relational.Query.Monad.Trans.RestrictingState
|
||||||
(RestrictContext, primeRestrictContext, addRestriction, composeWheres)
|
(RestrictContext, primeRestrictContext, addRestriction, composeWheres)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
|
||||||
import Database.Relational.Query.Expr (Expr)
|
import Database.Relational.Query.Expr (Expr)
|
||||||
|
|
||||||
import Database.Relational.Query.Monad.Class (MonadRestrict(..), MonadQuery (..))
|
import Database.Relational.Query.Monad.Class (MonadRestrict(..), MonadQuery (..))
|
||||||
@ -58,7 +58,7 @@ updateRestrictContext :: Monad m => (RestrictContext -> RestrictContext) -> Rest
|
|||||||
updateRestrictContext = Restrictings . modify
|
updateRestrictContext = Restrictings . modify
|
||||||
|
|
||||||
-- | Add whole query restriction.
|
-- | Add whole query restriction.
|
||||||
updateRestriction :: Monad m => Expr Projection (Maybe Bool) -> Restrictings m ()
|
updateRestriction :: Monad m => Expr Flat (Maybe Bool) -> Restrictings m ()
|
||||||
updateRestriction e = updateRestrictContext (addRestriction e)
|
updateRestriction e = updateRestrictContext (addRestriction e)
|
||||||
|
|
||||||
-- | 'MonadRestrict' instance.
|
-- | 'MonadRestrict' instance.
|
||||||
|
@ -20,11 +20,10 @@ module Database.Relational.Query.Monad.Trans.RestrictingState (
|
|||||||
composeWheres
|
composeWheres
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Expr (Expr, fromTriBool, exprAnd)
|
import Database.Relational.Query.Expr (Expr, fromTriBool, exprAnd)
|
||||||
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
import Database.Relational.Query.Expr.Unsafe (showExpr)
|
||||||
|
|
||||||
import Database.Relational.Query.Projection (Projection)
|
|
||||||
|
|
||||||
import Language.SQL.Keyword (Keyword(..), unwordsSQL)
|
import Language.SQL.Keyword (Keyword(..), unwordsSQL)
|
||||||
import qualified Language.SQL.Keyword as SQL
|
import qualified Language.SQL.Keyword as SQL
|
||||||
|
|
||||||
@ -32,21 +31,21 @@ import qualified Language.SQL.Keyword as SQL
|
|||||||
-- | Context type for Restrict.
|
-- | Context type for Restrict.
|
||||||
data RestrictContext =
|
data RestrictContext =
|
||||||
RestrictContext
|
RestrictContext
|
||||||
{ restriction :: Maybe (Expr Projection Bool) }
|
{ restriction :: Maybe (Expr Flat Bool) }
|
||||||
|
|
||||||
-- | Initial 'RestrictContext'.
|
-- | Initial 'RestrictContext'.
|
||||||
primeRestrictContext :: RestrictContext
|
primeRestrictContext :: RestrictContext
|
||||||
primeRestrictContext = RestrictContext Nothing
|
primeRestrictContext = RestrictContext Nothing
|
||||||
|
|
||||||
-- | Add restriction of 'RestrictContext'.
|
-- | Add restriction of 'RestrictContext'.
|
||||||
addRestriction :: Expr Projection (Maybe Bool) -> RestrictContext -> RestrictContext
|
addRestriction :: Expr Flat (Maybe Bool) -> RestrictContext -> RestrictContext
|
||||||
addRestriction e1 ctx =
|
addRestriction e1 ctx =
|
||||||
ctx { restriction = Just . uf . restriction $ ctx }
|
ctx { restriction = Just . uf . restriction $ ctx }
|
||||||
where uf Nothing = fromTriBool e1
|
where uf Nothing = fromTriBool e1
|
||||||
uf (Just e0) = e0 `exprAnd` fromTriBool e1
|
uf (Just e0) = e0 `exprAnd` fromTriBool e1
|
||||||
|
|
||||||
-- | Compose SQL String from 'RestrictContext' object.
|
-- | Compose SQL String from 'RestrictContext' object.
|
||||||
composeWheres' :: Maybe (Expr Projection Bool) -> String
|
composeWheres' :: Maybe (Expr Flat Bool) -> String
|
||||||
composeWheres' = maybe [] (\e -> unwordsSQL [WHERE, SQL.word . showExpr $ e])
|
composeWheres' = maybe [] (\e -> unwordsSQL [WHERE, SQL.word . showExpr $ e])
|
||||||
|
|
||||||
-- | Compose SQL String from 'RestrictContext' object.
|
-- | Compose SQL String from 'RestrictContext' object.
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
-- This module defines operators on various polymorphic projections.
|
-- This module defines operators on various polymorphic projections.
|
||||||
module Database.Relational.Query.Projectable (
|
module Database.Relational.Query.Projectable (
|
||||||
-- * Conversion between individual Projections
|
-- * Conversion between individual Projections
|
||||||
ExpressionProjectable (expr),
|
expr,
|
||||||
ProjectablePi (pi, piMaybe, piMaybe'),
|
-- ProjectablePi (pi, piMaybe, piMaybe'),
|
||||||
|
|
||||||
-- * Projectable from SQL strings
|
-- * Projectable from SQL strings
|
||||||
SqlProjectable (unsafeProjectSqlTerms), unsafeProjectSql,
|
SqlProjectable (unsafeProjectSqlTerms), unsafeProjectSql,
|
||||||
@ -29,7 +29,6 @@ module Database.Relational.Query.Projectable (
|
|||||||
-- * Projectable into SQL strings
|
-- * Projectable into SQL strings
|
||||||
unsafeShowSqlExpr,
|
unsafeShowSqlExpr,
|
||||||
unsafeShowSqlProjection,
|
unsafeShowSqlProjection,
|
||||||
unsafeShowSqlAggregation,
|
|
||||||
ProjectableShowSql (unsafeShowSql),
|
ProjectableShowSql (unsafeShowSql),
|
||||||
|
|
||||||
-- * Binary Operators
|
-- * Binary Operators
|
||||||
@ -72,9 +71,6 @@ import Database.Relational.Query.Pi (Pi, piZip)
|
|||||||
import Database.Relational.Query.Projection (Projection, columns, unsafeFromColumns)
|
import Database.Relational.Query.Projection (Projection, columns, unsafeFromColumns)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
|
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import qualified Database.Relational.Query.Aggregation as Aggregation
|
|
||||||
|
|
||||||
|
|
||||||
-- | Parened String.
|
-- | Parened String.
|
||||||
paren :: String -> String
|
paren :: String -> String
|
||||||
@ -88,24 +84,17 @@ sqlTermsString = d where
|
|||||||
d (cs) = paren $ intercalate ", " cs
|
d (cs) = paren $ intercalate ", " cs
|
||||||
|
|
||||||
-- | SQL expression strings which represent projection.
|
-- | SQL expression strings which represent projection.
|
||||||
sqlStringOfProjection :: Projection r -> String
|
sqlStringOfProjection :: Projection c r -> String
|
||||||
sqlStringOfProjection = sqlTermsString . columns
|
sqlStringOfProjection = sqlTermsString . columns
|
||||||
|
|
||||||
-- | 'Expr' from 'Projection'
|
-- | 'Expr' from 'Projection'
|
||||||
exprOfProjection :: Projection r -> Expr Projection r
|
exprOfProjection :: Projection c r -> Expr c r
|
||||||
exprOfProjection = UnsafeExpr.Expr . sqlStringOfProjection
|
exprOfProjection = UnsafeExpr.Expr . sqlStringOfProjection
|
||||||
|
|
||||||
-- | Projection interface into expression.
|
-- | Project from Projection type into expression type.
|
||||||
class ExpressionProjectable p where
|
expr :: Projection p a -> Expr p a
|
||||||
-- | Project from Projection type 'p' into expression type.
|
|
||||||
expr :: p a -> Expr p a
|
|
||||||
|
|
||||||
instance ExpressionProjectable Projection where
|
|
||||||
expr = exprOfProjection
|
expr = exprOfProjection
|
||||||
|
|
||||||
instance ExpressionProjectable Aggregation where
|
|
||||||
expr = UnsafeExpr.Expr . sqlStringOfProjection . Aggregation.unsafeProjection
|
|
||||||
|
|
||||||
-- | Projection interface.
|
-- | Projection interface.
|
||||||
class ProjectablePi p where
|
class ProjectablePi p where
|
||||||
-- | Trace projection path 'Pi' to get narrower projection type 'p'.
|
-- | Trace projection path 'Pi' to get narrower projection type 'p'.
|
||||||
@ -116,19 +105,14 @@ class ProjectablePi p where
|
|||||||
-- Leaf type of projection path is 'Maybe'.
|
-- Leaf type of projection path is 'Maybe'.
|
||||||
piMaybe' :: p (Maybe a) -> Pi a (Maybe b) -> p (Maybe b)
|
piMaybe' :: p (Maybe a) -> Pi a (Maybe b) -> p (Maybe b)
|
||||||
|
|
||||||
instance ProjectablePi Projection where
|
instance ProjectablePi (Projection c) where
|
||||||
pi = Projection.pi
|
pi = Projection.pi
|
||||||
piMaybe = Projection.piMaybe
|
piMaybe = Projection.piMaybe
|
||||||
piMaybe' = Projection.piMaybe'
|
piMaybe' = Projection.piMaybe'
|
||||||
|
|
||||||
instance ProjectablePi Aggregation where
|
|
||||||
pi = Aggregation.pi
|
|
||||||
piMaybe = Aggregation.piMaybe
|
|
||||||
piMaybe' = Aggregation.piMaybe'
|
|
||||||
|
|
||||||
|
|
||||||
-- | Unsafely generate 'Projection' from SQL expression strings.
|
-- | Unsafely generate 'Projection' from SQL expression strings.
|
||||||
unsafeSqlTermsProjection :: [String] -> Projection t
|
unsafeSqlTermsProjection :: [String] -> Projection c t
|
||||||
unsafeSqlTermsProjection = unsafeFromColumns
|
unsafeSqlTermsProjection = unsafeFromColumns
|
||||||
|
|
||||||
-- | Interface to project SQL terms unsafely.
|
-- | Interface to project SQL terms unsafely.
|
||||||
@ -138,17 +122,13 @@ class SqlProjectable p where
|
|||||||
-> p t -- ^ Result projection object
|
-> p t -- ^ Result projection object
|
||||||
|
|
||||||
-- | Unsafely make 'Projection' from SQL terms.
|
-- | Unsafely make 'Projection' from SQL terms.
|
||||||
instance SqlProjectable Projection where
|
instance SqlProjectable (Projection c) where
|
||||||
unsafeProjectSqlTerms = unsafeSqlTermsProjection
|
unsafeProjectSqlTerms = unsafeSqlTermsProjection
|
||||||
|
|
||||||
-- | Unsafely make 'Expr' from SQL terms.
|
-- | Unsafely make 'Expr' from SQL terms.
|
||||||
instance SqlProjectable (Expr p) where
|
instance SqlProjectable (Expr p) where
|
||||||
unsafeProjectSqlTerms = UnsafeExpr.Expr . sqlTermsString
|
unsafeProjectSqlTerms = UnsafeExpr.Expr . sqlTermsString
|
||||||
|
|
||||||
-- | Unsafely make 'Aggregation' from SQL terms.
|
|
||||||
instance SqlProjectable Aggregation where
|
|
||||||
unsafeProjectSqlTerms = Aggregation.unsafeFromProjection . unsafeProjectSqlTerms
|
|
||||||
|
|
||||||
-- | Unsafely Project single SQL term.
|
-- | Unsafely Project single SQL term.
|
||||||
unsafeProjectSql :: SqlProjectable p => String -> p t
|
unsafeProjectSql :: SqlProjectable p => String -> p t
|
||||||
unsafeProjectSql = unsafeProjectSqlTerms . (:[])
|
unsafeProjectSql = unsafeProjectSqlTerms . (:[])
|
||||||
@ -189,21 +169,13 @@ instance ProjectableShowSql (Expr p) where
|
|||||||
unsafeShowSql = unsafeShowSqlExpr
|
unsafeShowSql = unsafeShowSqlExpr
|
||||||
|
|
||||||
-- | Unsafely get SQL term from 'Proejction'.
|
-- | Unsafely get SQL term from 'Proejction'.
|
||||||
unsafeShowSqlProjection :: Projection r -> String
|
unsafeShowSqlProjection :: Projection c r -> String
|
||||||
unsafeShowSqlProjection = sqlStringOfProjection
|
unsafeShowSqlProjection = sqlStringOfProjection
|
||||||
|
|
||||||
-- | Unsafely get SQL term from 'Proejction'.
|
-- | Unsafely get SQL term from 'Proejction'.
|
||||||
instance ProjectableShowSql Projection where
|
instance ProjectableShowSql (Projection c) where
|
||||||
unsafeShowSql = unsafeShowSqlProjection
|
unsafeShowSql = unsafeShowSqlProjection
|
||||||
|
|
||||||
-- | Unsafely get SQL term from 'Aggregation'.
|
|
||||||
unsafeShowSqlAggregation :: Aggregation a -> String
|
|
||||||
unsafeShowSqlAggregation = unsafeShowSql . Aggregation.unsafeProjection
|
|
||||||
|
|
||||||
-- | Unsafely get SQL term from 'Aggregation'.
|
|
||||||
instance ProjectableShowSql Aggregation where
|
|
||||||
unsafeShowSql = unsafeShowSqlAggregation
|
|
||||||
|
|
||||||
|
|
||||||
-- | Binary operator type for SQL String.
|
-- | Binary operator type for SQL String.
|
||||||
type SqlBinOp = String -> String -> String
|
type SqlBinOp = String -> String -> String
|
||||||
@ -394,13 +366,9 @@ instance ProjectableZip PlaceHolders where
|
|||||||
projectZip PlaceHolders PlaceHolders = PlaceHolders
|
projectZip PlaceHolders PlaceHolders = PlaceHolders
|
||||||
|
|
||||||
-- | Zip 'Projection'.
|
-- | Zip 'Projection'.
|
||||||
instance ProjectableZip Projection where
|
instance ProjectableZip (Projection c) where
|
||||||
projectZip = Projection.compose
|
projectZip = Projection.compose
|
||||||
|
|
||||||
-- | Zip 'Aggregation'
|
|
||||||
instance ProjectableZip Aggregation where
|
|
||||||
projectZip = Aggregation.compose
|
|
||||||
|
|
||||||
-- | Zip 'Pi'
|
-- | Zip 'Pi'
|
||||||
instance ProjectableZip (Pi a) where
|
instance ProjectableZip (Pi a) where
|
||||||
projectZip = piZip
|
projectZip = piZip
|
||||||
@ -422,7 +390,7 @@ instance ProjectableMaybe PlaceHolders where
|
|||||||
flattenMaybe = unsafeCastPlaceHolders
|
flattenMaybe = unsafeCastPlaceHolders
|
||||||
|
|
||||||
-- | Control phantom 'Maybe' type in projection type 'Projection'.
|
-- | Control phantom 'Maybe' type in projection type 'Projection'.
|
||||||
instance ProjectableMaybe Projection where
|
instance ProjectableMaybe (Projection c) where
|
||||||
just = Projection.just
|
just = Projection.just
|
||||||
flattenMaybe = Projection.flattenMaybe
|
flattenMaybe = Projection.flattenMaybe
|
||||||
|
|
||||||
@ -431,11 +399,6 @@ instance ProjectableMaybe (Expr p) where
|
|||||||
just = Expr.just
|
just = Expr.just
|
||||||
flattenMaybe = Expr.fromJust
|
flattenMaybe = Expr.fromJust
|
||||||
|
|
||||||
-- | Control phantom 'Maybe' type in aggregate projection type 'Projection'.
|
|
||||||
instance ProjectableMaybe Aggregation where
|
|
||||||
just = Aggregation.just
|
|
||||||
flattenMaybe = Aggregation.flattenMaybe
|
|
||||||
|
|
||||||
-- | Zipping except for identity element laws.
|
-- | Zipping except for identity element laws.
|
||||||
class ProjectableZip p => ProjectableIdZip p where
|
class ProjectableZip p => ProjectableIdZip p where
|
||||||
leftId :: p ((), a) -> p a
|
leftId :: p ((), a) -> p a
|
||||||
|
@ -43,21 +43,21 @@ import Prelude hiding (pi)
|
|||||||
import Data.Int (Int32)
|
import Data.Int (Int32)
|
||||||
|
|
||||||
import qualified Language.SQL.Keyword as SQL
|
import qualified Language.SQL.Keyword as SQL
|
||||||
|
import Database.Relational.Query.Context (Flat, Aggregated)
|
||||||
import Database.Relational.Query.Expr (Expr, fromJust)
|
import Database.Relational.Query.Expr (Expr, fromJust)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.Projectable
|
import Database.Relational.Query.Projectable
|
||||||
(ExpressionProjectable (expr), ProjectablePi, PlaceHolders,
|
(expr, PlaceHolders,
|
||||||
ProjectableMaybe (flattenMaybe), ProjectableIdZip (leftId, rightId),
|
ProjectableMaybe (flattenMaybe), ProjectableIdZip (leftId, rightId),
|
||||||
SqlProjectable, unsafeProjectSql, ProjectableShowSql (unsafeShowSql))
|
SqlProjectable, unsafeProjectSql, ProjectableShowSql (unsafeShowSql))
|
||||||
import qualified Database.Relational.Query.Projectable as Projectable
|
|
||||||
import Database.Relational.Query.Pi (Pi)
|
import Database.Relational.Query.Pi (Pi)
|
||||||
|
|
||||||
|
|
||||||
-- | Projection interface.
|
-- | Projection interface.
|
||||||
class Projectable p0 p1 where
|
class Projectable p0 p1 where
|
||||||
-- | Project from projection type 'p0' into weaken projection types 'p1'.
|
-- | Project from projection type 'p0' into weaken projection types 'p1'.
|
||||||
project :: p0 a -> p1 a
|
project :: p0 c a -> p1 c a
|
||||||
|
|
||||||
-- | Parened String.
|
-- | Parened String.
|
||||||
paren :: String -> String
|
paren :: String -> String
|
||||||
@ -71,40 +71,40 @@ sqlUniOp :: SQL.Keyword -> SqlUniOp
|
|||||||
sqlUniOp kw = (SQL.wordShow kw ++) . (' ' :) . paren
|
sqlUniOp kw = (SQL.wordShow kw ++) . (' ' :) . paren
|
||||||
|
|
||||||
-- | Unsafely make aggregation uni-operator from SQL keyword.
|
-- | Unsafely make aggregation uni-operator from SQL keyword.
|
||||||
unsafeAggregateOp :: (SqlProjectable p, Projectable Aggregation p)
|
unsafeAggregateOp :: SqlProjectable (p Aggregated)
|
||||||
=> SQL.Keyword -> Projection a -> p b
|
=> SQL.Keyword -> Projection Flat a -> p Aggregated b
|
||||||
unsafeAggregateOp op = unsafeProjectSql . sqlUniOp op . unsafeShowSql
|
unsafeAggregateOp op = unsafeProjectSql . sqlUniOp op . unsafeShowSql
|
||||||
|
|
||||||
-- | Aggregation function COUNT.
|
-- | Aggregation function COUNT.
|
||||||
count :: (SqlProjectable p, Projectable Aggregation p) => Projection a -> p Int32
|
count :: SqlProjectable (p Aggregated) => Projection Flat a -> p Aggregated Int32
|
||||||
count = unsafeAggregateOp SQL.COUNT
|
count = unsafeAggregateOp SQL.COUNT
|
||||||
|
|
||||||
-- | Aggregation function SUM.
|
-- | Aggregation function SUM.
|
||||||
sum' :: (Num a, SqlProjectable p, Projectable Aggregation p) => Projection a -> p a
|
sum' :: (Num a, SqlProjectable (p Aggregated)) => Projection Flat a -> p Aggregated a
|
||||||
sum' = unsafeAggregateOp SQL.SUM
|
sum' = unsafeAggregateOp SQL.SUM
|
||||||
|
|
||||||
-- | Aggregation function AVG.
|
-- | Aggregation function AVG.
|
||||||
avg :: (Num a, Fractional b, SqlProjectable p, Projectable Aggregation p)=> Projection a -> p b
|
avg :: (Num a, Fractional b, SqlProjectable (p Aggregated))=> Projection Flat a -> p Aggregated b
|
||||||
avg = unsafeAggregateOp SQL.AVG
|
avg = unsafeAggregateOp SQL.AVG
|
||||||
|
|
||||||
-- | Aggregation function MAX.
|
-- | Aggregation function MAX.
|
||||||
max' :: (Ord a, SqlProjectable p, Projectable Aggregation p) => Projection a -> p a
|
max' :: (Ord a, SqlProjectable (p Aggregated)) => Projection Flat a -> p Aggregated a
|
||||||
max' = unsafeAggregateOp SQL.MAX
|
max' = unsafeAggregateOp SQL.MAX
|
||||||
|
|
||||||
-- | Aggregation function MIN.
|
-- | Aggregation function MIN.
|
||||||
min' :: (Ord a, SqlProjectable p, Projectable Aggregation p) => Projection a -> p a
|
min' :: (Ord a, SqlProjectable (p Aggregated)) => Projection Flat a -> p Aggregated a
|
||||||
min' = unsafeAggregateOp SQL.MIN
|
min' = unsafeAggregateOp SQL.MIN
|
||||||
|
|
||||||
-- | Aggregation function EVERY.
|
-- | Aggregation function EVERY.
|
||||||
every :: (SqlProjectable p, Projectable Aggregation p) => Projection (Maybe Bool) -> p (Maybe Bool)
|
every :: (SqlProjectable (p Aggregated)) => Projection Flat (Maybe Bool) -> p Aggregated (Maybe Bool)
|
||||||
every = unsafeAggregateOp SQL.EVERY
|
every = unsafeAggregateOp SQL.EVERY
|
||||||
|
|
||||||
-- | Aggregation function ANY.
|
-- | Aggregation function ANY.
|
||||||
any' :: (SqlProjectable p, Projectable Aggregation p) => Projection (Maybe Bool) -> p (Maybe Bool)
|
any' :: (SqlProjectable (p Aggregated)) => Projection Flat (Maybe Bool) -> p Aggregated (Maybe Bool)
|
||||||
any' = unsafeAggregateOp SQL.ANY
|
any' = unsafeAggregateOp SQL.ANY
|
||||||
|
|
||||||
-- | Aggregation function SOME.
|
-- | Aggregation function SOME.
|
||||||
some' :: (SqlProjectable p, Projectable Aggregation p) => Projection (Maybe Bool) -> p (Maybe Bool)
|
some' :: (SqlProjectable (p Aggregated)) => Projection Flat (Maybe Bool) -> p Aggregated (Maybe Bool)
|
||||||
some' = unsafeAggregateOp SQL.SOME
|
some' = unsafeAggregateOp SQL.SOME
|
||||||
|
|
||||||
-- | Project from 'Projection' into 'Projection'.
|
-- | Project from 'Projection' into 'Projection'.
|
||||||
@ -112,93 +112,75 @@ instance Projectable Projection Projection where
|
|||||||
project = id
|
project = id
|
||||||
|
|
||||||
-- | Project from 'Projection' into 'Expr' 'Projection'.
|
-- | Project from 'Projection' into 'Expr' 'Projection'.
|
||||||
instance Projectable Projection (Expr Projection) where
|
instance Projectable Projection Expr where
|
||||||
project = expr
|
project = expr
|
||||||
|
|
||||||
-- | Project from 'Aggregation' into 'Aggregation'.
|
projectPi :: Projectable Projection p1 => Projection c a -> Pi a b -> p1 c b
|
||||||
instance Projectable Aggregation Aggregation where
|
projectPi p = project . Projection.pi p
|
||||||
project = id
|
|
||||||
|
|
||||||
-- | Project from 'Aggregation' into 'Expr' 'Aggregation'.
|
projectPiMaybe :: Projectable Projection p1 => Projection c (Maybe a) -> Pi a b -> p1 c (Maybe b)
|
||||||
instance Projectable Aggregation (Expr Aggregation) where
|
projectPiMaybe p = project . Projection.piMaybe p
|
||||||
project = expr
|
|
||||||
|
|
||||||
projectPi :: (ProjectablePi p0, Projectable p0 p1) => p0 a -> Pi a b -> p1 b
|
projectPiMaybe' :: Projectable Projection p1 => Projection c (Maybe a) -> Pi a (Maybe b) -> p1 c (Maybe b)
|
||||||
projectPi p = project . Projectable.pi p
|
projectPiMaybe' p = project . Projection.piMaybe' p
|
||||||
|
|
||||||
projectPiMaybe :: (ProjectablePi p0, Projectable p0 p1) => p0 (Maybe a) -> Pi a b -> p1 (Maybe b)
|
|
||||||
projectPiMaybe p = project . Projectable.piMaybe p
|
|
||||||
|
|
||||||
projectPiMaybe' :: (ProjectablePi p0, Projectable p0 p1) => p0 (Maybe a) -> Pi a (Maybe b) -> p1 (Maybe b)
|
|
||||||
projectPiMaybe' p = project . Projectable.piMaybe' p
|
|
||||||
|
|
||||||
-- | Get narrower projection along with projection path
|
-- | Get narrower projection along with projection path
|
||||||
-- and project into result projection type.
|
-- and project into result projection type.
|
||||||
(!) :: Projectable Projection p
|
(!) :: Projectable Projection p
|
||||||
=> Projection a -- ^ Source projection
|
=> Projection c a -- ^ Source projection
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p b -- ^ Narrower projected object
|
-> p c b -- ^ Narrower projected object
|
||||||
(!) = projectPi
|
(!) = projectPi
|
||||||
|
|
||||||
-- | Get narrower projection along with projection path
|
-- | Get narrower projection along with projection path
|
||||||
-- and project into result projection type.
|
-- and project into result projection type.
|
||||||
-- 'Maybe' phantom type is propagated.
|
-- 'Maybe' phantom type is propagated.
|
||||||
(?!) :: Projectable Projection p
|
(?!) :: Projectable Projection p
|
||||||
=> Projection (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
=> Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p (Maybe b) -- ^ Narrower projected object. 'Maybe' type result
|
-> p c (Maybe b) -- ^ Narrower projected object. 'Maybe' type result
|
||||||
(?!) = projectPiMaybe
|
(?!) = projectPiMaybe
|
||||||
|
|
||||||
-- | Get narrower projection along with projection path
|
-- | Get narrower projection along with projection path
|
||||||
-- and project into result projection type.
|
-- and project into result projection type.
|
||||||
-- 'Maybe' phantom type is propagated. Projection path leaf is 'Maybe' case.
|
-- 'Maybe' phantom type is propagated. Projection path leaf is 'Maybe' case.
|
||||||
(?!?) :: Projectable Projection p
|
(?!?) :: Projectable Projection p
|
||||||
=> Projection (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
=> Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
||||||
-> p (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result
|
-> p c (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result
|
||||||
(?!?) = projectPiMaybe'
|
(?!?) = projectPiMaybe'
|
||||||
|
|
||||||
-- | Get narrower aggregated projection along with projection path
|
(<!>) :: Projectable Projection p
|
||||||
-- and project into result projection type.
|
=> Projection c a -- ^ Source projection
|
||||||
(<!>) :: Projectable Aggregation p
|
|
||||||
=> Aggregation a -- ^ Source 'Aggregation'
|
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p b -- ^ Narrower projected object
|
-> p c b -- ^ Narrower projected object
|
||||||
(<!>) = projectPi
|
(<!>) = (!)
|
||||||
|
|
||||||
-- | Get narrower aggregated projection along with projection path
|
(<?!>) :: Projectable Projection p
|
||||||
-- and project into result projection type.
|
=> Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
||||||
-- 'Maybe' phantom type is propagated.
|
|
||||||
(<?!>) :: Projectable Aggregation p
|
|
||||||
=> Aggregation (Maybe a) -- ^ Source 'Aggregation'. 'Maybe' phantom type
|
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result
|
-> p c (Maybe b) -- ^ Narrower projected object. 'Maybe' type result
|
||||||
(<?!>) = projectPiMaybe
|
(<?!>) = (?!)
|
||||||
|
|
||||||
-- | Get narrower aggregated projection along with projection path
|
(<?!?>) :: Projectable Projection p
|
||||||
-- and project into result projection type.
|
=> Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-- 'Maybe' phantom type is propagated. Projection path leaf is 'Maybe' case.
|
|
||||||
(<?!?>) :: Projectable Aggregation p
|
|
||||||
=> Aggregation (Maybe a) -- ^ Source 'Aggregation'. 'Maybe' phantom type
|
|
||||||
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
||||||
-> p (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result
|
-> p c (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result
|
||||||
(<?!?>) = projectPiMaybe'
|
(<?!?>) = (?!?)
|
||||||
|
|
||||||
-- | Get narrower projected expression along with projectino path
|
-- | Get narrower projected expression along with projectino path
|
||||||
-- and strip 'Maybe' phantom type off.
|
-- and strip 'Maybe' phantom type off.
|
||||||
(.!) :: (ProjectablePi p, Projectable p (Expr p))
|
(.!) :: Projection c (Maybe a) -- ^ Source projection type 'p'. 'Maybe' phantom type
|
||||||
=> p (Maybe a) -- ^ Source projection type 'p'. 'Maybe' phantom type
|
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> Expr p b -- ^ Narrower projected expression. 'Maybe' phantom type is stripped off
|
-> Expr c b -- ^ Narrower projected expression. 'Maybe' phantom type is stripped off
|
||||||
(.!) p = fromJust . projectPiMaybe p
|
(.!) p = fromJust . projectPiMaybe p
|
||||||
|
|
||||||
-- | Get narrower projected expression along with projectino path
|
-- | Get narrower projected expression along with projectino path
|
||||||
-- and strip 'Maybe' phantom type off.
|
-- and strip 'Maybe' phantom type off.
|
||||||
-- Projection path leaf is 'Maybe' case.
|
-- Projection path leaf is 'Maybe' case.
|
||||||
(.?) :: (ProjectablePi p, Projectable p (Expr p))
|
(.?) :: Projection c (Maybe a) -- ^ Source projection type 'p'. 'Maybe' phantom type
|
||||||
=> p (Maybe a) -- ^ Source projection type 'p'. 'Maybe' phantom type
|
|
||||||
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
||||||
-> Expr p b -- ^ Narrower projected expression. 'Maybe' phantom type is stripped off
|
-> Expr c b -- ^ Narrower projected expression. 'Maybe' phantom type is stripped off
|
||||||
(.?) p = fromJust . projectPiMaybe' p
|
(.?) p = fromJust . projectPiMaybe' p
|
||||||
|
|
||||||
|
|
||||||
@ -216,35 +198,34 @@ instance ProjectableFlattenMaybe (Maybe a) (Maybe a) where
|
|||||||
flatten = id
|
flatten = id
|
||||||
|
|
||||||
-- | Get narrower projection with flatten leaf phantom Maybe types along with projection path.
|
-- | Get narrower projection with flatten leaf phantom Maybe types along with projection path.
|
||||||
flattenPiMaybe :: (ProjectablePi p, ProjectableMaybe p, ProjectableFlattenMaybe (Maybe b) c)
|
flattenPiMaybe :: (ProjectableMaybe (Projection cont), ProjectableFlattenMaybe (Maybe b) c)
|
||||||
=> p (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
=> Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p c -- ^ Narrower 'Projection'. Flatten 'Maybe' phantom type
|
-> Projection cont c -- ^ Narrower 'Projection'. Flatten 'Maybe' phantom type
|
||||||
flattenPiMaybe p = flatten . Projectable.piMaybe p
|
flattenPiMaybe p = flatten . Projection.piMaybe p
|
||||||
|
|
||||||
projectFlattenPiMaybe :: (ProjectablePi p0, ProjectableMaybe p0, Projectable p0 p1, ProjectableFlattenMaybe (Maybe b) c)
|
projectFlattenPiMaybe :: (ProjectableMaybe (Projection cont),
|
||||||
=> p0 (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
Projectable Projection p1, ProjectableFlattenMaybe (Maybe b) c)
|
||||||
|
=> Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p1 c -- ^ Narrower 'Projection'. Flatten 'Maybe' phantom type
|
-> p1 cont c -- ^ Narrower 'Projection'. Flatten 'Maybe' phantom type
|
||||||
projectFlattenPiMaybe p = project . flattenPiMaybe p
|
projectFlattenPiMaybe p = project . flattenPiMaybe p
|
||||||
|
|
||||||
-- | Get narrower projection with flatten leaf phantom Maybe types along with projection path
|
-- | Get narrower projection with flatten leaf phantom Maybe types along with projection path
|
||||||
-- and project into result projection type.
|
-- and project into result projection type.
|
||||||
(!??) :: (ProjectableFlattenMaybe (Maybe b) c,
|
(!??) :: (ProjectableFlattenMaybe (Maybe b) c,
|
||||||
Projectable Projection p, ProjectableMaybe p)
|
Projectable Projection p, ProjectableMaybe (p cont))
|
||||||
=> Projection (Maybe a) -- ^ Source 'Aggregation'. 'Maybe' phantom type
|
=> Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p c -- ^ Narrower flatten and projected object.
|
-> p cont c -- ^ Narrower flatten and projected object.
|
||||||
(!??) = projectFlattenPiMaybe
|
(!??) = projectFlattenPiMaybe
|
||||||
|
|
||||||
-- | Get narrower aggregated projection with flatten leaf phantom Maybe types along with projection path
|
|
||||||
-- and project into result projection type.
|
|
||||||
(<!??>) :: (ProjectableFlattenMaybe (Maybe b) c,
|
(<!??>) :: (ProjectableFlattenMaybe (Maybe b) c,
|
||||||
Projectable Aggregation p, ProjectableMaybe p)
|
Projectable Projection p, ProjectableMaybe (p cont))
|
||||||
=> Aggregation (Maybe a) -- ^ Source 'Aggregation'. 'Maybe' phantom type
|
=> Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> p c -- ^ Narrower flatten and projected object.
|
-> p cont c -- ^ Narrower flatten and projected object.
|
||||||
(<!??>) = projectFlattenPiMaybe
|
(<!??>) = (!??)
|
||||||
|
|
||||||
|
|
||||||
-- | Interface to run recursively identity element laws.
|
-- | Interface to run recursively identity element laws.
|
||||||
@ -272,5 +253,5 @@ flattenPh = runIds
|
|||||||
-- => p a -> p b -> p c
|
-- => p a -> p b -> p c
|
||||||
-- (>?<) = generalizedZip'
|
-- (>?<) = generalizedZip'
|
||||||
|
|
||||||
infixl 8 !, ?!, ?!?, !??, <!>, <?!>, <?!?>, <!??>, .!, .?
|
infixl 8 !, ?!, ?!?, !??, .!, .?, <!>, <?!>, <?!?>, <!??>
|
||||||
-- infixl 1 >?<
|
-- infixl 1 >?<
|
||||||
|
@ -24,11 +24,14 @@ module Database.Relational.Query.Projection (
|
|||||||
|
|
||||||
pi, piMaybe, piMaybe',
|
pi, piMaybe, piMaybe',
|
||||||
|
|
||||||
flattenMaybe, just
|
flattenMaybe, just,
|
||||||
|
|
||||||
|
unsafeToAggregated, unsafeToFlat
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude hiding (pi)
|
import Prelude hiding (pi)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Aggregated, Flat)
|
||||||
import Database.Relational.Query.Table (Table)
|
import Database.Relational.Query.Table (Table)
|
||||||
import qualified Database.Relational.Query.Table as Table
|
import qualified Database.Relational.Query.Table as Table
|
||||||
import Database.Relational.Query.Pi (Pi)
|
import Database.Relational.Query.Pi (Pi)
|
||||||
@ -40,23 +43,23 @@ import Database.Relational.Query.Sub
|
|||||||
|
|
||||||
|
|
||||||
-- | Phantom typed projection. Projected into Haskell record type 't'.
|
-- | Phantom typed projection. Projected into Haskell record type 't'.
|
||||||
newtype Projection t = Projection { untypeProjection :: UntypedProjection }
|
newtype Projection c t = Projection { untypeProjection :: UntypedProjection }
|
||||||
|
|
||||||
typedProjection :: UntypedProjection -> Projection t
|
typedProjection :: UntypedProjection -> Projection c t
|
||||||
typedProjection = Projection
|
typedProjection = Projection
|
||||||
|
|
||||||
units :: Projection t -> [ProjectionUnit]
|
units :: Projection c t -> [ProjectionUnit]
|
||||||
units = untypeProjection
|
units = untypeProjection
|
||||||
|
|
||||||
fromUnits :: [ProjectionUnit] -> Projection t
|
fromUnits :: [ProjectionUnit] -> Projection c t
|
||||||
fromUnits = typedProjection
|
fromUnits = typedProjection
|
||||||
|
|
||||||
-- | Width of 'Projection'.
|
-- | Width of 'Projection'.
|
||||||
width :: Projection r -> Int
|
width :: Projection c r -> Int
|
||||||
width = sum . map widthOfProjectionUnit . units where
|
width = sum . map widthOfProjectionUnit . units where
|
||||||
|
|
||||||
-- | Get column SQL string of 'Projection'.
|
-- | Get column SQL string of 'Projection'.
|
||||||
column :: Projection r -- ^ Source 'Projection'
|
column :: Projection c r -- ^ Source 'Projection'
|
||||||
-> Int -- ^ Column index
|
-> Int -- ^ Column index
|
||||||
-> String -- ^ Result SQL string
|
-> String -- ^ Result SQL string
|
||||||
column = d where
|
column = d where
|
||||||
@ -68,7 +71,7 @@ column = d where
|
|||||||
| otherwise = rec us (i - widthOfProjectionUnit u)
|
| otherwise = rec us (i - widthOfProjectionUnit u)
|
||||||
|
|
||||||
-- | Get column SQL string list of projection.
|
-- | Get column SQL string list of projection.
|
||||||
columns :: Projection r -- ^ Source 'Projection'
|
columns :: Projection c r -- ^ Source 'Projection'
|
||||||
-> [String] -- ^ Result SQL string list
|
-> [String] -- ^ Result SQL string list
|
||||||
columns p = map (\n -> column p n) . take w $ [0 .. ]
|
columns p = map (\n -> column p n) . take w $ [0 .. ]
|
||||||
where w = width p
|
where w = width p
|
||||||
@ -76,53 +79,67 @@ columns p = map (\n -> column p n) . take w $ [0 .. ]
|
|||||||
|
|
||||||
-- | Unsafely generate 'Projection' from SQL string list.
|
-- | Unsafely generate 'Projection' from SQL string list.
|
||||||
unsafeFromColumns :: [String] -- ^ SQL string list specifies columns
|
unsafeFromColumns :: [String] -- ^ SQL string list specifies columns
|
||||||
-> Projection r -- ^ Result 'Projection'
|
-> Projection c r -- ^ Result 'Projection'
|
||||||
unsafeFromColumns = typedProjection . untypedProjectionFromColumns
|
unsafeFromColumns = typedProjection . untypedProjectionFromColumns
|
||||||
|
|
||||||
-- | Unsafely generate 'Projection' from qualified subquery.
|
-- | Unsafely generate 'Projection' from qualified subquery.
|
||||||
unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Projection t
|
unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Projection c t
|
||||||
unsafeFromQualifiedSubQuery = typedProjection . untypedProjectionFromSubQuery
|
unsafeFromQualifiedSubQuery = typedProjection . untypedProjectionFromSubQuery
|
||||||
|
|
||||||
-- | Unsafely generate unqualified 'Projection' from 'Table'.
|
-- | Unsafely generate unqualified 'Projection' from 'Table'.
|
||||||
unsafeFromTable :: Table r
|
unsafeFromTable :: Table r
|
||||||
-> Projection r
|
-> Projection c r
|
||||||
unsafeFromTable = unsafeFromColumns . Table.columns
|
unsafeFromTable = unsafeFromColumns . Table.columns
|
||||||
|
|
||||||
-- | Concatenate 'Projection'.
|
-- | Concatenate 'Projection'.
|
||||||
compose :: Projection a -> Projection b -> Projection (c a b)
|
compose :: Projection c a -> Projection c b -> Projection c (pair a b)
|
||||||
compose a b = fromUnits $ units a ++ units b
|
compose a b = fromUnits $ units a ++ units b
|
||||||
|
|
||||||
|
|
||||||
-- | Unsafely trace projection path.
|
-- | Unsafely trace projection path.
|
||||||
unsafeProject :: Projection a' -> Pi a b -> Projection b'
|
unsafeProject :: Projection c a' -> Pi a b -> Projection c b'
|
||||||
unsafeProject p pi' =
|
unsafeProject p pi' =
|
||||||
unsafeFromColumns
|
unsafeFromColumns
|
||||||
. (`UnsafePi.pi` pi')
|
. (`UnsafePi.pi` pi')
|
||||||
. columns $ p
|
. columns $ p
|
||||||
|
|
||||||
-- | Trace projection path to get narrower 'Projection'.
|
-- | Trace projection path to get narrower 'Projection'.
|
||||||
pi :: Projection a -- ^ Source 'Projection'
|
pi :: Projection c a -- ^ Source 'Projection'
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> Projection b -- ^ Narrower 'Projection'
|
-> Projection c b -- ^ Narrower 'Projection'
|
||||||
pi = unsafeProject
|
pi = unsafeProject
|
||||||
|
|
||||||
-- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.
|
-- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.
|
||||||
piMaybe :: Projection (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
piMaybe :: Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
||||||
-> Pi a b -- ^ Projection path
|
-> Pi a b -- ^ Projection path
|
||||||
-> Projection (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result
|
-> Projection c (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result
|
||||||
piMaybe = unsafeProject
|
piMaybe = unsafeProject
|
||||||
|
|
||||||
-- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.
|
-- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.
|
||||||
-- Leaf type of projection path is 'Maybe'.
|
-- Leaf type of projection path is 'Maybe'.
|
||||||
piMaybe' :: Projection (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
piMaybe' :: Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type
|
||||||
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
-> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf
|
||||||
-> Projection (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result
|
-> Projection c (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result
|
||||||
piMaybe' = unsafeProject
|
piMaybe' = unsafeProject
|
||||||
|
|
||||||
|
unsafeCast :: Projection c r -> Projection c r'
|
||||||
|
unsafeCast = typedProjection . untypeProjection
|
||||||
|
|
||||||
-- | Composite nested 'Maybe' on projection phantom type.
|
-- | Composite nested 'Maybe' on projection phantom type.
|
||||||
flattenMaybe :: Projection (Maybe (Maybe a)) -> Projection (Maybe a)
|
flattenMaybe :: Projection c (Maybe (Maybe a)) -> Projection c (Maybe a)
|
||||||
flattenMaybe = typedProjection . untypeProjection
|
flattenMaybe = unsafeCast
|
||||||
|
|
||||||
-- | Cast into 'Maybe' on projection phantom type.
|
-- | Cast into 'Maybe' on projection phantom type.
|
||||||
just :: Projection r -> Projection (Maybe r)
|
just :: Projection c r -> Projection c (Maybe r)
|
||||||
just = typedProjection . untypeProjection
|
just = unsafeCast
|
||||||
|
|
||||||
|
unsafeChangeContext :: Projection c r -> Projection c' r
|
||||||
|
unsafeChangeContext = typedProjection . untypeProjection
|
||||||
|
|
||||||
|
-- | Unsafely lift to aggregated context.
|
||||||
|
unsafeToAggregated :: Projection Flat r -> Projection Aggregated r
|
||||||
|
unsafeToAggregated = unsafeChangeContext
|
||||||
|
|
||||||
|
-- | Unsafely down to flat context.
|
||||||
|
unsafeToFlat :: Projection Aggregated r -> Projection Flat r
|
||||||
|
unsafeToFlat = unsafeChangeContext
|
||||||
|
@ -38,6 +38,7 @@ module Database.Relational.Query.Relation (
|
|||||||
union', except', intersect'
|
union', except', intersect'
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat, Aggregated)
|
||||||
import Database.Relational.Query.Monad.Qualify (Qualify, evalQualifyPrime, qualifyQuery)
|
import Database.Relational.Query.Monad.Qualify (Qualify, evalQualifyPrime, qualifyQuery)
|
||||||
import Database.Relational.Query.Monad.Class
|
import Database.Relational.Query.Monad.Class
|
||||||
(MonadQualify (liftQualify), MonadQuery (unsafeSubQuery), on)
|
(MonadQualify (liftQualify), MonadQuery (unsafeSubQuery), on)
|
||||||
@ -52,7 +53,6 @@ import Database.Relational.Query.Internal.Product (NodeAttr(Just', Maybe))
|
|||||||
|
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
import qualified Database.Relational.Query.Projection as Projection
|
import qualified Database.Relational.Query.Projection as Projection
|
||||||
import Database.Relational.Query.Aggregation (Aggregation)
|
|
||||||
import Database.Relational.Query.Projectable
|
import Database.Relational.Query.Projectable
|
||||||
(PlaceHolders, addPlaceHolders, projectZip)
|
(PlaceHolders, addPlaceHolders, projectZip)
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ subQueryQualifyFromRelation = d where
|
|||||||
|
|
||||||
-- | Basic monadic join operation using 'MonadQuery'.
|
-- | Basic monadic join operation using 'MonadQuery'.
|
||||||
queryWithAttr :: MonadQualify Qualify m
|
queryWithAttr :: MonadQualify Qualify m
|
||||||
=> NodeAttr -> Relation p r -> m (PlaceHolders p, Projection r)
|
=> NodeAttr -> Relation p r -> m (PlaceHolders p, Projection Flat r)
|
||||||
queryWithAttr attr = addPlaceHolders . run where
|
queryWithAttr attr = addPlaceHolders . run where
|
||||||
run rel = do
|
run rel = do
|
||||||
q <- liftQualify $ do
|
q <- liftQualify $ do
|
||||||
@ -94,42 +94,42 @@ queryWithAttr attr = addPlaceHolders . run where
|
|||||||
-- d (Relation q) = unsafeMergeAnotherQuery attr q
|
-- d (Relation q) = unsafeMergeAnotherQuery attr q
|
||||||
|
|
||||||
-- | Join subquery with place-holder parameter 'p'. query result is not 'Maybe'.
|
-- | Join subquery with place-holder parameter 'p'. query result is not 'Maybe'.
|
||||||
query' :: MonadQualify Qualify m => Relation p r -> m (PlaceHolders p, Projection r)
|
query' :: MonadQualify Qualify m => Relation p r -> m (PlaceHolders p, Projection Flat r)
|
||||||
query' = queryWithAttr Just'
|
query' = queryWithAttr Just'
|
||||||
|
|
||||||
-- | Join subquery. Query result is not 'Maybe'.
|
-- | Join subquery. Query result is not 'Maybe'.
|
||||||
query :: MonadQualify Qualify m => Relation () r -> m (Projection r)
|
query :: MonadQualify Qualify m => Relation () r -> m (Projection Flat r)
|
||||||
query = fmap snd . query'
|
query = fmap snd . query'
|
||||||
|
|
||||||
-- | Join subquery with place-holder parameter 'p'. Query result is 'Maybe'.
|
-- | Join subquery with place-holder parameter 'p'. Query result is 'Maybe'.
|
||||||
queryMaybe' :: MonadQualify Qualify m => Relation p r -> m (PlaceHolders p, Projection (Maybe r))
|
queryMaybe' :: MonadQualify Qualify m => Relation p r -> m (PlaceHolders p, Projection Flat (Maybe r))
|
||||||
queryMaybe' pr = do
|
queryMaybe' pr = do
|
||||||
(ph, pj) <- queryWithAttr Maybe pr
|
(ph, pj) <- queryWithAttr Maybe pr
|
||||||
return (ph, Projection.just pj)
|
return (ph, Projection.just pj)
|
||||||
|
|
||||||
-- | Join subquery. Query result is 'Maybe'.
|
-- | Join subquery. Query result is 'Maybe'.
|
||||||
queryMaybe :: MonadQualify Qualify m => Relation () r -> m (Projection (Maybe r))
|
queryMaybe :: MonadQualify Qualify m => Relation () r -> m (Projection Flat (Maybe r))
|
||||||
queryMaybe = fmap snd . queryMaybe'
|
queryMaybe = fmap snd . queryMaybe'
|
||||||
|
|
||||||
-- | Finalize 'QuerySimple' monad and generate 'Relation'.
|
-- | Finalize 'QuerySimple' monad and generate 'Relation'.
|
||||||
relation :: QuerySimple (Projection r) -> Relation () r
|
relation :: QuerySimple (Projection Flat r) -> Relation () r
|
||||||
relation = SimpleRel
|
relation = SimpleRel
|
||||||
|
|
||||||
-- | Finalize 'QuerySimple' monad and generate 'Relation' with place-holder parameter 'p'.
|
-- | Finalize 'QuerySimple' monad and generate 'Relation' with place-holder parameter 'p'.
|
||||||
relation' :: QuerySimple (PlaceHolders p, Projection r) -> Relation p r
|
relation' :: QuerySimple (PlaceHolders p, Projection Flat r) -> Relation p r
|
||||||
relation' = SimpleRel . fmap snd
|
relation' = SimpleRel . fmap snd
|
||||||
|
|
||||||
-- | Finalize 'QueryAggregate' monad and geneate 'Relation'.
|
-- | Finalize 'QueryAggregate' monad and geneate 'Relation'.
|
||||||
aggregateRelation :: QueryAggregate (Aggregation r) -> Relation () r
|
aggregateRelation :: QueryAggregate (Projection Aggregated r) -> Relation () r
|
||||||
aggregateRelation = AggregateRel
|
aggregateRelation = AggregateRel
|
||||||
|
|
||||||
-- | Finalize 'QueryAggregate' monad and geneate 'Relation' with place-holder parameter 'p'.
|
-- | Finalize 'QueryAggregate' monad and geneate 'Relation' with place-holder parameter 'p'.
|
||||||
aggregateRelation' :: QueryAggregate (PlaceHolders p, Aggregation r) -> Relation p r
|
aggregateRelation' :: QueryAggregate (PlaceHolders p, Projection Aggregated r) -> Relation p r
|
||||||
aggregateRelation' = AggregateRel . fmap snd
|
aggregateRelation' = AggregateRel . fmap snd
|
||||||
|
|
||||||
|
|
||||||
-- | Restriction function type for direct style join operator.
|
-- | Restriction function type for direct style join operator.
|
||||||
type JoinRestriction a b = Projection a -> Projection b -> Projection (Maybe Bool)
|
type JoinRestriction a b = Projection Flat a -> Projection Flat b -> Projection Flat (Maybe Bool)
|
||||||
|
|
||||||
unsafeCastPlaceHolder :: Relation a r -> Relation b r
|
unsafeCastPlaceHolder :: Relation a r -> Relation b r
|
||||||
unsafeCastPlaceHolder = d where
|
unsafeCastPlaceHolder = d where
|
||||||
@ -146,8 +146,8 @@ leftPh :: Relation (p, ()) r -> Relation p r
|
|||||||
leftPh = unsafeCastPlaceHolder
|
leftPh = unsafeCastPlaceHolder
|
||||||
|
|
||||||
-- | Basic direct join operation with place-holder parameters.
|
-- | Basic direct join operation with place-holder parameters.
|
||||||
join' :: (qa -> QuerySimple (PlaceHolders pa, Projection a))
|
join' :: (qa -> QuerySimple (PlaceHolders pa, Projection Flat a))
|
||||||
-> (qb -> QuerySimple (PlaceHolders pb, Projection b))
|
-> (qb -> QuerySimple (PlaceHolders pb, Projection Flat b))
|
||||||
-> qa
|
-> qa
|
||||||
-> qb
|
-> qb
|
||||||
-> [JoinRestriction a b]
|
-> [JoinRestriction a b]
|
||||||
@ -187,8 +187,8 @@ full' :: Relation pa a -- ^ Left query to join
|
|||||||
full' = join' queryMaybe' queryMaybe'
|
full' = join' queryMaybe' queryMaybe'
|
||||||
|
|
||||||
-- | Basic direct join operation.
|
-- | Basic direct join operation.
|
||||||
join :: (qa -> QuerySimple (Projection a))
|
join :: (qa -> QuerySimple (Projection Flat a))
|
||||||
-> (qb -> QuerySimple (Projection b))
|
-> (qb -> QuerySimple (Projection Flat b))
|
||||||
-> qa
|
-> qa
|
||||||
-> qb
|
-> qb
|
||||||
-> [JoinRestriction a b]
|
-> [JoinRestriction a b]
|
||||||
|
@ -25,6 +25,7 @@ module Database.Relational.Query.Restriction (
|
|||||||
|
|
||||||
import Database.Record (PersistableWidth)
|
import Database.Record (PersistableWidth)
|
||||||
|
|
||||||
|
import Database.Relational.Query.Context (Flat)
|
||||||
import Database.Relational.Query.Pi (id')
|
import Database.Relational.Query.Pi (id')
|
||||||
import Database.Relational.Query.Table (Table)
|
import Database.Relational.Query.Table (Table)
|
||||||
import Database.Relational.Query.Projection (Projection)
|
import Database.Relational.Query.Projection (Projection)
|
||||||
@ -38,14 +39,15 @@ import Database.Relational.Query.Monad.Trans.Restricting (prependWhere)
|
|||||||
import Database.Relational.Query.Monad.Restrict (Restrict, RestrictedStatement, expandWhere)
|
import Database.Relational.Query.Monad.Restrict (Restrict, RestrictedStatement, expandWhere)
|
||||||
import Database.Relational.Query.Monad.Target (Target, TargetStatement, expandPrepend)
|
import Database.Relational.Query.Monad.Target (Target, TargetStatement, expandPrepend)
|
||||||
|
|
||||||
|
|
||||||
-- | Restriction type with place-holder parameter 'p' and projection record type 'r'.
|
-- | Restriction type with place-holder parameter 'p' and projection record type 'r'.
|
||||||
newtype Restriction p r = Restriction (Projection r -> Restrict ())
|
newtype Restriction p r = Restriction (Projection Flat r -> Restrict ())
|
||||||
|
|
||||||
-- | Not finalized 'Restrict' monad type.
|
-- | Not finalized 'Restrict' monad type.
|
||||||
type RestrictionContext p r = RestrictedStatement r (PlaceHolders p)
|
type RestrictionContext p r = RestrictedStatement r (PlaceHolders p)
|
||||||
|
|
||||||
-- | Finalize 'Restrict' monad and generate 'Restriction'.
|
-- | Finalize 'Restrict' monad and generate 'Restriction'.
|
||||||
restriction :: (Projection r -> Restrict ()) -> Restriction () r
|
restriction :: (Projection Flat r -> Restrict ()) -> Restriction () r
|
||||||
restriction = Restriction
|
restriction = Restriction
|
||||||
|
|
||||||
-- | Finalize 'Restrict' monad and generate 'Restriction' with place-holder parameter 'p'
|
-- | Finalize 'Restrict' monad and generate 'Restriction' with place-holder parameter 'p'
|
||||||
@ -65,13 +67,13 @@ sqlWhereFromRestriction tbl (Restriction q) = prependWhere aw
|
|||||||
|
|
||||||
-- | UpdateTarget type with place-holder parameter 'p' and projection record type 'r'.
|
-- | UpdateTarget type with place-holder parameter 'p' and projection record type 'r'.
|
||||||
newtype UpdateTarget p r =
|
newtype UpdateTarget p r =
|
||||||
UpdateTarget (Table r -> Projection r -> Target r ())
|
UpdateTarget (Table r -> Projection Flat r -> Target r ())
|
||||||
|
|
||||||
-- | Not finalized 'Target' monad type.
|
-- | Not finalized 'Target' monad type.
|
||||||
type UpdateTargetContext p r = TargetStatement r (PlaceHolders p)
|
type UpdateTargetContext p r = TargetStatement r (PlaceHolders p)
|
||||||
|
|
||||||
-- | Finalize 'Target' monad and generate 'UpdateTarget'.
|
-- | Finalize 'Target' monad and generate 'UpdateTarget'.
|
||||||
updateTarget :: (Table r -> Projection r -> Target r ())
|
updateTarget :: (Table r -> Projection Flat r -> Target r ())
|
||||||
-> UpdateTarget () r
|
-> UpdateTarget () r
|
||||||
updateTarget = UpdateTarget
|
updateTarget = UpdateTarget
|
||||||
|
|
||||||
@ -107,13 +109,13 @@ liftTargetAllColumn' rs = updateTarget' $ updateAllColumn rs
|
|||||||
|
|
||||||
-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all.
|
-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all.
|
||||||
updateTargetAllColumn :: PersistableWidth r
|
updateTargetAllColumn :: PersistableWidth r
|
||||||
=> (Projection r -> Restrict ())
|
=> (Projection Flat r -> Restrict ())
|
||||||
-> UpdateTarget r r
|
-> UpdateTarget r r
|
||||||
updateTargetAllColumn = liftTargetAllColumn . restriction
|
updateTargetAllColumn = liftTargetAllColumn . restriction
|
||||||
|
|
||||||
-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.
|
-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.
|
||||||
updateTargetAllColumn' :: PersistableWidth r
|
updateTargetAllColumn' :: PersistableWidth r
|
||||||
=> (Projection r -> Restrict (PlaceHolders p))
|
=> (Projection Flat r -> Restrict (PlaceHolders p))
|
||||||
-> UpdateTarget (r, p) r
|
-> UpdateTarget (r, p) r
|
||||||
updateTargetAllColumn' = liftTargetAllColumn' . restriction'
|
updateTargetAllColumn' = liftTargetAllColumn' . restriction'
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ import qualified Database.Relational.Query.Projection as Projection
|
|||||||
|
|
||||||
|
|
||||||
-- | Generate select SQL. Seed SQL string append to this.
|
-- | Generate select SQL. Seed SQL string append to this.
|
||||||
selectSeedSQL :: Projection r -> ShowS
|
selectSeedSQL :: Projection c r -> ShowS
|
||||||
selectSeedSQL pj =
|
selectSeedSQL pj =
|
||||||
(unwordsSQL [SELECT, columns' `SQL.sepBy` ", "] ++)
|
(unwordsSQL [SELECT, columns' `SQL.sepBy` ", "] ++)
|
||||||
where columns' = zipWith
|
where columns' = zipWith
|
||||||
|
Loading…
Reference in New Issue
Block a user