Merge pull request #607 from league/urlencode-location

Simplify serialization of location header
This commit is contained in:
Joe Nelson
2016-05-25 20:53:41 -07:00
3 changed files with 19 additions and 10 deletions
+5 -4
View File
@@ -130,9 +130,10 @@ app dbStructure conf apiRequest =
let pKeys = map pkName $ filter (filterPk schema table) allPrKeys -- would it be ok to move primary key detection in the query itself? let pKeys = map pkName $ filter (filterPk schema table) allPrKeys -- would it be ok to move primary key detection in the query itself?
let stm = createWriteStatement qi sq mq isSingle (iPreferRepresentation apiRequest) pKeys (contentType == TextCSV) payload let stm = createWriteStatement qi sq mq isSingle (iPreferRepresentation apiRequest) pKeys (contentType == TextCSV) payload
row <- H.query uniform stm row <- H.query uniform stm
let (_, _, locationFieldsOpt, body) = extractQueryResult row let (_, _, fs, body) = extractQueryResult row
mkHeader fs = [(hLocation, "/" <> cs table <> renderLocationFields fs)] header =
header = maybe [] mkHeader locationFieldsOpt if null fs then []
else [(hLocation, "/" <> cs table <> renderLocationFields fs)]
return $ if iPreferRepresentation apiRequest == Full return $ if iPreferRepresentation apiRequest == Full
then responseLBS status201 (contentTypeH : header) (cs body) then responseLBS status201 (contentTypeH : header) (cs body)
@@ -391,4 +392,4 @@ instance ToJSON TableOptions where
extractQueryResult :: Maybe ResultsWithCount -> ResultsWithCount extractQueryResult :: Maybe ResultsWithCount -> ResultsWithCount
extractQueryResult = fromMaybe (Nothing, 0, Nothing, "") extractQueryResult = fromMaybe (Nothing, 0, [], "")
+4 -6
View File
@@ -63,20 +63,18 @@ import PostgREST.ApiRequest (PreferRepresentation (..))
{-| The generic query result format used by API responses. The location header {-| The generic query result format used by API responses. The location header
is represented as a list of strings containing variable bindings like is represented as a list of strings containing variable bindings like
@"k1=eq.42"@. If unused, it's null/Nothing rather than the empty list @"k1=eq.42"@, or the empty list if there is no location header.
because 'PostgreSQL.Binary.Decoder.arrayDimension' cannot decode an empty
array!
-} -}
type ResultsWithCount = (Maybe Int64, Int64, Maybe [BS.ByteString], BS.ByteString) type ResultsWithCount = (Maybe Int64, Int64, [BS.ByteString], BS.ByteString)
standardRow :: HD.Row ResultsWithCount standardRow :: HD.Row ResultsWithCount
standardRow = (,,,) <$> HD.nullableValue HD.int8 <*> HD.value HD.int8 standardRow = (,,,) <$> HD.nullableValue HD.int8 <*> HD.value HD.int8
<*> HD.nullableValue header <*> HD.value HD.bytea <*> HD.value header <*> HD.value HD.bytea
where where
header = HD.array $ HD.arrayDimension replicateM $ HD.arrayValue HD.bytea header = HD.array $ HD.arrayDimension replicateM $ HD.arrayValue HD.bytea
noLocationF :: Text noLocationF :: Text
noLocationF = "NULL::text[]" noLocationF = "array[]::text[]"
{-| Read and Write api requests use a similar response format which includes {-| Read and Write api requests use a similar response format which includes
various record counts and possible location header. This is the decoder various record counts and possible location header. This is the decoder
+10
View File
@@ -138,6 +138,16 @@ spec = do
JSON.decode (simpleBody r) `shouldBe` Just [expectedObj] JSON.decode (simpleBody r) `shouldBe` Just [expectedObj]
simpleStatus r `shouldBe` ok200 simpleStatus r `shouldBe` ok200
context "with bulk insert" $
it "returns 201 but no location header" $ do
let bulkData = [json| [ {"k1":21, "k2":"hello world"}
, {"k1":22, "k2":"bye for now"}]
|]
p <- request methodPost "/compound_pk" [] bulkData
liftIO $ do
simpleStatus p `shouldBe` created201
lookup hLocation (simpleHeaders p) `shouldBe` Nothing
context "with invalid json payload" $ context "with invalid json payload" $
it "fails with 400 and error" $ it "fails with 400 and error" $
post "/simple_pk" "}{ x = 2" `shouldRespondWith` 400 post "/simple_pk" "}{ x = 2" `shouldRespondWith` 400