Merge pull request #625 from ruslantalpa/return_data_on_delete

Implement select/return representation for DELETE queries (fix #518)
This commit is contained in:
Joe Nelson
2016-06-02 08:38:46 -07:00
4 changed files with 33 additions and 8 deletions
+2 -1
View File
@@ -12,7 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Accept posts from HTML forms - @begriffs
- Ability to order embedded entities - @ruslantalpa
- Ability to paginate using &limit and &offset parameters - @ruslantalpa
- Ability to apply limits to embedded entities and enforce --max-rows on all levels - @ruslantalpa, @begriffs
- Ability to apply limits to embedded entities and enforce --max-rows on all levels - @ruslantalpa, @begriffs
### Fixed
- Return 401 or 403 for access denied rather than 404 - @begriffs
@@ -22,6 +22,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Include entities from the same parent table using two different foreign keys - @ruslantalpa
- Ensure that Location header in 201 response is URL-encoded - @league
- Fix garbage collector CPU leak - @ruslantalpa et al.
- Return deleted items when return=representation header is sent - @ruslantalpa
## [0.3.1.1] - 2016-03-28
+1 -3
View File
@@ -150,9 +150,7 @@ userApiRequest schema req reqBody =
, iPreferSingular = singular
, iPreferCount = not $ singular || hasPrefer "count=none"
, iFilters = [ (cs k, fromJust v) | (k,v) <- qParams, isJust v, k /= "select", k /= "offset", not (endingIn ["order", "limit"] k) ]
, iSelect = if method == "DELETE"
then "*"
else fromMaybe "*" $ fromMaybe (Just "*") $ lookup "select" qParams
, iSelect = fromMaybe "*" $ fromMaybe (Just "*") $ lookup "select" qParams
, iOrder = [(cs k, fromJust v) | (k,v) <- qParams, isJust v, endingIn ["order"] k ]
, iCanonicalQS = urlEncodeVars
. sortBy (comparing fst)
+8 -4
View File
@@ -161,13 +161,16 @@ app dbStructure conf apiRequest =
Left e -> return $ responseLBS status400 [jsonH] $ cs e
Right (sq,mq) -> do
let emptyUniform = UniformObjects V.empty
let fakeload = PayloadJSON emptyUniform
let stm = createWriteStatement qi sq mq False (iPreferRepresentation apiRequest) [] (contentType == TextCSV) fakeload
fakeload = PayloadJSON emptyUniform
stm = createWriteStatement qi sq mq False (iPreferRepresentation apiRequest) [] (contentType == TextCSV) fakeload
row <- H.query emptyUniform stm
let (_, queryTotal, _, _) = extractQueryResult row
let (_, queryTotal, _, body) = extractQueryResult row
r = contentRangeH 1 0 (toInteger <$> Just queryTotal)
return $ if queryTotal == 0
then notFound
else responseLBS status204 [("Content-Range", "*/"<> cs (show queryTotal))] ""
else if iPreferRepresentation apiRequest == Full
then responseLBS status200 [contentTypeH, r] (cs body)
else responseLBS status204 [r] ""
(ActionInfo, TargetIdent (QualifiedIdentifier tSchema tTable), Nothing) ->
if isJust $ find (\t -> tableName t == tTable && tableSchema t == tSchema) (dbTables dbStructure)
@@ -346,6 +349,7 @@ buildReadRequest maxRows allRels apiRequest =
relations = case action of
ActionCreate -> fakeSourceRelations ++ allRels
ActionUpdate -> fakeSourceRelations ++ allRels
ActionDelete -> fakeSourceRelations ++ allRels
_ -> allRels
where fakeSourceRelations = mapMaybe (toSourceRelation rootTableName) allRels -- see comment in toSourceRelation
+22
View File
@@ -19,6 +19,28 @@ spec =
, matchHeaders = ["Content-Range" <:> "*/1"]
}
it "returns the deleted item" $
request methodDelete "/items?id=eq.2" [("Prefer", "return=representation")] ""
`shouldRespondWith` ResponseMatcher {
matchBody = Just [str|[{"id":2}]|]
, matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/1"]
}
it "returns the deleted item and shapes the response" $
request methodDelete "/complex_items?id=eq.2&select=id,name" [("Prefer", "return=representation")] ""
`shouldRespondWith` ResponseMatcher {
matchBody = Just [str|[{"id":2,"name":"Two"}]|]
, matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/1"]
}
it "can embed (parent) entities" $
request methodDelete "/tasks?id=eq.8&select=id,name,project{id}" [("Prefer", "return=representation")] ""
`shouldRespondWith` ResponseMatcher {
matchBody = Just [str|[{"id":8,"name":"Code OSX","project":{"id":4}}]|]
, matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/1"]
}
it "actually clears items ouf the db" $ do
_ <- request methodDelete "/items?id=lt.15" [] ""
get "/items"