Provide more information in PATCH response

* 404 if no records updated
* Range header for number updated
* Full results depending on Prefer header

Fixes #187
Fixes #182
This commit is contained in:
Joe Nelson
2015-05-12 10:47:55 -07:00
parent ef0dc26de5
commit 709e70561f
3 changed files with 40 additions and 7 deletions
+18 -4
View File
@@ -39,6 +39,8 @@ import PgQuery
import RangeQuery
import PgStructure
import Debug.Trace
app :: Text -> BL.ByteString -> Request -> H.Tx P.Postgres s Response
app v1schema reqBody req =
case (path, verb) of
@@ -164,10 +166,22 @@ app v1schema reqBody req =
([table], "PATCH") ->
handleJsonObj reqBody $ \obj -> do
let qt = QualifiedTable schema (cs table)
H.unitEx
$ whereT qq
$ update qt (map cs $ M.keys obj) (M.elems obj)
return $ responseLBS status204 [ jsonH ] ""
up = returningStarT
. whereT qq
$ update qt (map cs $ M.keys obj) (M.elems obj)
patch = withT up "t" $ B.Stmt
"select count(t), array_to_json(array_agg(row_to_json(t)))::character varying"
V.empty True
row <- H.maybeEx $ traceShow (B.stmtTemplate patch) patch
let (queryTotal, body) =
fromMaybe (0 :: Int, Just "" :: Maybe Text) row
r = contentRangeH 0 (queryTotal-1) queryTotal
echoRequested = lookup "Prefer" hdrs == Just "return=representation"
s = case () of _ | queryTotal == 0 -> status404
| echoRequested -> status200
| otherwise -> status204
return $ responseLBS s [ jsonH, r ] $ if echoRequested then cs $ fromMaybe "[]" body else ""
([table], "DELETE") -> do
let qt = QualifiedTable schema (cs table)
+6
View File
@@ -59,6 +59,12 @@ whereT params q =
cols = [ col | col <- params, fst col `notElem` ["order"] ]
conjunction = mconcat $ L.intersperse andq (map wherePred cols)
withT :: PStmt -> T.Text -> StatementT
withT (B.Stmt eq ep epre) v (B.Stmt wq wp wpre) =
B.Stmt ("WITH " <> v <> " AS (" <> eq <> ") " <> wq <> " from " <> v)
(ep <> wp)
(epre && wpre)
orderT :: [OrderTerm] -> StatementT
orderT ts q =
if L.null ts
+16 -3
View File
@@ -232,10 +232,10 @@ spec = afterAll_ resetDb $ around withApp $ do
`shouldRespondWith` 404
context "on an empty table" $
it "succeeds with no effect" $
it "indicates no records found to update" $
request methodPatch "/simple_pk" []
[json| { "extra":20 } |]
`shouldRespondWith` 204
`shouldRespondWith` 404
context "in a nonempty table" . before_ (clearTable "items" >> createItems 15) .
after_ (clearTable "items") $ do
@@ -245,7 +245,11 @@ spec = afterAll_ resetDb $ around withApp $ do
`shouldSatisfy` matchHeader "Content-Range" "\\*/0"
request methodPatch "/items?id=eq.1" []
[json| { "id":42 } |]
`shouldRespondWith` 204
`shouldRespondWith` ResponseMatcher {
matchBody = Nothing,
matchStatus = 204,
matchHeaders = ["Content-Range" <:> "0-0/1"]
}
g' <- get "/items?id=eq.42"
liftIO $ simpleHeaders g'
`shouldSatisfy` matchHeader "Content-Range" "0-0/1"
@@ -261,3 +265,12 @@ spec = afterAll_ resetDb $ around withApp $ do
g <- get "/auto_incrementing_pk?non_nullable_string=eq.c"
liftIO $ simpleHeaders g
`shouldSatisfy` matchHeader "Content-Range" "0-9/10"
it "can provide a representation" $ do
_ <- post "/items"
[json| { id: 1 } |]
request methodPatch
"/items?id=eq.1"
[("Prefer", "return=representation")]
[json| { id: 99 } |]
`shouldRespondWith` [json| [{id:99}] |]