Maintain backward compatibility on GUC headers feature

If pg version >= 9.6 is detected the feature is enabled,
also all of the 9.6 dependent tests are moved to their own spec.
This commit is contained in:
steve-chavez
2017-10-18 17:41:55 -05:00
committed by Steve Chávez
parent b9a591aecb
commit 188f947437
12 changed files with 170 additions and 129 deletions
+2 -4
View File
@@ -84,12 +84,9 @@ postgrest conf refDbStructure pool worker =
(iTarget apiRequest) (iAction apiRequest)
response <- P.use pool $ HT.transaction HT.ReadCommitted txMode handleReq
return $ either (pgError authed) identity response
when (isResponse503 response) worker
when (responseStatus response == status503) worker
respond response
isResponse503 :: Response -> Bool
isResponse503 resp = statusCode (responseStatus resp) == 503
transactionMode :: DbStructure -> Target -> Action -> H.Mode
transactionMode structure target action =
case action of
@@ -252,6 +249,7 @@ app dbStructure conf apiRequest =
singular paramsAsSingleObject
(contentType == CTTextCSV)
(contentType == CTOctetStream) _isReadOnly bField
(pgVersion dbStructure)
let (tableTotal, queryTotal, body, jsonHeaders) =
fromMaybe (Just 0, 0, "[]", "[]") row
(status, contentRange) = rangeHeader queryTotal tableTotal
+5 -6
View File
@@ -19,11 +19,12 @@ module PostgREST.Config ( prettyVersion
, readOptions
, corsPolicy
, minimumPgVersion
, PgVersion (..)
, pgVersion96
, AppConfig (..)
)
where
import PostgREST.Types (PgVersion(..))
import Control.Applicative
import Control.Monad (fail)
import Control.Lens (preview)
@@ -211,11 +212,9 @@ pathParser =
metavar "FILENAME" <>
help "Path to configuration file"
data PgVersion = PgVersion {
pgvNum :: Int32
, pgvName :: Text
}
-- | Tells the minimum PostgreSQL version required by this version of PostgREST
minimumPgVersion :: PgVersion
minimumPgVersion = PgVersion 90300 "9.3"
pgVersion96 :: PgVersion
pgVersion96 = PgVersion 90600 "9.6"
+10 -2
View File
@@ -8,6 +8,7 @@ module PostgREST.DbStructure (
, accessibleTables
, accessibleProcs
, schemaDescription
, getPgVersion
) where
import qualified Hasql.Decoders as HD
@@ -29,8 +30,8 @@ import GHC.Exts (groupWith)
import Protolude
import Unsafe (unsafeHead)
getDbStructure :: Schema -> H.Session DbStructure
getDbStructure schema = do
getDbStructure :: Schema -> PgVersion -> H.Session DbStructure
getDbStructure schema pgVer = do
tabs <- H.query () allTables
cols <- H.query () $ allColumns tabs
syns <- H.query () $ allSynonyms cols
@@ -48,6 +49,7 @@ getDbStructure schema = do
, dbRelations = rels'
, dbPrimaryKeys = keys'
, dbProcs = procs
, pgVersion = pgVer
}
decodeTables :: HD.Result [Table]
@@ -706,3 +708,9 @@ synonymFromRow allCols (s1,t1,c1,s2,t2,c2) = (,) <$> col1 <*> col2
col1 = findCol s1 t1 c1
col2 = findCol s2 t2 c2
findCol s t c = find (\col -> (tableSchema . colTable) col == s && (tableName . colTable) col == t && colName col == c) allCols
getPgVersion :: H.Session PgVersion
getPgVersion = H.query () $ H.statement sql HE.unit versionRow False
where
sql = "SELECT current_setting('server_version_num')::integer, current_setting('server_version')"
versionRow = HD.singleRow $ PgVersion <$> HD.value HD.int4 <*> HD.value HD.text
+10 -6
View File
@@ -31,6 +31,7 @@ import qualified Hasql.Decoders as HD
import qualified Data.Aeson as JSON
import PostgREST.Config (pgVersion96)
import PostgREST.RangeQuery (NonnegRange, rangeLimit, rangeOffset, allRange)
import Data.Functor.Contravariant (contramap)
import qualified Data.HashMap.Strict as HM
@@ -143,9 +144,9 @@ createWriteStatement selectQuery mutateQuery wantSingle wantHdrs asCsv rep pKeys
| otherwise = asJsonF
type ProcResults = (Maybe Int64, Int64, ByteString, ByteString)
callProc :: QualifiedIdentifier -> JSON.Object -> Bool -> SqlQuery -> SqlQuery ->
Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe FieldName -> H.Query () (Maybe ProcResults)
callProc qi params returnsScalar selectQuery countQuery countTotal isSingle paramsAsJson asCsv asBinary isReadOnly binaryField =
callProc :: QualifiedIdentifier -> JSON.Object -> Bool -> SqlQuery -> SqlQuery -> Bool ->
Bool -> Bool -> Bool -> Bool -> Bool -> Maybe FieldName -> PgVersion -> H.Query () (Maybe ProcResults)
callProc qi params returnsScalar selectQuery countQuery countTotal isSingle paramsAsJson asCsv asBinary isReadOnly binaryField pgVer =
unicodeStatement sql HE.unit decodeProc True
where
sql =
@@ -155,7 +156,7 @@ callProc qi params returnsScalar selectQuery countQuery countTotal isSingle para
{countResultF} AS total_result_set,
1 AS page_total,
{scalarBodyF} AS body,
{responseHeaders} AS headers
{responseHeaders} AS response_headers
FROM ({selectQuery}) _postgrest_t;|]
else [qc|
WITH {sourceCTEName} AS (select * from {fromQi qi}({_args}))
@@ -163,7 +164,7 @@ callProc qi params returnsScalar selectQuery countQuery countTotal isSingle para
{countResultF} AS total_result_set,
pg_catalog.count(_postgrest_t) AS page_total,
{bodyF} AS body,
{responseHeaders} AS headers
{responseHeaders} AS response_headers
FROM ({selectQuery}) _postgrest_t;|]
countResultF = if countTotal then "( "<> countQuery <> ")" else "null::bigint" :: Text
@@ -172,7 +173,10 @@ callProc qi params returnsScalar selectQuery countQuery countTotal isSingle para
else intercalate "," $ map _assignment (HM.toList params)
_procName = qiName qi
_assignment (n,v) = pgFmtIdent n <> ":=" <> insertableValue v
responseHeaders = "coalesce(nullif(current_setting('response.headers', true), ''), '[]')" :: Text -- nullif is used because of https://gist.github.com/steve-chavez/8d7033ea5655096903f3b52f8ed09a15
responseHeaders =
if pgVer >= pgVersion96
then "coalesce(nullif(current_setting('response.headers', true), ''), '[]')" :: Text -- nullif is used because of https://gist.github.com/steve-chavez/8d7033ea5655096903f3b52f8ed09a15
else "'[]'" :: Text
decodeProc = HD.maybeRow procRow
procRow = (,,,) <$> HD.nullableValue HD.int8 <*> HD.value HD.int8
<*> HD.value HD.bytea <*> HD.value HD.bytea
+6
View File
@@ -31,6 +31,7 @@ data DbStructure = DbStructure {
, dbRelations :: [Relation]
, dbPrimaryKeys :: [PrimaryKey]
, dbProcs :: M.HashMap Text ProcDescription
, pgVersion :: PgVersion
} deriving (Show, Eq)
data PgArg = PgArg {
@@ -271,3 +272,8 @@ toMime CTSingularJSON = "application/vnd.pgrst.object+json"
toMime CTOctetStream = "application/octet-stream"
toMime CTAny = "*/*"
toMime (CTOther ct) = ct
data PgVersion = PgVersion {
pgvNum :: Int32
, pgvName :: Text
} deriving (Eq, Ord, Show)