Add hint to verify table and foreign key existence on a relationship error
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name: postgrest
|
name: postgrest
|
||||||
version: 9.0.0
|
version: 9.0.0.20211220
|
||||||
synopsis: REST API for any Postgres database
|
synopsis: REST API for any Postgres database
|
||||||
description: Reads the schema of a PostgreSQL database and creates RESTful routes
|
description: Reads the schema of a PostgreSQL database and creates RESTful routes
|
||||||
for the tables and views, supporting all HTTP verbs that security
|
for the tables and views, supporting all HTTP verbs that security
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ data ApiRequestError
|
|||||||
| InvalidRange
|
| InvalidRange
|
||||||
| InvalidBody ByteString
|
| InvalidBody ByteString
|
||||||
| ParseRequestError Text Text
|
| ParseRequestError Text Text
|
||||||
| NoRelBetween Text Text
|
| NoRelBetween Text Text Text
|
||||||
| AmbiguousRelBetween Text Text [Relationship]
|
| AmbiguousRelBetween Text Text [Relationship]
|
||||||
| AmbiguousRpc [ProcDescription]
|
| AmbiguousRpc [ProcDescription]
|
||||||
| NoRpc Text Text [Text] Bool ContentType Bool
|
| NoRpc Text Text [Text] Bool ContentType Bool
|
||||||
@@ -75,7 +75,7 @@ instance PgrstError ApiRequestError where
|
|||||||
status UnsupportedVerb = HTTP.status405
|
status UnsupportedVerb = HTTP.status405
|
||||||
status ActionInappropriate = HTTP.status405
|
status ActionInappropriate = HTTP.status405
|
||||||
status (ParseRequestError _ _) = HTTP.status400
|
status (ParseRequestError _ _) = HTTP.status400
|
||||||
status (NoRelBetween _ _) = HTTP.status400
|
status NoRelBetween{} = HTTP.status400
|
||||||
status AmbiguousRelBetween{} = HTTP.status300
|
status AmbiguousRelBetween{} = HTTP.status300
|
||||||
status (AmbiguousRpc _) = HTTP.status300
|
status (AmbiguousRpc _) = HTTP.status300
|
||||||
status NoRpc{} = HTTP.status404
|
status NoRpc{} = HTTP.status404
|
||||||
@@ -93,9 +93,9 @@ instance JSON.ToJSON ApiRequestError where
|
|||||||
"message" .= T.decodeUtf8 errorMessage]
|
"message" .= T.decodeUtf8 errorMessage]
|
||||||
toJSON InvalidRange = JSON.object [
|
toJSON InvalidRange = JSON.object [
|
||||||
"message" .= ("HTTP Range error" :: Text)]
|
"message" .= ("HTTP Range error" :: Text)]
|
||||||
toJSON (NoRelBetween parent child) = JSON.object [
|
toJSON (NoRelBetween parent child schema) = JSON.object [
|
||||||
"hint" .= ("If a new foreign key between these entities was created in the database, try reloading the schema cache." :: Text),
|
"hint" .= ("Verify that '" <> parent <> "' and '" <> child <> "' exist in the schema '" <> schema <> "' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache." :: Text),
|
||||||
"message" .= ("Could not find a relationship between " <> parent <> " and " <> child <> " in the schema cache" :: Text)]
|
"message" .= ("Could not find a relationship between '" <> parent <> "' and '" <> child <> "' in the schema cache" :: Text)]
|
||||||
toJSON (AmbiguousRelBetween parent child rels) = JSON.object [
|
toJSON (AmbiguousRelBetween parent child rels) = JSON.object [
|
||||||
"hint" .= ("Try changing '" <> child <> "' to one of the following: " <> relHint rels <> ". Find the desired relationship in the 'details' key." :: Text),
|
"hint" .= ("Try changing '" <> child <> "' to one of the following: " <> relHint rels <> ". Find the desired relationship in the 'details' key." :: Text),
|
||||||
"message" .= ("Could not embed because more than one relationship was found for '" <> parent <> "' and '" <> child <> "'" :: Text),
|
"message" .= ("Could not embed because more than one relationship was found for '" <> parent <> "' and '" <> child <> "'" :: Text),
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ addRels schema allRels parentNode (Node (query@Select{from=tbl}, (nodeName, _, a
|
|||||||
findRel :: Schema -> [Relationship] -> NodeName -> NodeName -> Maybe Hint -> Either ApiRequestError Relationship
|
findRel :: Schema -> [Relationship] -> NodeName -> NodeName -> Maybe Hint -> Either ApiRequestError Relationship
|
||||||
findRel schema allRels origin target hint =
|
findRel schema allRels origin target hint =
|
||||||
case rel of
|
case rel of
|
||||||
[] -> Left $ NoRelBetween origin target
|
[] -> Left $ NoRelBetween origin target schema
|
||||||
[r] -> Right r
|
[r] -> Right r
|
||||||
-- Here we handle a self reference relationship to not cause a breaking
|
-- Here we handle a self reference relationship to not cause a breaking
|
||||||
-- change: In a self reference we get two relationships with the same
|
-- change: In a self reference we get two relationships with the same
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ spec =
|
|||||||
it "fails if the fk is not known" $
|
it "fails if the fk is not known" $
|
||||||
get "/message?select=id,sender:person!space(name)&id=lt.4" `shouldRespondWith`
|
get "/message?select=id,sender:person!space(name)&id=lt.4" `shouldRespondWith`
|
||||||
[json|{
|
[json|{
|
||||||
"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
"hint":"Verify that 'message' and 'person' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between message and person in the schema cache"}|]
|
"message":"Could not find a relationship between 'message' and 'person' in the schema cache"}|]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson] }
|
, matchHeaders = [matchContentTypeJson] }
|
||||||
|
|
||||||
@@ -425,8 +425,8 @@ spec =
|
|||||||
it "doesn't work if the junction is only internal" $
|
it "doesn't work if the junction is only internal" $
|
||||||
get "/end_1?select=end_2(*)" `shouldRespondWith`
|
get "/end_1?select=end_2(*)" `shouldRespondWith`
|
||||||
[json|{
|
[json|{
|
||||||
"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
"hint":"Verify that 'end_1' and 'end_2' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between end_1 and end_2 in the schema cache"}|]
|
"message":"Could not find a relationship between 'end_1' and 'end_2' in the schema cache"}|]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson] }
|
, matchHeaders = [matchContentTypeJson] }
|
||||||
it "shouldn't try to embed if the private junction has an exposed homonym" $
|
it "shouldn't try to embed if the private junction has an exposed homonym" $
|
||||||
@@ -434,7 +434,7 @@ spec =
|
|||||||
-- Ref: https://github.com/PostgREST/postgrest/issues/1587#issuecomment-734995669
|
-- Ref: https://github.com/PostgREST/postgrest/issues/1587#issuecomment-734995669
|
||||||
get "/schauspieler?select=filme(*)" `shouldRespondWith`
|
get "/schauspieler?select=filme(*)" `shouldRespondWith`
|
||||||
[json|{
|
[json|{
|
||||||
"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
"hint":"Verify that 'schauspieler' and 'filme' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between schauspieler and filme in the schema cache"}|]
|
"message":"Could not find a relationship between 'schauspieler' and 'filme' in the schema cache"}|]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson] }
|
, matchHeaders = [matchContentTypeJson] }
|
||||||
|
|||||||
+10
-10
@@ -260,8 +260,8 @@ spec actualPgVersion = do
|
|||||||
it "matches filtering nested items 2" $
|
it "matches filtering nested items 2" $
|
||||||
get "/clients?select=id,projects(id,tasks2(id,name))&projects.tasks.name=like.Design*" `shouldRespondWith`
|
get "/clients?select=id,projects(id,tasks2(id,name))&projects.tasks.name=like.Design*" `shouldRespondWith`
|
||||||
[json| {
|
[json| {
|
||||||
"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
"hint":"Verify that 'projects' and 'tasks2' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between projects and tasks2 in the schema cache"}|]
|
"message":"Could not find a relationship between 'projects' and 'tasks2' in the schema cache"}|]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
@@ -489,8 +489,8 @@ spec actualPgVersion = do
|
|||||||
it "cannot request partitions as children from a partitioned table" $
|
it "cannot request partitions as children from a partitioned table" $
|
||||||
get "/car_models?id=in.(1,2,4)&select=id,name,car_model_sales_202101(id)&order=id.asc" `shouldRespondWith`
|
get "/car_models?id=in.(1,2,4)&select=id,name,car_model_sales_202101(id)&order=id.asc" `shouldRespondWith`
|
||||||
[json|
|
[json|
|
||||||
{"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
{"hint":"Verify that 'car_models' and 'car_model_sales_202101' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between car_models and car_model_sales_202101 in the schema cache"} |]
|
"message":"Could not find a relationship between 'car_models' and 'car_model_sales_202101' in the schema cache"} |]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
@@ -498,8 +498,8 @@ spec actualPgVersion = do
|
|||||||
it "cannot request a partitioned table as parent from a partition" $
|
it "cannot request a partitioned table as parent from a partition" $
|
||||||
get "/car_model_sales_202101?select=id,name,car_models(id,name)&order=id.asc" `shouldRespondWith`
|
get "/car_model_sales_202101?select=id,name,car_models(id,name)&order=id.asc" `shouldRespondWith`
|
||||||
[json|
|
[json|
|
||||||
{"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
{"hint":"Verify that 'car_model_sales_202101' and 'car_models' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between car_model_sales_202101 and car_models in the schema cache"} |]
|
"message":"Could not find a relationship between 'car_model_sales_202101' and 'car_models' in the schema cache"} |]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
@@ -507,8 +507,8 @@ spec actualPgVersion = do
|
|||||||
it "cannot request a partition as parent from a partitioned table" $
|
it "cannot request a partition as parent from a partitioned table" $
|
||||||
get "/car_model_sales?id=in.(1,3,4)&select=id,name,car_models_default(id,name)&order=id.asc" `shouldRespondWith`
|
get "/car_model_sales?id=in.(1,3,4)&select=id,name,car_models_default(id,name)&order=id.asc" `shouldRespondWith`
|
||||||
[json|
|
[json|
|
||||||
{"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
{"hint":"Verify that 'car_model_sales' and 'car_models_default' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between car_model_sales and car_models_default in the schema cache"} |]
|
"message":"Could not find a relationship between 'car_model_sales' and 'car_models_default' in the schema cache"} |]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
@@ -516,8 +516,8 @@ spec actualPgVersion = do
|
|||||||
it "cannot request partitioned tables as children from a partition" $
|
it "cannot request partitioned tables as children from a partition" $
|
||||||
get "/car_models_default?select=id,name,car_model_sales(id,name)&order=id.asc" `shouldRespondWith`
|
get "/car_models_default?select=id,name,car_model_sales(id,name)&order=id.asc" `shouldRespondWith`
|
||||||
[json|
|
[json|
|
||||||
{"hint":"If a new foreign key between these entities was created in the database, try reloading the schema cache.",
|
{"hint":"Verify that 'car_models_default' and 'car_model_sales' exist in the schema 'test' and that there is a foreign key relationship between them. If a new relationship was created, try reloading the schema cache.",
|
||||||
"message":"Could not find a relationship between car_models_default and car_model_sales in the schema cache"} |]
|
"message":"Could not find a relationship between 'car_models_default' and 'car_model_sales' in the schema cache"} |]
|
||||||
{ matchStatus = 400
|
{ matchStatus = 400
|
||||||
, matchHeaders = [matchContentTypeJson]
|
, matchHeaders = [matchContentTypeJson]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user