Add PUT handler
This commit is contained in:
+26
-38
@@ -15,7 +15,7 @@ import Data.Ord (comparing)
|
|||||||
import Data.HashMap.Strict (keys, elems, filterWithKey, toList)
|
import Data.HashMap.Strict (keys, elems, filterWithKey, toList)
|
||||||
-- import Data.Map (intersection, fromList, toList, Map)
|
-- import Data.Map (intersection, fromList, toList, Map)
|
||||||
import Data.List (sortBy)
|
import Data.List (sortBy)
|
||||||
-- import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
-- import Data.Convertible.Base (convert)
|
-- import Data.Convertible.Base (convert)
|
||||||
-- import Data.Text (strip, Text)
|
-- import Data.Text (strip, Text)
|
||||||
|
|
||||||
@@ -33,9 +33,6 @@ import Data.ByteString.Char8 hiding (zip, map, elem)
|
|||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
-- import qualified Data.CaseInsensitive as CI
|
-- import qualified Data.CaseInsensitive as CI
|
||||||
|
|
||||||
-- import PgStructure (printTables, printColumns, primaryKeyColumns,
|
|
||||||
-- columns, Column(colName))
|
|
||||||
|
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
import Database.PostgreSQL.Simple
|
import Database.PostgreSQL.Simple
|
||||||
|
|
||||||
@@ -109,6 +106,31 @@ app conn req respond =
|
|||||||
] ""
|
] ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
([table], "PUT") ->
|
||||||
|
handleJsonObj req (\obj -> do
|
||||||
|
let qt = QualifiedTable schema (cs table)
|
||||||
|
primaryKeys <- primaryKeyColumns conn qt
|
||||||
|
let specifiedKeys = map (cs . fst) qq
|
||||||
|
if S.fromList primaryKeys /= S.fromList specifiedKeys
|
||||||
|
then return $ responseLBS status405 []
|
||||||
|
"You must speficy all and only primary keys as params"
|
||||||
|
else do
|
||||||
|
tableCols <- map (cs . colName) <$> columns conn qt
|
||||||
|
let cols = map cs $ keys obj
|
||||||
|
if S.fromList tableCols == S.fromList cols then do
|
||||||
|
let vals = elems obj
|
||||||
|
let upsert =
|
||||||
|
aIffNotBT (whereT qq $ update qt cols vals)
|
||||||
|
(insertInto qt cols vals)
|
||||||
|
_ <- uncurry (execute conn) upsert
|
||||||
|
return $ responseLBS status204 [ jsonH ] ""
|
||||||
|
|
||||||
|
else return $ if Prelude.null tableCols
|
||||||
|
then responseLBS status404 [] ""
|
||||||
|
else responseLBS status400 []
|
||||||
|
"You must specify all columns in PUT request"
|
||||||
|
)
|
||||||
|
|
||||||
(_, _) ->
|
(_, _) ->
|
||||||
return $ responseLBS status404 [] ""
|
return $ responseLBS status404 [] ""
|
||||||
|
|
||||||
@@ -198,40 +220,6 @@ instance ToJSON TableOptions where
|
|||||||
-- , (hLocation, "/dbapi/users?id=eq." <> cs (userId u))
|
-- , (hLocation, "/dbapi/users?id=eq." <> cs (userId u))
|
||||||
-- ] ""
|
-- ] ""
|
||||||
|
|
||||||
-- ([table], "POST") ->
|
|
||||||
-- jsonBodyAction req (\row -> do
|
|
||||||
-- allvals <- insert ver table row conn
|
|
||||||
-- keys <- map cs <$> primaryKeyColumns ver (cs table) conn
|
|
||||||
-- let params = urlEncodeVars $ map (\t -> (fst t, "eq." <> convert (snd t) :: String)) $ toList $ filterByKeys allvals keys
|
|
||||||
-- return $ responseLBS status201
|
|
||||||
-- [ jsonContentType
|
|
||||||
-- , (hLocation, "/" <> cs table <> "?" <> cs params)
|
|
||||||
-- ] ""
|
|
||||||
-- )
|
|
||||||
|
|
||||||
-- ([table], "PUT") ->
|
|
||||||
-- jsonBodyAction req (\row -> do
|
|
||||||
-- keys <- primaryKeyColumns ver (cs table) conn
|
|
||||||
-- let specifiedKeys = map (cs . fst) qq
|
|
||||||
-- if S.fromList keys /= S.fromList specifiedKeys
|
|
||||||
-- then return $ responseLBS status405 []
|
|
||||||
-- "You must speficy all and only primary keys as params"
|
|
||||||
-- else
|
|
||||||
-- if isJust cRange
|
|
||||||
-- then return $ responseLBS status400 []
|
|
||||||
-- "Content-Range is not allowed in PUT request"
|
|
||||||
-- else do
|
|
||||||
-- cols <- columns ver (cs table) conn
|
|
||||||
-- let colNames = S.fromList $ map (cs . colName) cols
|
|
||||||
-- let specifiedCols = S.fromList $ map fst $ getRow row
|
|
||||||
-- if colNames == specifiedCols then do
|
|
||||||
-- _ <- upsert ver table row qq conn
|
|
||||||
-- return $ responseLBS status204 [ jsonContentType ] ""
|
|
||||||
|
|
||||||
-- else return $ if S.null colNames then responseLBS status404 [] ""
|
|
||||||
-- else responseLBS status400 []
|
|
||||||
-- "You must specify all columns in PUT request"
|
|
||||||
-- )
|
|
||||||
|
|
||||||
-- ([table], "PATCH") ->
|
-- ([table], "PATCH") ->
|
||||||
-- jsonBodyAction req (\row -> do
|
-- jsonBodyAction req (\row -> do
|
||||||
|
|||||||
@@ -61,6 +61,13 @@ parentheticT :: CompleteQueryT
|
|||||||
parentheticT (sql, params) =
|
parentheticT (sql, params) =
|
||||||
(" (" <> sql <> ") ", params)
|
(" (" <> sql <> ") ", params)
|
||||||
|
|
||||||
|
aIffNotBT :: CompleteQuery -> CompleteQueryT
|
||||||
|
aIffNotBT (aq, ap) (bq, bp) =
|
||||||
|
("WITH aaa AS (" <> aq <> " returning *) " <>
|
||||||
|
bq <> "WHERE NOT EXISTS (SELECT * FROM aaa)"
|
||||||
|
, ap ++ bp
|
||||||
|
)
|
||||||
|
|
||||||
countRows :: QualifiedTable -> CompleteQuery
|
countRows :: QualifiedTable -> CompleteQuery
|
||||||
countRows t =
|
countRows t =
|
||||||
("select count(1) from ?.?",
|
("select count(1) from ?.?",
|
||||||
@@ -92,6 +99,17 @@ insertInto t cols vals =
|
|||||||
++ map EscapeIdentifier cols ++ map toField vals
|
++ map EscapeIdentifier cols ++ map toField vals
|
||||||
)
|
)
|
||||||
|
|
||||||
|
update :: QualifiedTable -> [BS.ByteString] -> [Value] ->
|
||||||
|
CompleteQuery
|
||||||
|
update t cols vals =
|
||||||
|
("update ?.? set (" <>
|
||||||
|
Query (BS.intercalate ", " (map (const "?") cols)) <>
|
||||||
|
") = (" <>
|
||||||
|
Query (BS.intercalate ", " (map (const "?") vals)) <> ")"
|
||||||
|
, [EscapeIdentifier (qtSchema t), EscapeIdentifier (qtName t)]
|
||||||
|
++ map EscapeIdentifier cols ++ map toField vals
|
||||||
|
)
|
||||||
|
|
||||||
wherePred :: Net.QueryItem -> CompleteQuery
|
wherePred :: Net.QueryItem -> CompleteQuery
|
||||||
wherePred (col, predicate) =
|
wherePred (col, predicate) =
|
||||||
(" ? ? ? ", [EscapeIdentifier col, Plain op, toField value])
|
(" ? ? ? ", [EscapeIdentifier col, Plain op, toField value])
|
||||||
|
|||||||
Reference in New Issue
Block a user