-
Notifications
You must be signed in to change notification settings - Fork 6
/
DatabaseEsq.hs
87 lines (71 loc) · 3.47 KB
/
DatabaseEsq.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{-# LANGUAGE OverloadedStrings #-}
module DatabaseEsq where
import Control.Monad (void)
import Control.Monad.Logger (runStdoutLoggingT, MonadLogger, LoggingT,
LogLevel(..), filterLogger)
import Control.Monad.Reader (runReaderT)
import Control.Monad.IO.Class (MonadIO)
import Data.ByteString.Char8 (pack, unpack)
import Data.Int (Int64)
import Data.Maybe (listToMaybe)
import Database.Esqueleto (select, from, where_, (^.), val, (==.), on,
InnerJoin(..), limit, orderBy, desc)
import Database.Persist (get, insert, delete, entityVal, Entity)
import Database.Persist.Sql (fromSqlKey, toSqlKey)
import Database.Persist.Postgresql (ConnectionString, withPostgresqlConn,
runMigration, SqlPersistT)
import SchemaEsq
type PGInfo = ConnectionString
localConnString :: PGInfo
localConnString = "host=127.0.0.1 port=5432 user=postgres dbname=postgres password=postgres"
logFilter :: a -> LogLevel -> Bool
logFilter _ LevelError = True
logFilter _ LevelWarn = True
logFilter _ LevelInfo = True
logFilter _ LevelDebug = False
logFilter _ (LevelOther _) = False
runAction :: PGInfo -> SqlPersistT (LoggingT IO) a -> IO a
runAction connectionString action =
runStdoutLoggingT $ filterLogger logFilter $ withPostgresqlConn connectionString $ \backend ->
runReaderT action backend
migrateDB :: PGInfo -> IO ()
migrateDB connString = runAction connString (runMigration migrateAll)
fetchUserPG :: PGInfo -> Int64 -> IO (Maybe User)
fetchUserPG connString uid = runAction connString (get (toSqlKey uid))
createUserPG :: PGInfo -> User -> IO Int64
createUserPG connString user = fromSqlKey <$> runAction connString (insert user)
deleteUserPG :: PGInfo -> Int64 -> IO ()
deleteUserPG connString uid = runAction connString (delete userKey)
where
userKey :: Key User
userKey = toSqlKey uid
fetchArticlePG :: PGInfo -> Int64 -> IO (Maybe Article)
fetchArticlePG connString aid = runAction connString selectAction
where
selectAction :: SqlPersistT (LoggingT IO) (Maybe Article)
selectAction = ((fmap entityVal) . listToMaybe) <$> (select . from $ \articles -> do
where_ (articles ^. ArticleId ==. val (toSqlKey aid))
return articles)
fetchArticlesByAuthorPG :: PGInfo -> Int64 -> IO [Entity Article]
fetchArticlesByAuthorPG connString uid = runAction connString fetchAction
where
fetchAction :: SqlPersistT (LoggingT IO) [Entity Article]
fetchAction = select . from $ \articles -> do
where_ (articles ^. ArticleAuthorId ==. val (toSqlKey uid))
return articles
fetchRecentArticlesPG :: PGInfo -> IO [(Entity User, Entity Article)]
fetchRecentArticlesPG connString = runAction connString fetchAction
where
fetchAction :: SqlPersistT (LoggingT IO) [(Entity User, Entity Article)]
fetchAction = select . from $ \(users `InnerJoin` articles) -> do
on (users ^. UserId ==. articles ^. ArticleAuthorId)
orderBy [desc (articles ^. ArticlePublishedTime)]
limit 3
return (users, articles)
createArticlePG :: PGInfo -> Article -> IO Int64
createArticlePG connString article = fromSqlKey <$> runAction connString (insert article)
deleteArticlePG :: PGInfo -> Int64 -> IO ()
deleteArticlePG connString aid = runAction connString (delete articleKey)
where
articleKey :: Key Article
articleKey = toSqlKey aid