From 0827e24413976459359b17691aeed01cd7f01192 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Mon, 19 Feb 2024 18:45:14 +0100 Subject: [PATCH] fix: Dump media handlers and timezones with --dump-schema Those were left out of the schema dump when the features were introduced, probably because ByteString doesn't have a toJSON instance. Changing the type to Text solves this easily. Resolves #3237 --- CHANGELOG.md | 1 + src/PostgREST/ApiRequest/Preferences.hs | 2 +- src/PostgREST/Config/Database.hs | 2 +- src/PostgREST/MediaType.hs | 14 ++++++++------ src/PostgREST/SchemaCache.hs | 9 ++++----- src/PostgREST/SchemaCache/Routine.hs | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b26f07f97..b1b978ef1c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #3205, Fix wrong subquery error returning a status of 400 Bad Request - @steve-chavez - #3224, Return status code 406 for non-accepted media type instead of code 415 - @wolfgangwalther - #3160, Fix using select= query parameter for custom media type handlers - @wolfgangwalther + - #3237, Dump media handlers and timezones with --dump-schema - @wolfgangwalther ### Deprecated diff --git a/src/PostgREST/ApiRequest/Preferences.hs b/src/PostgREST/ApiRequest/Preferences.hs index 3bc6c50a24a..b869c4a9f20 100644 --- a/src/PostgREST/ApiRequest/Preferences.hs +++ b/src/PostgREST/ApiRequest/Preferences.hs @@ -163,7 +163,7 @@ fromHeaders allowTxDbOverride acceptedTzNames headers = listStripPrefix prefix prefList = listToMaybe $ mapMaybe (BS.stripPrefix prefix) prefList timezonePref = listStripPrefix "timezone=" prefs - isTimezonePrefAccepted = (S.member <$> timezonePref <*> pure acceptedTzNames) == Just True + isTimezonePrefAccepted = (S.member <$> (decodeUtf8 <$> timezonePref) <*> pure acceptedTzNames) == Just True maxAffectedPref = listStripPrefix "max-affected=" prefs >>= readMaybe . BS.unpack diff --git a/src/PostgREST/Config/Database.hs b/src/PostgREST/Config/Database.hs index 54b83797417..3792a48d7f6 100644 --- a/src/PostgREST/Config/Database.hs +++ b/src/PostgREST/Config/Database.hs @@ -30,7 +30,7 @@ import Protolude type RoleSettings = (HM.HashMap ByteString (HM.HashMap ByteString ByteString)) type RoleIsolationLvl = HM.HashMap ByteString SQL.IsolationLevel -type TimezoneNames = Set ByteString -- cache timezone names for prefer timezone= +type TimezoneNames = Set Text -- cache timezone names for prefer timezone= toIsolationLevel :: (Eq a, IsString a) => a -> SQL.IsolationLevel toIsolationLevel a = case a of diff --git a/src/PostgREST/MediaType.hs b/src/PostgREST/MediaType.hs index 9a54286b8af..89918772df3 100644 --- a/src/PostgREST/MediaType.hs +++ b/src/PostgREST/MediaType.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} @@ -10,6 +11,7 @@ module PostgREST.MediaType , decodeMediaType ) where +import qualified Data.Aeson as JSON import qualified Data.ByteString as BS import qualified Data.ByteString.Internal as BS (c2w) @@ -28,23 +30,23 @@ data MediaType | MTUrlEncoded | MTOctetStream | MTAny - | MTOther ByteString + | MTOther Text -- vendored media types | MTVndArrayJSONStrip | MTVndSingularJSON Bool -- TODO MTVndPlan should only have its options as [Text]. Its ResultAggregate should have the typed attributes. | MTVndPlan MediaType MTVndPlanFormat [MTVndPlanOption] - deriving (Eq, Show, Generic) + deriving (Eq, Show, Generic, JSON.ToJSON) instance Hashable MediaType data MTVndPlanOption = PlanAnalyze | PlanVerbose | PlanSettings | PlanBuffers | PlanWAL - deriving (Eq, Show, Generic) + deriving (Eq, Show, Generic, JSON.ToJSON) instance Hashable MTVndPlanOption data MTVndPlanFormat = PlanJSON | PlanText - deriving (Eq, Show, Generic) + deriving (Eq, Show, Generic, JSON.ToJSON) instance Hashable MTVndPlanFormat -- | Convert MediaType to a Content-Type HTTP Header @@ -70,7 +72,7 @@ toMime (MTVndSingularJSON False) = "application/vnd.pgrst.object+json" toMime MTUrlEncoded = "application/x-www-form-urlencoded" toMime MTOctetStream = "application/octet-stream" toMime MTAny = "*/*" -toMime (MTOther ct) = ct +toMime (MTOther ct) = encodeUtf8 ct toMime (MTVndPlan mt fmt opts) = "application/vnd.pgrst.plan+" <> toMimePlanFormat fmt <> ("; for=\"" <> toMime mt <> "\"") <> @@ -132,7 +134,7 @@ decodeMediaType mt = "application/vnd.pgrst.array+json":rest -> checkArrayNullStrip rest "application/vnd.pgrst.array":rest -> checkArrayNullStrip rest "*/*":_ -> MTAny - other:_ -> MTOther other + other:_ -> MTOther $ decodeUtf8 other _ -> MTAny where checkArrayNullStrip ["nulls=stripped"] = MTVndArrayJSONStrip diff --git a/src/PostgREST/SchemaCache.hs b/src/PostgREST/SchemaCache.hs index b3fa8650019..3e27c13ddf5 100644 --- a/src/PostgREST/SchemaCache.hs +++ b/src/PostgREST/SchemaCache.hs @@ -31,7 +31,6 @@ import Control.Monad.Extra (whenJust) import Data.Aeson ((.=)) import qualified Data.Aeson as JSON -import qualified Data.Aeson.Types as JSON import qualified Data.HashMap.Strict as HM import qualified Data.HashMap.Strict.InsOrd as HMI import qualified Data.Set as S @@ -86,13 +85,13 @@ data SchemaCache = SchemaCache } instance JSON.ToJSON SchemaCache where - toJSON (SchemaCache tabs rels routs reps _ _) = JSON.object [ + toJSON (SchemaCache tabs rels routs reps hdlers tzs) = JSON.object [ "dbTables" .= JSON.toJSON tabs , "dbRelationships" .= JSON.toJSON rels , "dbRoutines" .= JSON.toJSON routs , "dbRepresentations" .= JSON.toJSON reps - , "dbMediaHandlers" .= JSON.emptyArray - , "dbTimezones" .= JSON.emptyArray + , "dbMediaHandlers" .= JSON.toJSON hdlers + , "dbTimezones" .= JSON.toJSON tzs ] showSummary :: SchemaCache -> Text @@ -1222,7 +1221,7 @@ timezones = SQL.Statement sql HE.noParams decodeTimezones where sql = "SELECT name FROM pg_timezone_names" decodeTimezones :: HD.Result TimezoneNames - decodeTimezones = S.fromList . map encodeUtf8 <$> HD.rowList (column HD.text) + decodeTimezones = S.fromList <$> HD.rowList (column HD.text) param :: HE.Value a -> HE.Params a param = HE.param . HE.nonNullable diff --git a/src/PostgREST/SchemaCache/Routine.hs b/src/PostgREST/SchemaCache/Routine.hs index 446d84628f1..248fb5682f2 100644 --- a/src/PostgREST/SchemaCache/Routine.hs +++ b/src/PostgREST/SchemaCache/Routine.hs @@ -110,7 +110,7 @@ data MediaHandler -- custom | CustomFunc QualifiedIdentifier RelIdentifier | NoAgg - deriving (Eq, Show) + deriving (Eq, Show, Generic, JSON.ToJSON) funcReturnsSingle :: Routine -> Bool funcReturnsSingle proc = case proc of