ebook-manager/backend/src/Database/Tag.hs

63 lines
2.1 KiB
Haskell
Raw Normal View History

2018-08-14 22:19:55 +03:00
{-# Language TypeApplications #-}
{-# Language TypeOperators #-}
{-# Language DataKinds #-}
{-# Language DuplicateRecordFields #-}
{-# Language NamedFieldPuns #-}
module Database.Tag
( def
, booksTags
, attachTag
, upsertTag
, clearTags
2018-08-14 22:19:55 +03:00
, Tag(..) ) where
import ClassyPrelude
2018-10-17 23:51:30 +03:00
import Control.Monad.Catch (MonadCatch)
import Control.Monad.Trans.Maybe
2018-08-14 22:19:55 +03:00
import Database
2018-10-17 23:51:30 +03:00
import Database.Schema
2018-08-14 22:19:55 +03:00
import Database.Selda
import Database.Selda.Generic
2018-10-17 23:51:30 +03:00
upsertTag :: (MonadCatch m, MonadIO m, MonadSelda m) => Username -> Text -> m (Maybe Tag)
2018-08-15 22:10:15 +03:00
upsertTag username tag = runMaybeT $ do
userId <- MaybeT (listToMaybe <$> query userQ)
void $ lift $ upsert (gen tags) (predicate userId) id [toRel (Tag def tag userId)]
MaybeT (listToMaybe . fromRels <$> query (tagQ userId))
2018-08-14 22:19:55 +03:00
where
predicate userId (_ :*: tag' :*: owner) = tag' .== literal tag .&& owner .== literal userId
tagQ userId = do
t@(_ :*: tag' :*: owner) <- select (gen tags)
restrict (tag' .== literal tag .&& owner .== literal userId)
return t
userQ = do
userId :*: _ :*: username' :*: _ <- select (gen users)
restrict (username' .== literal username)
return userId
2018-10-17 23:51:30 +03:00
booksTags :: (MonadIO m, MonadSelda m) => BookID -> m [Tag]
2018-08-14 22:19:55 +03:00
booksTags bookId = fromRels <$> query q
where
q = do
tagId :*: bookId' <- select (gen bookTags)
tag@(tagId' :*: _) <- select (gen tags)
restrict (tagId .== tagId')
restrict (bookId' .== literal bookId)
return tag
2018-10-17 23:51:30 +03:00
attachTag :: (MonadCatch m, MonadIO m, MonadSelda m) => Username -> BookID -> Text -> m ()
2018-08-14 22:19:55 +03:00
attachTag username bookId tag = do
2018-08-15 22:10:15 +03:00
maybeT <- upsertTag username tag
forM_ maybeT $ \Tag{identifier} -> do
whenM (null <$> query (tagQ identifier)) $
void $ insertGen bookTags [BookTag identifier bookId]
2018-08-14 22:19:55 +03:00
where
tagQ tagId = do
(tagId' :*: bookId') <- select (gen bookTags)
restrict (tagId' .== literal tagId .&& bookId' .== literal bookId)
return tagId'
2018-10-17 23:51:30 +03:00
clearTags :: (MonadIO m, MonadSelda m) => BookID -> m Int
clearTags bookId = deleteFrom (gen bookTags) (\(_ :*: bookId') -> bookId' .== literal bookId)