Prepared statement for set_config
This commit is contained in:
committed by
Steve Chavez
parent
7069bb3c01
commit
11d62a8010
+1
-1
@@ -16,7 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- #504, Add `log-level` config option. The admitted levels are: crit, error, warn and info - @steve-chavez
|
||||
- #1607, Enable embedding through multiple views recursively - @wolfgangwalther
|
||||
- #1598, Allow rollback of the transaction with Prefer tx=rollback - @wolfgangwalther
|
||||
- #1633, Enable prepared statements for filters. When behind a connection pooler, you can disable preparing with `db-prepared-statements=false` - @steve-chavez
|
||||
- #1633, #1600, Enable prepared statements for filters. When behind a connection pooler, you can disable preparing with `db-prepared-statements=false` - @steve-chavez
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
+18
-11
@@ -8,16 +8,21 @@ Description : Sets CORS policy. Also the PostgreSQL GUCs, role, search_path and
|
||||
|
||||
module PostgREST.Middleware where
|
||||
|
||||
import qualified Data.Aeson as JSON
|
||||
import qualified Data.ByteString.Char8 as BS
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
import Data.Function (id)
|
||||
import qualified Data.HashMap.Strict as M
|
||||
import Data.List (lookup)
|
||||
import Data.Scientific (FPFormat (..),
|
||||
formatScientific, isInteger)
|
||||
import qualified Data.Text as T
|
||||
import qualified Hasql.Transaction as H
|
||||
import qualified Hasql.Decoders as HD
|
||||
import qualified Hasql.DynamicStatements.Statement as H
|
||||
import PostgREST.Private.Common
|
||||
|
||||
import qualified Data.Aeson as JSON
|
||||
import qualified Data.ByteString.Char8 as BS
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
import Data.Function (id)
|
||||
import qualified Data.HashMap.Strict as M
|
||||
import Data.List (lookup)
|
||||
import Data.Scientific (FPFormat (..),
|
||||
formatScientific,
|
||||
isInteger)
|
||||
import qualified Data.Text as T
|
||||
import qualified Hasql.Transaction as H
|
||||
import Network.HTTP.Types.Status (Status, status400,
|
||||
status500, statusCode)
|
||||
import Network.Wai.Logger (showSockAddr)
|
||||
@@ -43,7 +48,9 @@ runPgLocals :: AppConfig -> M.HashMap Text JSON.Value ->
|
||||
(ApiRequest -> H.Transaction Response) ->
|
||||
ApiRequest -> H.Transaction Response
|
||||
runPgLocals conf claims app req = do
|
||||
H.sql . toS $ "select " <> T.intercalate ", " (searchPathSql : roleSql ++ claimsSql ++ [methodSql, pathSql] ++ headersSql ++ cookiesSql ++ appSettingsSql)
|
||||
H.statement mempty $ H.dynamicallyParameterized
|
||||
("select " <> intercalateSnippet ", " (searchPathSql : roleSql ++ claimsSql ++ [methodSql, pathSql] ++ headersSql ++ cookiesSql ++ appSettingsSql))
|
||||
HD.noResult (configDbPreparedStatements conf)
|
||||
traverse_ H.sql preReqSql
|
||||
app req
|
||||
where
|
||||
|
||||
@@ -5,10 +5,13 @@ Description : Common helper functions.
|
||||
module PostgREST.Private.Common where
|
||||
|
||||
import Data.Maybe
|
||||
import qualified Hasql.Decoders as HD
|
||||
import qualified Hasql.Encoders as HE
|
||||
import qualified Hasql.Decoders as HD
|
||||
import qualified Hasql.DynamicStatements.Snippet as H
|
||||
import qualified Hasql.Encoders as HE
|
||||
import Protolude
|
||||
|
||||
import Data.Foldable (foldr1)
|
||||
|
||||
column :: HD.Value a -> HD.Row a
|
||||
column = HD.column . HD.nonNullable
|
||||
|
||||
@@ -23,3 +26,10 @@ param = HE.param . HE.nonNullable
|
||||
|
||||
arrayParam :: HE.Value a -> HE.Params [a]
|
||||
arrayParam = param . HE.array . HE.dimension foldl' . HE.element . HE.nonNullable
|
||||
|
||||
emptySnippetOnFalse :: H.Snippet -> Bool -> H.Snippet
|
||||
emptySnippetOnFalse val cond = if cond then mempty else val
|
||||
|
||||
intercalateSnippet :: ByteString -> [H.Snippet] -> H.Snippet
|
||||
intercalateSnippet _ [] = mempty
|
||||
intercalateSnippet frag snippets = foldr1 (\a b -> a <> H.sql frag <> b) snippets
|
||||
|
||||
@@ -30,9 +30,8 @@ import Protolude hiding (cast,
|
||||
import Protolude.Conv (toS)
|
||||
import Text.InterpolatedString.Perl6 (qc)
|
||||
|
||||
import qualified Hasql.Encoders as HE
|
||||
|
||||
import Data.Foldable (foldr1)
|
||||
import qualified Hasql.Encoders as HE
|
||||
import PostgREST.Private.Common
|
||||
|
||||
noLocationF :: SqlFragment
|
||||
noLocationF = "array[]::text[]"
|
||||
@@ -250,10 +249,3 @@ unknownEncoder = H.encoderAndParam (HE.nonNullable HE.unknown)
|
||||
|
||||
unknownLiteral :: Text -> H.Snippet
|
||||
unknownLiteral = unknownEncoder . encodeUtf8
|
||||
|
||||
emptySnippetOnFalse :: H.Snippet -> Bool -> H.Snippet
|
||||
emptySnippetOnFalse val cond = if cond then mempty else val
|
||||
|
||||
intercalateSnippet :: SqlFragment -> [H.Snippet] -> H.Snippet
|
||||
intercalateSnippet _ [] = mempty
|
||||
intercalateSnippet frag snippets = foldr1 (\a b -> a <> H.sql frag <> b) snippets
|
||||
|
||||
@@ -26,6 +26,7 @@ import qualified Hasql.DynamicStatements.Snippet as H
|
||||
import Data.Tree (Tree (..))
|
||||
|
||||
import Data.Maybe
|
||||
import PostgREST.Private.Common
|
||||
import PostgREST.Private.QueryFragment
|
||||
import PostgREST.Types
|
||||
import Protolude hiding (cast, intercalate,
|
||||
@@ -173,6 +174,6 @@ limitedQuery :: H.Snippet -> Maybe Integer -> H.Snippet
|
||||
limitedQuery query maxRows = query <> H.sql (maybe mempty (\x -> " LIMIT " <> BS.pack (show x)) maxRows)
|
||||
|
||||
-- | Do a pg set_config(setting, value, true) call. This is equivalent to a SET LOCAL.
|
||||
setConfigLocal :: Text -> (Text, Text) -> Text
|
||||
setConfigLocal :: Text -> (Text, Text) -> H.Snippet
|
||||
setConfigLocal prefix (k, v) =
|
||||
"set_config(" <> decodeUtf8 (pgFmtLit (prefix <> k)) <> ", " <> decodeUtf8 (pgFmtLit v) <> ", true)"
|
||||
"set_config(" <> unknownLiteral (prefix <> k) <> ", " <> unknownLiteral v <> ", true)"
|
||||
|
||||
Reference in New Issue
Block a user