ability to order embeded items (closes #509)

This commit is contained in:
Ruslan Talpa
2016-05-21 20:52:13 +03:00
parent 2cb04c1d5c
commit 45d0f85b0d
6 changed files with 64 additions and 13 deletions
+7 -4
View File
@@ -77,8 +77,8 @@ data ApiRequest = ApiRequest {
, iFilters :: [(String, String)]
-- | &select parameter used to shape the response
, iSelect :: String
-- | &order parameter
, iOrder :: Maybe String
-- | &order parameters for each level
, iOrder :: [(String,String)]
-- | Alphabetized (canonical) request query string for response URLs
, iCanonicalQS :: String
-- | JSON Web Token
@@ -147,11 +147,11 @@ userApiRequest schema req reqBody =
, iPreferRepresentation = representation
, iPreferSingular = singular
, iPreferCount = not $ singular || hasPrefer "count=none"
, iFilters = [ (k, fromJust v) | (k,v) <- qParams, k `notElem` ["select", "order"], isJust v ]
, iFilters = [ (cs k, fromJust v) | (k,v) <- qParams, isJust v, k /= "select", not (endingIn "order" k) ]
, iSelect = if method == "DELETE"
then "*"
else fromMaybe "*" $ fromMaybe (Just "*") $ lookup "select" qParams
, iOrder = join $ lookup "order" qParams
, iOrder = [(cs k, fromJust v) | (k,v) <- qParams, isJust v, endingIn "order" k ]
, iCanonicalQS = urlEncodeVars
. sortBy (comparing fst)
. map (join (***) cs)
@@ -181,6 +181,9 @@ userApiRequest schema req reqBody =
tokenStr = case T.split (== ' ') (cs auth) of
("Bearer" : t : _) -> t
_ -> ""
endingIn:: T.Text -> T.Text -> Bool
endingIn word key = word == lastWord
where lastWord = last $ T.split (=='.') key
-- PRIVATE ---------------------------------------------------------------
+20 -8
View File
@@ -280,10 +280,10 @@ augumentRequestWithJoin schema allRels request =
buildReadRequest :: [Relation] -> ApiRequest -> Either Text ReadRequest
buildReadRequest allRels apiRequest =
augumentRequestWithJoin schema rels =<< first formatParserError (foldr addFilter <$> (addOrder <$> readRequest <*> ord) <*> flts)
augumentRequestWithJoin schema rels =<<
first formatParserError (foldr addFilter <$> (foldr addOrder <$> readRequest <*> ords) <*> flts)
where
selStr = iSelect apiRequest
orderS = iOrder apiRequest
action = iAction apiRequest
target = iTarget apiRequest
(schema, rootTableName) = fromJust $ -- Make it safe
@@ -303,9 +303,9 @@ buildReadRequest allRels apiRequest =
_ -> allRels
where fakeSourceRelations = mapMaybe (toSourceRelation rootTableName) allRels -- see comment in toSourceRelation
readRequest = parse (pRequestSelect rootName) ("failed to parse select parameter <<"++selStr++">>") selStr
addOrder (Node (q,i) f) o = Node (q{order=o}, i) f
flts = mapM pRequestFilter filters
ord = traverse (parse pOrder ("failed to parse order parameter <<"++fromMaybe "" orderS++">>")) orderS
orders = iOrder apiRequest
ords = mapM pRequestOrder orders
buildMutateRequest :: ApiRequest -> Either Text MutateRequest
buildMutateRequest apiRequest =
@@ -326,12 +326,24 @@ buildMutateRequest apiRequest =
mutateFilters = filter (not . ( '.' `elem` ) . fst) $ iFilters apiRequest -- update/delete filters can be only on the root table
cond = first formatParserError $ map snd <$> mapM pRequestFilter mutateFilters
addFilterToNode :: Filter -> ReadRequest -> ReadRequest
addFilterToNode flt (Node (q@Select {flt_=flts}, i) f) = Node (q {flt_=flt:flts}, i) f
addFilter :: (Path, Filter) -> ReadRequest -> ReadRequest
addFilter ([], flt) (Node (q@Select {flt_=flts}, i) forest) = Node (q {flt_=flt:flts}, i) forest
addFilter (path, flt) (Node rn forest) =
addFilter = addProperty addFilterToNode
addOrderToNode :: [OrderTerm] -> ReadRequest -> ReadRequest
addOrderToNode o (Node (q,i) f) = Node (q{order=Just o}, i) f
addOrder :: (Path, [OrderTerm]) -> ReadRequest -> ReadRequest
addOrder = addProperty addOrderToNode
addProperty :: (a -> ReadRequest -> ReadRequest) -> (Path, a) -> ReadRequest -> ReadRequest
addProperty f ([], a) n = f a n
addProperty f (path, a) (Node rn forest) =
case targetNode of
Nothing -> Node rn forest -- the filter is silenty dropped in the Request does not contain the required path
Just tn -> Node rn (addFilter (remainingPath, flt) tn:restForest)
Nothing -> Node rn forest -- the property is silenty dropped in the Request does not contain the required path
Just tn -> Node rn (addProperty f (remainingPath, a) tn:restForest)
where
targetNodeName:remainingPath = path
(targetNode,restForest) = splitForest targetNodeName forest
+7
View File
@@ -38,6 +38,13 @@ pRequestFilter (k, v) = (,) <$> path <*> (Filter <$> fld <*> op <*> val)
op = fst <$> opVal
val = snd <$> opVal
pRequestOrder :: (String, String) -> Either ParseError (Path, [OrderTerm])
pRequestOrder (k, v) = (,) <$> path <*> ord
where
treePath = parse pTreePath ("failed to parser tree path (" ++ k ++ ")") k
path = fst <$> treePath
ord = parse pOrder ("failed to parse order (" ++ v ++ ")") v
ws :: Parser Text
ws = cs <$> many (oneOf " \t")