App.hs typechecks
This commit is contained in:
+26
-24
@@ -1,9 +1,11 @@
|
|||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
module App (app) where
|
module App (app) where
|
||||||
|
|
||||||
import Control.Monad (join)
|
import Control.Monad (join)
|
||||||
import Data.Monoid ( (<>) )
|
import Data.Monoid ( (<>) )
|
||||||
import Control.Arrow ((***))
|
import Control.Arrow ((***))
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
import Control.Monad.IO.Class (liftIO, MonadIO)
|
||||||
|
|
||||||
import Data.Text hiding (map)
|
import Data.Text hiding (map)
|
||||||
import Data.Maybe (listToMaybe, fromMaybe)
|
import Data.Maybe (listToMaybe, fromMaybe)
|
||||||
@@ -31,19 +33,20 @@ import RangeQuery
|
|||||||
import PgStructure
|
import PgStructure
|
||||||
import Auth
|
import Auth
|
||||||
|
|
||||||
app :: Connection -> Application
|
app :: Request -> H.Session H.Postgres IO Response
|
||||||
app conn req respond =
|
app req =
|
||||||
respond =<< case (path, verb) of
|
case (path, verb) of
|
||||||
([], _) -> do
|
([], _) -> do
|
||||||
body <- encode <$> tables conn (cs schema)
|
body <- H.tx Nothing $ encode <$> tables (cs schema)
|
||||||
return $ responseLBS status200 [jsonH] $ cs body
|
return $ responseLBS status200 [jsonH] $ cs body
|
||||||
|
|
||||||
([table], "OPTIONS") -> do
|
([table], "OPTIONS") -> do
|
||||||
let t = QualifiedTable schema (cs table)
|
let t = QualifiedTable schema (cs table)
|
||||||
cols <- columns conn t
|
H.tx Nothing $ do
|
||||||
pkey <- map cs <$> primaryKeyColumns conn t
|
cols <- columns t
|
||||||
return $ responseLBS status200 [jsonH, allOrigins]
|
pkey <- map cs <$> primaryKeyColumns t
|
||||||
$ encode (TableOptions cols pkey)
|
return $ responseLBS status200 [jsonH, allOrigins]
|
||||||
|
$ encode (TableOptions cols pkey)
|
||||||
|
|
||||||
([table], "GET") ->
|
([table], "GET") ->
|
||||||
if range == Just emptyRange
|
if range == Just emptyRange
|
||||||
@@ -61,7 +64,7 @@ app conn req respond =
|
|||||||
. whereT qq
|
. whereT qq
|
||||||
$ selectStar qt
|
$ selectStar qt
|
||||||
)
|
)
|
||||||
row <- listToMaybe <$> uncurry (query conn) select
|
row <- H.tx Nothing $ listToMaybe <$> H.list select
|
||||||
let (tableTotal, queryTotal, body) =
|
let (tableTotal, queryTotal, body) =
|
||||||
fromMaybe (0, 0, Just "" :: Maybe ByteString) row
|
fromMaybe (0, 0, Just "" :: Maybe ByteString) row
|
||||||
from = fromMaybe 0 $ rangeOffset <$> range
|
from = fromMaybe 0 $ rangeOffset <$> range
|
||||||
@@ -82,26 +85,25 @@ app conn req respond =
|
|||||||
] (cs $ fromMaybe "[]" body)
|
] (cs $ fromMaybe "[]" body)
|
||||||
|
|
||||||
(["dbapi", "users"], "POST") -> do
|
(["dbapi", "users"], "POST") -> do
|
||||||
body <- strictRequestBody req
|
body <- liftIO $ strictRequestBody req
|
||||||
let user = decode body :: Maybe AuthUser
|
let user = decode body :: Maybe AuthUser
|
||||||
|
|
||||||
case user of
|
case user of
|
||||||
Nothing -> return $ responseLBS status400 [jsonH] $
|
Nothing -> return $ responseLBS status400 [jsonH] $
|
||||||
encode . object $ [("error", String "Failed to parse user.")]
|
encode . object $ [("error", String "Failed to parse user.")]
|
||||||
Just u -> do
|
Just u -> do
|
||||||
_ <- addUser conn (cs $ userId u)
|
_ <- liftIO $ addUser (cs $ userId u)
|
||||||
(cs $ userPass u) (cs $ userRole u)
|
(cs $ userPass u) (cs $ userRole u)
|
||||||
return $ responseLBS status201
|
return $ responseLBS status201
|
||||||
[ jsonH
|
[ jsonH
|
||||||
, (hLocation, "/dbapi/users?id=eq." <> cs (userId u))
|
, (hLocation, "/dbapi/users?id=eq." <> cs (userId u))
|
||||||
] ""
|
] ""
|
||||||
|
|
||||||
([table], "POST") ->
|
([table], "POST") ->
|
||||||
handleJsonObj req $ \obj -> do
|
handleJsonObj req $ \obj -> H.tx Nothing $ do
|
||||||
let qt = QualifiedTable schema (cs table)
|
let qt = QualifiedTable schema (cs table)
|
||||||
_ <- uncurry (execute conn)
|
H.unit $ insertInto qt (map cs $ keys obj) (elems obj)
|
||||||
$ insertInto qt (map cs $ keys obj) (elems obj)
|
primaryKeys <- map cs <$> primaryKeyColumns qt
|
||||||
primaryKeys <- map cs <$> primaryKeyColumns conn qt
|
|
||||||
let primaries = filterWithKey (const . (`elem` primaryKeys)) obj
|
let primaries = filterWithKey (const . (`elem` primaryKeys)) obj
|
||||||
let params = urlEncodeVars
|
let params = urlEncodeVars
|
||||||
$ map (\t -> (cs $ fst t, "eq." <> cs (encode $ snd t)))
|
$ map (\t -> (cs $ fst t, "eq." <> cs (encode $ snd t)))
|
||||||
@@ -112,19 +114,19 @@ app conn req respond =
|
|||||||
] ""
|
] ""
|
||||||
|
|
||||||
([table], "PUT") ->
|
([table], "PUT") ->
|
||||||
handleJsonObj req $ \obj -> do
|
handleJsonObj req $ \obj -> H.tx Nothing $ do
|
||||||
let qt = QualifiedTable schema (cs table)
|
let qt = QualifiedTable schema (cs table)
|
||||||
primaryKeys <- primaryKeyColumns conn qt
|
primaryKeys <- primaryKeyColumns qt
|
||||||
let specifiedKeys = map (cs . fst) qq
|
let specifiedKeys = map (cs . fst) qq
|
||||||
if S.fromList primaryKeys /= S.fromList specifiedKeys
|
if S.fromList primaryKeys /= S.fromList specifiedKeys
|
||||||
then return $ responseLBS status405 []
|
then return $ responseLBS status405 []
|
||||||
"You must speficy all and only primary keys as params"
|
"You must speficy all and only primary keys as params"
|
||||||
else do
|
else do
|
||||||
tableCols <- map (cs . colName) <$> columns conn qt
|
tableCols <- map (cs . colName) <$> columns qt
|
||||||
let cols = map cs $ keys obj
|
let cols = map cs $ keys obj
|
||||||
if S.fromList tableCols == S.fromList cols then do
|
if S.fromList tableCols == S.fromList cols then do
|
||||||
let vals = elems obj
|
let vals = elems obj
|
||||||
_ <- uncurry (execute conn) $ iffNotT
|
H.unit $ iffNotT
|
||||||
(whereT qq $ update qt cols vals)
|
(whereT qq $ update qt cols vals)
|
||||||
(insertInto qt cols vals)
|
(insertInto qt cols vals)
|
||||||
return $ responseLBS status204 [ jsonH ] ""
|
return $ responseLBS status204 [ jsonH ] ""
|
||||||
@@ -135,9 +137,9 @@ app conn req respond =
|
|||||||
"You must specify all columns in PUT request"
|
"You must specify all columns in PUT request"
|
||||||
|
|
||||||
([table], "PATCH") ->
|
([table], "PATCH") ->
|
||||||
handleJsonObj req $ \obj -> do
|
handleJsonObj req $ \obj -> H.tx Nothing $ do
|
||||||
let qt = QualifiedTable schema (cs table)
|
let qt = QualifiedTable schema (cs table)
|
||||||
_ <- uncurry (execute conn)
|
H.unit
|
||||||
$ whereT qq
|
$ whereT qq
|
||||||
$ update qt (map cs $ keys obj) (elems obj)
|
$ update qt (map cs $ keys obj) (elems obj)
|
||||||
return $ responseLBS status204 [ jsonH ] ""
|
return $ responseLBS status204 [ jsonH ] ""
|
||||||
@@ -184,9 +186,9 @@ requestedSchema hdrs =
|
|||||||
jsonH :: Header
|
jsonH :: Header
|
||||||
jsonH = (hContentType, "application/json")
|
jsonH = (hContentType, "application/json")
|
||||||
|
|
||||||
handleJsonObj :: Request -> (Object -> IO Response) -> IO Response
|
handleJsonObj :: MonadIO m => Request -> (Object -> m Response) -> m Response
|
||||||
handleJsonObj req handler = do
|
handleJsonObj req handler = do
|
||||||
parse <- fmap eitherDecode . strictRequestBody $ req
|
parse <- liftIO $ fmap eitherDecode . strictRequestBody $ req
|
||||||
case parse of
|
case parse of
|
||||||
Left err ->
|
Left err ->
|
||||||
return $ responseLBS status400 [jsonH] jErr
|
return $ responseLBS status400 [jsonH] jErr
|
||||||
|
|||||||
Reference in New Issue
Block a user