WIP: call stored pprocedures that emit plain text

The beginning of #114
This commit is contained in:
Joe Nelson
2015-08-20 21:52:46 -07:00
parent f564fb0977
commit bb511f0df2
3 changed files with 38 additions and 2 deletions
+18 -1
View File
@@ -163,6 +163,21 @@ app conf reqBody req =
] $ if echoRequested then encode obj else ""
return $ multipart status201 responses
(["rpc", proc], "POST") -> do
let qi = QualifiedIdentifier schema (cs proc)
exists <- doesProcExist schema proc
if exists
then do
row :: Maybe (Identity Text) <- H.maybeEx $ callProc qi $
fromMaybe M.empty (decode reqBody)
return $ responseLBS status200 [textH]
(cs $ fromMaybe "" $ runIdentity <$> row)
else return $ responseLBS status404 [] ""
-- check that proc exists
-- check that arg names are all specified
-- select * from "1".proc(a := "foo"::undefined) where whereT limit limitT
([table], "PUT") ->
handleJsonObj reqBody $ \obj -> do
let qt = qualify table
@@ -279,6 +294,9 @@ csvMT = "text/csv"
jsonH :: Header
jsonH = (hContentType, jsonMT)
textH :: Header
textH = (hContentType, "text/plain")
contentTypeForAccept :: Maybe BS.ByteString -> Maybe BS.ByteString
contentTypeForAccept accept
| isNothing accept || hasJson = Just jsonMT
@@ -295,7 +313,6 @@ bodyForAccept contentType table
| contentType == csvMT = asCsvWithCount table
| otherwise = asJsonWithCount -- defaults to JSON
handleJsonObj :: BL.ByteString -> (Object -> H.Tx P.Postgres s Response)
-> H.Tx P.Postgres s Response
handleJsonObj reqBody handler = do
+8
View File
@@ -10,6 +10,7 @@ import qualified Hasql.Postgres as P
import qualified Hasql.Backend as B
import qualified Data.Text as T
import qualified Data.HashMap.Strict as H
import Text.Regex.TDFA ( (=~) )
import qualified Network.HTTP.Types.URI as Net
import qualified Data.ByteString.Char8 as BS
@@ -172,6 +173,13 @@ update t cols vals = B.Stmt
<> ")")
empty True
callProc :: QualifiedIdentifier -> JSON.Object -> PStmt
callProc qi params = do
let args = T.intercalate "," $ map assignment (H.toList params)
B.Stmt ("select " <> fromQi qi <> "(" <> args <> ")") empty True
where
assignment (n,v) = pgFmtIdent n <> ":=" <> insertableValue v
wherePred :: QualifiedIdentifier -> Net.QueryItem -> PStmt
wherePred table (col, predicate) =
B.Stmt (" " <> pgFmtJsonbPath table (cs col) <> " " <> op <> " " <>
+12 -1
View File
@@ -8,7 +8,7 @@ import Data.Text hiding (foldl, map, zipWith, concat)
import Data.Aeson
import Data.Functor.Identity
import Data.String.Conversions (cs)
import Data.Maybe (fromMaybe)
import Data.Maybe (fromMaybe, isJust)
import Control.Applicative
import qualified Data.Map as Map
@@ -121,6 +121,17 @@ primaryKeyColumns table = do
and kc.table_name = ? |] (qiSchema table) (qiName table)
return $ map runIdentity r
doesProcExist :: Text -> Text -> H.Tx P.Postgres s Bool
doesProcExist schema proc = do
row :: Maybe (Identity Int) <- H.maybeEx $ [H.stmt|
SELECT 1
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p
ON pronamespace = n.oid
WHERE nspname = ?
AND proname = ?
|] schema proc
return $ isJust row
data Table = Table {
tableSchema :: Text