scotty-rest-0.2.0.0: examples/Database.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Exception (SomeException, try)
import Control.Monad.State
import Data.Aeson hiding (json)
import Data.Foldable
import Data.Text.Lazy hiding (map)
import Database.SQLite.Simple hiding (fold)
import GHC.Generics
import Network.Wai.Middleware.RequestLogger
import Web.Scotty.Rest
import Web.Scotty.Trans hiding (get, put)
data Message = Message {
message :: Text
} deriving Generic
instance FromJSON Message
app :: IO ()
app = scottyT 3000 (`evalStateT` Nothing) $ do
middleware logStdoutDev
rest "/messages" defaultConfig { allowedMethods = allowed
, serviceAvailable = available
, contentTypesProvided = provided
, contentTypesAccepted = accepted
}
where
available = do
-- Try to open the database, if we fail, the service is not available, so
-- we return False.
connection <- liftIO (try (open "test.db") :: IO (Either SomeException Connection))
case connection of
Left ex -> (html . pack . show) ex >> return False
Right conn -> do
liftIO $ execute_ conn "CREATE TABLE IF NOT EXISTS messages (message varchar)"
lift (put (Just conn)) -- store the database connection handle in the state
return True
allowed = return [GET, HEAD, POST, OPTIONS]
provided = return [
("text/html", do
Just conn <- lift get
messages <- liftIO $ query_ conn "SELECT message FROM messages LIMIT 10"
text $ fold $ map (\(Only m) -> pack m `snoc` '\n') messages
),
("application/json", do
Just conn <- lift get
messages <- liftIO $ query_ conn "SELECT message FROM messages LIMIT 10"
json $ map (\(Only m) -> pack m `snoc` '\n') messages
)
]
accepted = return [
("application/json", do
Just conn <- lift get
Message msg <- jsonData
liftIO $ execute conn "INSERT INTO messages(message) VALUES (?)" (Only msg)
return Succeeded
)
]
main :: IO ()
main = app