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 - #777, Empty body is allowed when calling a non-parameterized RPC - @koulakis
- #831, Fix proc resource embedding issue with search_path - @steve-chavez - #831, Fix proc resource embedding issue with search_path - @steve-chavez
- #857, Fix swagger-ui when "server-proxy-uri" is not set - @feynmanliang - #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 ## [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 eClaims = jwtClaims jwtSecret (iJWT apiRequest) time
authed = containsRole eClaims authed = containsRole eClaims
handleReq = runWithClaims conf eClaims (app dbStructure conf) apiRequest 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 response <- P.use pool $ HT.transaction HT.ReadCommitted txMode handleReq
return $ either (pgError authed) identity response return $ either (pgError authed) identity response
respond response respond response
transactionMode :: Action -> H.Mode transactionMode :: DbStructure -> Target -> Action -> H.Mode
transactionMode ActionRead = HT.Read transactionMode structure target action =
transactionMode ActionInfo = HT.Read case action of
transactionMode _ = HT.Write 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 -> AppConfig -> ApiRequest -> H.Transaction Response
app dbStructure conf apiRequest = app dbStructure conf apiRequest =
+21 -5
View File
@@ -100,10 +100,19 @@ decodeSynonyms cols =
accessibleProcs :: H.Query Schema (M.HashMap Text ProcDescription) accessibleProcs :: H.Query Schema (M.HashMap Text ProcDescription)
accessibleProcs = accessibleProcs =
H.statement sql (HE.value HE.text) H.statement sql (HE.value HE.text)
(M.fromList . map addName <$> HD.rowsList (ProcDescription <$> HD.value HD.text (M.fromList . map addName <$>
<*> (parseArgs <$> HD.value HD.text) HD.rowsList (
<*> (parseRetType <$> HD.value HD.text <*> HD.value HD.text <*> ProcDescription <$> HD.value HD.text
HD.value HD.bool <*> HD.value HD.char))) True <*> (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 where
addName :: ProcDescription -> (Text, ProcDescription) addName :: ProcDescription -> (Text, ProcDescription)
addName pd = (pdName pd, pd) addName pd = (pdName pd, pd)
@@ -131,13 +140,20 @@ accessibleProcs =
'p' -> Pseudo name 'p' -> Pseudo name
_ -> Scalar qi -- 'b'ase, 'd'omain, 'e'num, 'r'ange _ -> 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| sql = [q|
SELECT p.proname as "proc_name", SELECT p.proname as "proc_name",
pg_get_function_arguments(p.oid) as "args", pg_get_function_arguments(p.oid) as "args",
tn.nspname as "rettype_schema", tn.nspname as "rettype_schema",
coalesce(comp.relname, t.typname) as "rettype_name", coalesce(comp.relname, t.typname) as "rettype_name",
p.proretset as "rettype_is_setof", p.proretset as "rettype_is_setof",
t.typtype as "rettype_typ" t.typtype as "rettype_typ",
p.provolatile
FROM pg_proc p FROM pg_proc p
JOIN pg_namespace pn ON pn.oid = p.pronamespace JOIN pg_namespace pn ON pn.oid = p.pronamespace
JOIN pg_type t ON t.oid = p.prorettype JOIN pg_type t ON t.oid = p.prorettype
+4
View File
@@ -41,10 +41,14 @@ data PgType = Scalar QualifiedIdentifier | Composite QualifiedIdentifier | Pseud
data RetType = Single PgType | SetOf PgType deriving (Eq, Show) data RetType = Single PgType | SetOf PgType deriving (Eq, Show)
data ProcVolatility = Volatile | Stable | Immutable
deriving (Eq, Show)
data ProcDescription = ProcDescription { data ProcDescription = ProcDescription {
pdName :: Text pdName :: Text
, pdArgs :: [PgArg] , pdArgs :: [PgArg]
, pdReturnType :: RetType , pdReturnType :: RetType
, pdVolatility :: ProcVolatility
} deriving (Show, Eq) } deriving (Show, Eq)
type Schema = Text type Schema = Text
+1
View File
@@ -316,6 +316,7 @@ $$;
CREATE FUNCTION sayhello(name text) RETURNS text CREATE FUNCTION sayhello(name text) RETURNS text
LANGUAGE sql LANGUAGE sql
IMMUTABLE
AS $_$ AS $_$
SELECT 'Hello, ' || $1; SELECT 'Hello, ' || $1;
$_$; $_$;