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 stm = createWriteStatement qi sq mq isSingle (iPreferRepresentation apiRequest) pKeys (contentType == TextCSV) payload
row <- H.query uniform stm
let (_, _, locationFieldsOpt, body) = extractQueryResult row
mkHeader fs = [(hLocation, "/" <> cs table <> renderLocationFields fs)]
header = maybe [] mkHeader locationFieldsOpt
let (_, _, fs, body) = extractQueryResult row
header =
if null fs then []
else [(hLocation, "/" <> cs table <> renderLocationFields fs)]
return $ if iPreferRepresentation apiRequest == Full
then responseLBS status201 (contentTypeH : header) (cs body)
@@ -391,4 +392,4 @@ instance ToJSON TableOptions where
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
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
because 'PostgreSQL.Binary.Decoder.arrayDimension' cannot decode an empty
array!
@"k1=eq.42"@, or the empty list if there is no location header.
-}
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.nullableValue HD.int8 <*> HD.value HD.int8
<*> HD.nullableValue header <*> HD.value HD.bytea
<*> HD.value header <*> HD.value HD.bytea
where
header = HD.array $ HD.arrayDimension replicateM $ HD.arrayValue HD.bytea
noLocationF :: Text
noLocationF = "NULL::text[]"
noLocationF = "array[]::text[]"
{-| Read and Write api requests use a similar response format which includes
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]
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" $
it "fails with 400 and error" $
post "/simple_pk" "}{ x = 2" `shouldRespondWith` 400