Read only proc tx (#844)

This commit is contained in:
Joe Nelson
2017-04-07 12:52:16 -05:00
committed by GitHub
parent 77af16c9e4
commit 56bdf59e14
5 changed files with 50 additions and 14 deletions
+1
View File
@@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #777, Empty body is allowed when calling a non-parameterized RPC - @koulakis
- #831, Fix proc resource embedding issue with search_path - @steve-chavez
- #857, Fix swagger-ui when "server-proxy-uri" is not set - @feynmanliang
- #547, Use read-only transaction for stable/immutable RPC - @begriffs
## [0.4.0.0] - 2017-01-19
+19 -5
View File
@@ -79,15 +79,29 @@ postgrest conf refDbStructure pool getTime =
eClaims = jwtClaims jwtSecret (iJWT apiRequest) time
authed = containsRole eClaims
handleReq = runWithClaims conf eClaims (app dbStructure conf) apiRequest
txMode = transactionMode $ iAction apiRequest
txMode = transactionMode dbStructure
(iTarget apiRequest) (iAction apiRequest)
response <- P.use pool $ HT.transaction HT.ReadCommitted txMode handleReq
return $ either (pgError authed) identity response
respond response
transactionMode :: Action -> H.Mode
transactionMode ActionRead = HT.Read
transactionMode ActionInfo = HT.Read
transactionMode _ = HT.Write
transactionMode :: DbStructure -> Target -> Action -> H.Mode
transactionMode structure target action =
case action of
ActionRead -> HT.Read
ActionInfo -> HT.Read
ActionInspect -> HT.Read
ActionInvoke ->
let proc =
case target of
(TargetProc qi) -> M.lookup (qiName qi) $
dbProcs structure
_ -> Nothing
v = fromMaybe Volatile $ pdVolatility <$> proc in
if v == Stable || v == Immutable
then HT.Read
else HT.Write
_ -> HT.Write
app :: DbStructure -> AppConfig -> ApiRequest -> H.Transaction Response
app dbStructure conf apiRequest =
+25 -9
View File
@@ -100,10 +100,19 @@ decodeSynonyms cols =
accessibleProcs :: H.Query Schema (M.HashMap Text ProcDescription)
accessibleProcs =
H.statement sql (HE.value HE.text)
(M.fromList . map addName <$> HD.rowsList (ProcDescription <$> HD.value HD.text
<*> (parseArgs <$> HD.value HD.text)
<*> (parseRetType <$> HD.value HD.text <*> HD.value HD.text <*>
HD.value HD.bool <*> HD.value HD.char))) True
(M.fromList . map addName <$>
HD.rowsList (
ProcDescription <$> HD.value HD.text
<*> (parseArgs <$> HD.value HD.text)
<*> (parseRetType <$>
HD.value HD.text <*>
HD.value HD.text <*>
HD.value HD.bool <*>
HD.value HD.char)
<*> (parseVolatility <$>
HD.value HD.char)
)
) True
where
addName :: ProcDescription -> (Text, ProcDescription)
addName pd = (pdName pd, pd)
@@ -124,25 +133,32 @@ accessibleProcs =
parseRetType schema name isSetOf typ
| isSetOf = SetOf pgType
| otherwise = Single pgType
where
where
qi = QualifiedIdentifier schema name
pgType = case typ of
pgType = case typ of
'c' -> Composite qi
'p' -> Pseudo name
_ -> Scalar qi -- 'b'ase, 'd'omain, 'e'num, 'r'ange
parseVolatility :: Char -> ProcVolatility
parseVolatility 'i' = Immutable
parseVolatility 's' = Stable
parseVolatility 'v' = Volatile
parseVolatility _ = Volatile -- should not happen, but be pessimistic
sql = [q|
SELECT p.proname as "proc_name",
pg_get_function_arguments(p.oid) as "args",
tn.nspname as "rettype_schema",
coalesce(comp.relname, t.typname) as "rettype_name",
p.proretset as "rettype_is_setof",
t.typtype as "rettype_typ"
t.typtype as "rettype_typ",
p.provolatile
FROM pg_proc p
JOIN pg_namespace pn ON pn.oid = p.pronamespace
JOIN pg_type t ON t.oid = p.prorettype
JOIN pg_namespace tn ON tn.oid = t.typnamespace
LEFT JOIN pg_class comp ON comp.oid = t.typrelid
LEFT JOIN pg_class comp ON comp.oid = t.typrelid
WHERE pn.nspname = $1|]
accessibleTables :: H.Query Schema [Table]
+4
View File
@@ -41,10 +41,14 @@ data PgType = Scalar QualifiedIdentifier | Composite QualifiedIdentifier | Pseud
data RetType = Single PgType | SetOf PgType deriving (Eq, Show)
data ProcVolatility = Volatile | Stable | Immutable
deriving (Eq, Show)
data ProcDescription = ProcDescription {
pdName :: Text
, pdArgs :: [PgArg]
, pdReturnType :: RetType
, pdVolatility :: ProcVolatility
} deriving (Show, Eq)
type Schema = Text
+1
View File
@@ -316,6 +316,7 @@ $$;
CREATE FUNCTION sayhello(name text) RETURNS text
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT 'Hello, ' || $1;
$_$;