Rename QualifiedTable to encompass proc names as well
This commit is contained in:
@@ -209,7 +209,7 @@ app conf reqBody req =
|
|||||||
|
|
||||||
([table], "DELETE") -> do
|
([table], "DELETE") -> do
|
||||||
let qt = qualify table
|
let qt = qualify table
|
||||||
let del = countT
|
del = countT
|
||||||
. returningStarT
|
. returningStarT
|
||||||
. whereT qt qq
|
. whereT qt qq
|
||||||
$ deleteFrom qt
|
$ deleteFrom qt
|
||||||
@@ -226,7 +226,7 @@ app conf reqBody req =
|
|||||||
path = pathInfo req
|
path = pathInfo req
|
||||||
verb = requestMethod req
|
verb = requestMethod req
|
||||||
qq = queryString req
|
qq = queryString req
|
||||||
qualify = QualifiedTable schema
|
qualify = QualifiedIdentifier schema
|
||||||
hdrs = requestHeaders req
|
hdrs = requestHeaders req
|
||||||
lookupHeader = flip lookup hdrs
|
lookupHeader = flip lookup hdrs
|
||||||
accept = lookupHeader hAccept
|
accept = lookupHeader hAccept
|
||||||
@@ -290,7 +290,7 @@ contentTypeForAccept accept
|
|||||||
hasJson = isJust $ findInAccept $ BS.isPrefixOf jsonMT
|
hasJson = isJust $ findInAccept $ BS.isPrefixOf jsonMT
|
||||||
hasCsv = isJust $ findInAccept $ BS.isPrefixOf csvMT
|
hasCsv = isJust $ findInAccept $ BS.isPrefixOf csvMT
|
||||||
|
|
||||||
bodyForAccept :: BS.ByteString -> QualifiedTable -> StatementT
|
bodyForAccept :: BS.ByteString -> QualifiedIdentifier -> StatementT
|
||||||
bodyForAccept contentType table
|
bodyForAccept contentType table
|
||||||
| contentType == csvMT = asCsvWithCount table
|
| contentType == csvMT = asCsvWithCount table
|
||||||
| otherwise = asJsonWithCount -- defaults to JSON
|
| otherwise = asJsonWithCount -- defaults to JSON
|
||||||
|
|||||||
+27
-27
@@ -33,9 +33,9 @@ instance Monoid PStmt where
|
|||||||
mempty = B.Stmt "" empty True
|
mempty = B.Stmt "" empty True
|
||||||
type StatementT = PStmt -> PStmt
|
type StatementT = PStmt -> PStmt
|
||||||
|
|
||||||
data QualifiedTable = QualifiedTable {
|
data QualifiedIdentifier = QualifiedIdentifier {
|
||||||
qtSchema :: T.Text
|
qiSchema :: T.Text
|
||||||
, qtName :: T.Text
|
, qiName :: T.Text
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
data OrderTerm = OrderTerm {
|
data OrderTerm = OrderTerm {
|
||||||
@@ -51,7 +51,7 @@ limitT r q =
|
|||||||
limit = maybe "ALL" (cs . show) $ join $ rangeLimit <$> r
|
limit = maybe "ALL" (cs . show) $ join $ rangeLimit <$> r
|
||||||
offset = cs . show $ fromMaybe 0 $ rangeOffset <$> r
|
offset = cs . show $ fromMaybe 0 $ rangeOffset <$> r
|
||||||
|
|
||||||
whereT :: QualifiedTable -> Net.Query -> StatementT
|
whereT :: QualifiedIdentifier -> Net.Query -> StatementT
|
||||||
whereT table params q =
|
whereT table params q =
|
||||||
if L.null cols
|
if L.null cols
|
||||||
then q
|
then q
|
||||||
@@ -97,17 +97,17 @@ countT :: StatementT
|
|||||||
countT s =
|
countT s =
|
||||||
s { B.stmtTemplate = "WITH qqq AS (" <> B.stmtTemplate s <> ") SELECT pg_catalog.count(1) FROM qqq" }
|
s { B.stmtTemplate = "WITH qqq AS (" <> B.stmtTemplate s <> ") SELECT pg_catalog.count(1) FROM qqq" }
|
||||||
|
|
||||||
countRows :: QualifiedTable -> PStmt
|
countRows :: QualifiedIdentifier -> PStmt
|
||||||
countRows t = B.Stmt ("select pg_catalog.count(1) from " <> fromQt t) empty True
|
countRows t = B.Stmt ("select pg_catalog.count(1) from " <> fromQi t) empty True
|
||||||
|
|
||||||
asCsvWithCount :: QualifiedTable -> StatementT
|
asCsvWithCount :: QualifiedIdentifier -> StatementT
|
||||||
asCsvWithCount table = withCount . asCsv table
|
asCsvWithCount table = withCount . asCsv table
|
||||||
|
|
||||||
asCsv :: QualifiedTable -> StatementT
|
asCsv :: QualifiedIdentifier -> StatementT
|
||||||
asCsv table s = s { B.stmtTemplate =
|
asCsv table s = s { B.stmtTemplate =
|
||||||
"(select string_agg(quote_ident(column_name::text), ',') from "
|
"(select string_agg(quote_ident(column_name::text), ',') from "
|
||||||
<> "(select column_name from information_schema.columns where quote_ident(table_schema) || '.' || table_name = '"
|
<> "(select column_name from information_schema.columns where quote_ident(table_schema) || '.' || table_name = '"
|
||||||
<> fromQt table <> "' order by ordinal_position) h) || '\r' || "
|
<> fromQi table <> "' order by ordinal_position) h) || '\r' || "
|
||||||
<> "coalesce(string_agg(substring(t::text, 2, length(t::text) - 2), '\r'), '') from ("
|
<> "coalesce(string_agg(substring(t::text, 2, length(t::text) - 2), '\r'), '') from ("
|
||||||
<> B.stmtTemplate s <> ") t" }
|
<> B.stmtTemplate s <> ") t" }
|
||||||
|
|
||||||
@@ -125,23 +125,23 @@ withCount s = s { B.stmtTemplate = "pg_catalog.count(t), " <> B.stmtTemplate s }
|
|||||||
asJsonRow :: StatementT
|
asJsonRow :: StatementT
|
||||||
asJsonRow s = s { B.stmtTemplate = "row_to_json(t) from (" <> B.stmtTemplate s <> ") t" }
|
asJsonRow s = s { B.stmtTemplate = "row_to_json(t) from (" <> B.stmtTemplate s <> ") t" }
|
||||||
|
|
||||||
selectStar :: QualifiedTable -> PStmt
|
selectStar :: QualifiedIdentifier -> PStmt
|
||||||
selectStar t = B.Stmt ("select * from " <> fromQt t) empty True
|
selectStar t = B.Stmt ("select * from " <> fromQi t) empty True
|
||||||
|
|
||||||
returningStarT :: StatementT
|
returningStarT :: StatementT
|
||||||
returningStarT s = s { B.stmtTemplate = B.stmtTemplate s <> " RETURNING *" }
|
returningStarT s = s { B.stmtTemplate = B.stmtTemplate s <> " RETURNING *" }
|
||||||
|
|
||||||
deleteFrom :: QualifiedTable -> PStmt
|
deleteFrom :: QualifiedIdentifier -> PStmt
|
||||||
deleteFrom t = B.Stmt ("delete from " <> fromQt t) empty True
|
deleteFrom t = B.Stmt ("delete from " <> fromQi t) empty True
|
||||||
|
|
||||||
insertInto :: QualifiedTable
|
insertInto :: QualifiedIdentifier
|
||||||
-> V.Vector T.Text
|
-> V.Vector T.Text
|
||||||
-> V.Vector (V.Vector JSON.Value)
|
-> V.Vector (V.Vector JSON.Value)
|
||||||
-> PStmt
|
-> PStmt
|
||||||
insertInto t cols vals
|
insertInto t cols vals
|
||||||
| V.null cols = B.Stmt ("insert into " <> fromQt t <> " default values returning *") empty True
|
| V.null cols = B.Stmt ("insert into " <> fromQi t <> " default values returning *") empty True
|
||||||
| otherwise = B.Stmt
|
| otherwise = B.Stmt
|
||||||
("insert into " <> fromQt t <> " (" <>
|
("insert into " <> fromQi t <> " (" <>
|
||||||
T.intercalate ", " (V.toList $ V.map pgFmtIdent cols) <>
|
T.intercalate ", " (V.toList $ V.map pgFmtIdent cols) <>
|
||||||
") values "
|
") values "
|
||||||
<> T.intercalate ", "
|
<> T.intercalate ", "
|
||||||
@@ -150,29 +150,29 @@ insertInto t cols vals
|
|||||||
<> ")"
|
<> ")"
|
||||||
) vals
|
) vals
|
||||||
)
|
)
|
||||||
<> " returning row_to_json(" <> fromQt t <> ".*)")
|
<> " returning row_to_json(" <> fromQi t <> ".*)")
|
||||||
empty True
|
empty True
|
||||||
|
|
||||||
insertSelect :: QualifiedTable -> [T.Text] -> [JSON.Value] -> PStmt
|
insertSelect :: QualifiedIdentifier -> [T.Text] -> [JSON.Value] -> PStmt
|
||||||
insertSelect t [] _ = B.Stmt
|
insertSelect t [] _ = B.Stmt
|
||||||
("insert into " <> fromQt t <> " default values returning *") empty True
|
("insert into " <> fromQi t <> " default values returning *") empty True
|
||||||
insertSelect t cols vals = B.Stmt
|
insertSelect t cols vals = B.Stmt
|
||||||
("insert into " <> fromQt t <> " ("
|
("insert into " <> fromQi t <> " ("
|
||||||
<> T.intercalate ", " (map pgFmtIdent cols)
|
<> T.intercalate ", " (map pgFmtIdent cols)
|
||||||
<> ") select "
|
<> ") select "
|
||||||
<> T.intercalate ", " (map insertableValue vals))
|
<> T.intercalate ", " (map insertableValue vals))
|
||||||
empty True
|
empty True
|
||||||
|
|
||||||
update :: QualifiedTable -> [T.Text] -> [JSON.Value] -> PStmt
|
update :: QualifiedIdentifier -> [T.Text] -> [JSON.Value] -> PStmt
|
||||||
update t cols vals = B.Stmt
|
update t cols vals = B.Stmt
|
||||||
("update " <> fromQt t <> " set ("
|
("update " <> fromQi t <> " set ("
|
||||||
<> T.intercalate ", " (map pgFmtIdent cols)
|
<> T.intercalate ", " (map pgFmtIdent cols)
|
||||||
<> ") = ("
|
<> ") = ("
|
||||||
<> T.intercalate ", " (map insertableValue vals)
|
<> T.intercalate ", " (map insertableValue vals)
|
||||||
<> ")")
|
<> ")")
|
||||||
empty True
|
empty True
|
||||||
|
|
||||||
wherePred :: QualifiedTable -> Net.QueryItem -> PStmt
|
wherePred :: QualifiedIdentifier -> Net.QueryItem -> PStmt
|
||||||
wherePred table (col, predicate) =
|
wherePred table (col, predicate) =
|
||||||
B.Stmt (" " <> pgFmtJsonbPath table (cs col) <> " " <> op <> " " <>
|
B.Stmt (" " <> pgFmtJsonbPath table (cs col) <> " " <> op <> " " <>
|
||||||
if opCode `elem` ["is","isnot"] then whiteList value
|
if opCode `elem` ["is","isnot"] then whiteList value
|
||||||
@@ -257,11 +257,11 @@ parseJsonbPath p =
|
|||||||
(KeyIdentifier b)
|
(KeyIdentifier b)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
pgFmtJsonbPath :: QualifiedTable -> T.Text -> T.Text
|
pgFmtJsonbPath :: QualifiedIdentifier -> T.Text -> T.Text
|
||||||
pgFmtJsonbPath table p =
|
pgFmtJsonbPath table p =
|
||||||
pgFmtJsonbPath' $ fromMaybe (ColIdentifier p) (parseJsonbPath p)
|
pgFmtJsonbPath' $ fromMaybe (ColIdentifier p) (parseJsonbPath p)
|
||||||
where
|
where
|
||||||
pgFmtJsonbPath' (ColIdentifier i) = fromQt table <> "." <> pgFmtIdent i
|
pgFmtJsonbPath' (ColIdentifier i) = fromQi table <> "." <> pgFmtIdent i
|
||||||
pgFmtJsonbPath' (KeyIdentifier i) = pgFmtLit i
|
pgFmtJsonbPath' (KeyIdentifier i) = pgFmtLit i
|
||||||
pgFmtJsonbPath' (SingleArrow a b) =
|
pgFmtJsonbPath' (SingleArrow a b) =
|
||||||
pgFmtJsonbPath' a <> "->" <> pgFmtJsonbPath' b
|
pgFmtJsonbPath' a <> "->" <> pgFmtJsonbPath' b
|
||||||
@@ -289,8 +289,8 @@ pgFmtLit x =
|
|||||||
trimNullChars :: T.Text -> T.Text
|
trimNullChars :: T.Text -> T.Text
|
||||||
trimNullChars = T.takeWhile (/= '\x0')
|
trimNullChars = T.takeWhile (/= '\x0')
|
||||||
|
|
||||||
fromQt :: QualifiedTable -> T.Text
|
fromQi :: QualifiedIdentifier -> T.Text
|
||||||
fromQt t = pgFmtIdent (qtSchema t) <> "." <> pgFmtIdent (qtName t)
|
fromQi t = pgFmtIdent (qiSchema t) <> "." <> pgFmtIdent (qiName t)
|
||||||
|
|
||||||
unquoted :: JSON.Value -> T.Text
|
unquoted :: JSON.Value -> T.Text
|
||||||
unquoted (JSON.String t) = t
|
unquoted (JSON.String t) = t
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
FlexibleContexts #-}
|
FlexibleContexts #-}
|
||||||
module PostgREST.PgStructure where
|
module PostgREST.PgStructure where
|
||||||
|
|
||||||
import PostgREST.PgQuery (QualifiedTable(..))
|
import PostgREST.PgQuery (QualifiedIdentifier(..))
|
||||||
import Data.Text hiding (foldl, map, zipWith, concat)
|
import Data.Text hiding (foldl, map, zipWith, concat)
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
import Data.Functor.Identity
|
import Data.Functor.Identity
|
||||||
@@ -18,7 +18,7 @@ import qualified Hasql.Postgres as P
|
|||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
foreignKeys :: QualifiedTable -> H.Tx P.Postgres s (Map.Map Text ForeignKey)
|
foreignKeys :: QualifiedIdentifier -> H.Tx P.Postgres s (Map.Map Text ForeignKey)
|
||||||
foreignKeys table = do
|
foreignKeys table = do
|
||||||
r <- H.listEx $ [H.stmt|
|
r <- H.listEx $ [H.stmt|
|
||||||
select kcu.column_name, ccu.table_name AS foreign_table_name,
|
select kcu.column_name, ccu.table_name AS foreign_table_name,
|
||||||
@@ -31,7 +31,7 @@ foreignKeys table = do
|
|||||||
where constraint_type = 'FOREIGN KEY'
|
where constraint_type = 'FOREIGN KEY'
|
||||||
and tc.table_name=? and tc.table_schema = ?
|
and tc.table_name=? and tc.table_schema = ?
|
||||||
order by kcu.column_name
|
order by kcu.column_name
|
||||||
|] (qtName table) (qtSchema table)
|
|] (qiName table) (qiSchema table)
|
||||||
|
|
||||||
return $ foldl addKey Map.empty r
|
return $ foldl addKey Map.empty r
|
||||||
where
|
where
|
||||||
@@ -67,7 +67,7 @@ tables schema = do
|
|||||||
return $ map tableFromRow rows
|
return $ map tableFromRow rows
|
||||||
|
|
||||||
|
|
||||||
columns :: QualifiedTable -> H.Tx P.Postgres s [Column]
|
columns :: QualifiedIdentifier -> H.Tx P.Postgres s [Column]
|
||||||
columns table = do
|
columns table = do
|
||||||
cols <- H.listEx $ [H.stmt|
|
cols <- H.listEx $ [H.stmt|
|
||||||
select info.table_schema as schema, info.table_name as table_name,
|
select info.table_schema as schema, info.table_name as table_name,
|
||||||
@@ -97,7 +97,7 @@ columns table = do
|
|||||||
) as enum_info
|
) as enum_info
|
||||||
on (info.udt_name = enum_info.n)
|
on (info.udt_name = enum_info.n)
|
||||||
order by position |]
|
order by position |]
|
||||||
(qtSchema table) (qtName table)
|
(qiSchema table) (qiName table)
|
||||||
|
|
||||||
fks <- foreignKeys table
|
fks <- foreignKeys table
|
||||||
return $ map (addFK fks . columnFromRow) cols
|
return $ map (addFK fks . columnFromRow) cols
|
||||||
@@ -106,7 +106,7 @@ columns table = do
|
|||||||
addFK fks col = col { colFK = Map.lookup (cs . colName $ col) fks }
|
addFK fks col = col { colFK = Map.lookup (cs . colName $ col) fks }
|
||||||
|
|
||||||
|
|
||||||
primaryKeyColumns :: QualifiedTable -> H.Tx P.Postgres s [Text]
|
primaryKeyColumns :: QualifiedIdentifier -> H.Tx P.Postgres s [Text]
|
||||||
primaryKeyColumns table = do
|
primaryKeyColumns table = do
|
||||||
r <- H.listEx $ [H.stmt|
|
r <- H.listEx $ [H.stmt|
|
||||||
select kc.column_name
|
select kc.column_name
|
||||||
@@ -118,7 +118,7 @@ primaryKeyColumns table = do
|
|||||||
and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
|
and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
|
||||||
and kc.constraint_name = tc.constraint_name
|
and kc.constraint_name = tc.constraint_name
|
||||||
and kc.table_schema = ?
|
and kc.table_schema = ?
|
||||||
and kc.table_name = ? |] (qtSchema table) (qtName table)
|
and kc.table_name = ? |] (qiSchema table) (qiName table)
|
||||||
return $ map runIdentity r
|
return $ map runIdentity r
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user