diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eef34f60..48d6f94e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Allow SQL functions to generate registered JWT claims - @begriffs - Terminate gracefully on SIGTERM (for use in Docker) - @recmo - Relation detection fix for views that depend on multiple tables - @ruslantalpa +- Avoid count on plurality=singular and allow multiple Prefer values - @ruslantalpa ## [0.3.1.0] - 2016-02-28 diff --git a/src/PostgREST/ApiRequest.hs b/src/PostgREST/ApiRequest.hs index 92be95859..2c0b84aaf 100644 --- a/src/PostgREST/ApiRequest.hs +++ b/src/PostgREST/ApiRequest.hs @@ -130,7 +130,7 @@ userApiRequest schema req reqBody = , iPayload = relevantPayload , iPreferRepresentation = representation , iPreferSingular = singular - , iPreferCount = not $ hasPrefer "count=none" + , iPreferCount = not $ singular || hasPrefer "count=none" , iFilters = [ (k, fromJust v) | (k,v) <- qParams, k `notElem` ["select", "order"], isJust v ] , iSelect = if method == "DELETE" then "*" @@ -145,7 +145,11 @@ userApiRequest schema req reqBody = hdrs = requestHeaders req qParams = [(cs k, cs <$> v)|(k,v) <- queryString req] lookupHeader = flip lookup hdrs - hasPrefer val = any (\(h,v) -> h == "Prefer" && v == val) hdrs + hasPrefer :: T.Text -> Bool + hasPrefer val = any (\(h,v) -> h == "Prefer" && val `elem` split v) hdrs + where + split :: BS.ByteString -> [T.Text] + split = map T.strip . T.split (==';') . cs singular = hasPrefer "plurality=singular" representation | hasPrefer "return=representation" = Full diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index 71b353187..f450f7b06 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -246,6 +246,14 @@ spec = do , matchHeaders = [] } + it "can combine multiple prefer values" $ + request methodGet "/items?id=eq.5" [("Prefer","plurality=singular ; future=new; count=none")] "" + `shouldRespondWith` ResponseMatcher { + matchBody = Just [json| {"id":5} |] + , matchStatus = 200 + , matchHeaders = [] + } + it "works in the presence of a range header" $ let headers = ("Prefer","plurality=singular") : rangeHdrs (ByteRangeFromTo 0 9) in