mirror of
https://github.com/khibino/haskell-relational-record.git
synced 2024-12-13 07:56:32 +03:00
ORDER BY support.
This commit is contained in:
parent
7824af3a78
commit
c11310fc59
@ -21,4 +21,4 @@ import Database.Relational.Query.Projection
|
|||||||
value, valueTrue, valueFalse, valueNull, placeholder)
|
value, valueTrue, valueFalse, valueNull, placeholder)
|
||||||
import Database.Relational.Query.Relation (Relation)
|
import Database.Relational.Query.Relation (Relation)
|
||||||
import Database.Relational.Query.Join
|
import Database.Relational.Query.Join
|
||||||
import Database.Relational.Query.Type (Query, untypeQuery, toQuery)
|
import Database.Relational.Query.Type (Query, untypeQuery, fromRelation)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
module Database.Relational.Query.Join (
|
module Database.Relational.Query.Join (
|
||||||
QueryJoin,
|
QueryJoin,
|
||||||
|
|
||||||
on, wheres,
|
on, wheres, asc, desc,
|
||||||
table,
|
table,
|
||||||
|
|
||||||
record, expr, compose, (>*<), (!), (!?), relation,
|
record, expr, compose, (>*<), (!), (!?), relation,
|
||||||
@ -25,7 +25,7 @@ import qualified Database.Relational.Query.AliasId as AliasId
|
|||||||
import Database.Relational.Query.Table (Table)
|
import Database.Relational.Query.Table (Table)
|
||||||
import Database.Relational.Query.Sub (SubQuery)
|
import Database.Relational.Query.Sub (SubQuery)
|
||||||
|
|
||||||
import Database.Relational.Query.Expr (Expr)
|
import Database.Relational.Query.Expr (Expr, showExpr)
|
||||||
import qualified Database.Relational.Query.Expr as Expr
|
import qualified Database.Relational.Query.Expr as Expr
|
||||||
|
|
||||||
import Database.Relational.Query.Product
|
import Database.Relational.Query.Product
|
||||||
@ -37,17 +37,18 @@ import qualified Database.Relational.Query.Projection as Projection
|
|||||||
|
|
||||||
import Database.Relational.Query.Pi (Pi)
|
import Database.Relational.Query.Pi (Pi)
|
||||||
|
|
||||||
import Database.Relational.Query.Relation (Relation, finalizeRelation)
|
import Database.Relational.Query.Relation (Relation, finalizeRelation, Order(Asc, Desc))
|
||||||
import qualified Database.Relational.Query.Relation as Relation
|
import qualified Database.Relational.Query.Relation as Relation
|
||||||
|
|
||||||
data Context = Context
|
data Context = Context
|
||||||
{ currentAliasId :: AliasId
|
{ currentAliasId :: AliasId
|
||||||
, product :: Maybe QueryProduct
|
, product :: Maybe QueryProduct
|
||||||
, restriction :: Maybe (Expr Bool)
|
, restriction :: Maybe (Expr Bool)
|
||||||
|
, orderByRev :: [(Order, String)]
|
||||||
}
|
}
|
||||||
|
|
||||||
primContext :: Context
|
primContext :: Context
|
||||||
primContext = Context primAlias Nothing Nothing
|
primContext = Context primAlias Nothing Nothing []
|
||||||
|
|
||||||
nextAliasContext :: Context -> Context
|
nextAliasContext :: Context -> Context
|
||||||
nextAliasContext s = s { currentAliasId = newAliasId (currentAliasId s) }
|
nextAliasContext s = s { currentAliasId = newAliasId (currentAliasId s) }
|
||||||
@ -62,6 +63,10 @@ updateRestriction' e1 ctx =
|
|||||||
where uf Nothing = e1
|
where uf Nothing = e1
|
||||||
uf (Just e0) = e0 `Expr.and` e1
|
uf (Just e0) = e0 `Expr.and` e1
|
||||||
|
|
||||||
|
updateOrderBy' :: Order -> Expr t -> Context -> Context
|
||||||
|
updateOrderBy' order e ctx =
|
||||||
|
ctx { orderByRev = ((order, showExpr e) :) . orderByRev $ ctx }
|
||||||
|
|
||||||
|
|
||||||
newtype QueryJoin a =
|
newtype QueryJoin a =
|
||||||
QueryJoin { runQueryJoin :: Context -> (a, Context) }
|
QueryJoin { runQueryJoin :: Context -> (a, Context) }
|
||||||
@ -89,6 +94,9 @@ updateJoinRestriction e = updateContext (updateProduct' d) where
|
|||||||
updateRestriction :: Expr Bool -> QueryJoin ()
|
updateRestriction :: Expr Bool -> QueryJoin ()
|
||||||
updateRestriction e = updateContext (updateRestriction' e)
|
updateRestriction e = updateContext (updateRestriction' e)
|
||||||
|
|
||||||
|
updateOrderBy :: Order -> Expr t -> QueryJoin ()
|
||||||
|
updateOrderBy order e = updateContext (updateOrderBy' order e)
|
||||||
|
|
||||||
|
|
||||||
on :: Expr Bool -> QueryJoin ()
|
on :: Expr Bool -> QueryJoin ()
|
||||||
on = updateJoinRestriction
|
on = updateJoinRestriction
|
||||||
@ -96,6 +104,12 @@ on = updateJoinRestriction
|
|||||||
wheres :: Expr Bool -> QueryJoin ()
|
wheres :: Expr Bool -> QueryJoin ()
|
||||||
wheres = updateRestriction
|
wheres = updateRestriction
|
||||||
|
|
||||||
|
asc :: Expr t -> QueryJoin ()
|
||||||
|
asc = updateOrderBy Asc
|
||||||
|
|
||||||
|
desc :: Expr t -> QueryJoin ()
|
||||||
|
desc = updateOrderBy Desc
|
||||||
|
|
||||||
|
|
||||||
table :: Table r -> Relation r
|
table :: Table r -> Relation r
|
||||||
table = Relation.fromTable
|
table = Relation.fromTable
|
||||||
@ -157,7 +171,7 @@ from :: Table r -> QueryJoin (Projection r)
|
|||||||
from = inner . table
|
from = inner . table
|
||||||
|
|
||||||
relation :: QueryJoin (Projection r) -> Relation r
|
relation :: QueryJoin (Projection r) -> Relation r
|
||||||
relation q = finalizeRelation projection product' (restriction st) where
|
relation q = finalizeRelation projection product' (restriction st) (orderByRev st) where
|
||||||
(projection, st) = runQueryPrime q
|
(projection, st) = runQueryPrime q
|
||||||
product' = maybe (error "relation: empty product!") Product.tree $ product st
|
product' = maybe (error "relation: empty product!") Product.tree $ product st
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module Database.Relational.Query.Relation (
|
module Database.Relational.Query.Relation (
|
||||||
|
|
||||||
|
Order (..),
|
||||||
Relation,
|
Relation,
|
||||||
|
|
||||||
outer,
|
outer,
|
||||||
@ -13,6 +15,7 @@ module Database.Relational.Query.Relation (
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Prelude hiding (product, and)
|
import Prelude hiding (product, and)
|
||||||
|
import Data.List (foldl')
|
||||||
|
|
||||||
import Database.Relational.Query.AliasId (asColumnN)
|
import Database.Relational.Query.AliasId (asColumnN)
|
||||||
|
|
||||||
@ -33,11 +36,14 @@ import Language.SQL.Keyword (Keyword(..), unwordsSQL)
|
|||||||
import qualified Language.SQL.Keyword as SQL
|
import qualified Language.SQL.Keyword as SQL
|
||||||
|
|
||||||
|
|
||||||
|
data Order = Asc | Desc
|
||||||
|
|
||||||
data Relation r = Table (Table r)
|
data Relation r = Table (Table r)
|
||||||
| Relation
|
| Relation
|
||||||
{ projection :: Projection r
|
{ projection :: Projection r
|
||||||
, product :: Product
|
, product :: Product
|
||||||
, restriction :: Maybe (Expr Bool)
|
, restriction :: Maybe (Expr Bool)
|
||||||
|
, orderByRev :: [(Order, String)]
|
||||||
}
|
}
|
||||||
|
|
||||||
outer :: Relation r -> Relation (Maybe r)
|
outer :: Relation r -> Relation (Maybe r)
|
||||||
@ -53,17 +59,23 @@ width = d where
|
|||||||
fromTable :: Table r -> Relation r
|
fromTable :: Table r -> Relation r
|
||||||
fromTable = Table
|
fromTable = Table
|
||||||
|
|
||||||
composedSQL :: Projection r -> Product -> Maybe (Expr Bool) -> String
|
composedSQL :: Projection r -> Product -> Maybe (Expr Bool) -> [(Order, String)] -> String
|
||||||
composedSQL pj pd re =
|
composedSQL pj pd re odRev =
|
||||||
unwordsSQL
|
unwordsSQL
|
||||||
$ [SELECT, columns' `SQL.sepBy` SQL.word ", ",
|
$ [SELECT, columns' `SQL.sepBy` ", ",
|
||||||
FROM, SQL.word . productSQL $ pd ]
|
FROM, SQL.word . productSQL $ pd]
|
||||||
++ wheres re
|
++ wheres re
|
||||||
|
++ orders
|
||||||
where columns' = zipWith
|
where columns' = zipWith
|
||||||
(\f n -> SQL.word f `asColumnN` n)
|
(\f n -> SQL.word f `asColumnN` n)
|
||||||
(Projection.columns pj)
|
(Projection.columns pj)
|
||||||
[(0 :: Int)..]
|
[(0 :: Int)..]
|
||||||
wheres = maybe [] (\e -> [WHERE, SQL.word . showExpr $ e])
|
wheres = maybe [] (\e -> [WHERE, SQL.word . showExpr $ e])
|
||||||
|
order Asc = ASC
|
||||||
|
order Desc = DESC
|
||||||
|
orderList = foldl' (\ r (o, e) -> [SQL.word e, order o] `SQL.sepBy` " " : r) [] odRev
|
||||||
|
orders | null odRev = []
|
||||||
|
| otherwise = [ORDER, BY, orderList `SQL.sepBy` ", "]
|
||||||
|
|
||||||
toSubQuery :: Relation r -> SubQuery
|
toSubQuery :: Relation r -> SubQuery
|
||||||
toSubQuery = d where
|
toSubQuery = d where
|
||||||
@ -72,10 +84,12 @@ toSubQuery = d where
|
|||||||
(composedSQL
|
(composedSQL
|
||||||
(projection rel)
|
(projection rel)
|
||||||
(product rel)
|
(product rel)
|
||||||
(restriction rel))
|
(restriction rel)
|
||||||
|
(orderByRev rel)
|
||||||
|
)
|
||||||
(width rel)
|
(width rel)
|
||||||
|
|
||||||
finalizeRelation :: Projection r -> Product -> Maybe (Expr Bool) -> Relation r
|
finalizeRelation :: Projection r -> Product -> Maybe (Expr Bool) -> [(Order, String)] -> Relation r
|
||||||
finalizeRelation = Relation
|
finalizeRelation = Relation
|
||||||
|
|
||||||
toSQL :: Relation r -> String
|
toSQL :: Relation r -> String
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
module Database.Relational.Query.Type (
|
module Database.Relational.Query.Type (
|
||||||
Query (untypeQuery), unsafeTypedQuery, toQuery
|
Query (untypeQuery), unsafeTypedQuery, fromRelation
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Database.Relational.Query.Relation (Relation)
|
import Database.Relational.Query.Relation (Relation)
|
||||||
@ -15,5 +15,5 @@ instance Show (Query p a) where
|
|||||||
show = untypeQuery
|
show = untypeQuery
|
||||||
|
|
||||||
|
|
||||||
toQuery :: Relation r -> Query p r
|
fromRelation :: Relation r -> Query p r
|
||||||
toQuery = unsafeTypedQuery . Relation.toSQL
|
fromRelation = unsafeTypedQuery . Relation.toSQL
|
||||||
|
Loading…
Reference in New Issue
Block a user