#8 Support for tags #13

Merged
MasseR merged 1 commits from sandbox/MasseR/8-tags into master 2018-08-14 23:50:49 +03:00
3 changed files with 38 additions and 5 deletions

View File

@ -23,7 +23,8 @@ import Database
import Database.Selda import Database.Selda
import Database.Selda.Generic import Database.Selda.Generic
import Database.Tag (attachTag) import Database.Tag (attachTag, clearTags)
import Database.Channel (attachChannel, clearChannels)
usersBooks :: (MonadSelda m, MonadMask m, MonadIO m) => Username -> m [Book] usersBooks :: (MonadSelda m, MonadMask m, MonadIO m) => Username -> m [Book]
usersBooks username = fromRels <$> query q usersBooks username = fromRels <$> query q
@ -67,7 +68,8 @@ data UpdateBook = UpdateBook { identifier :: BookID
, title :: Maybe Text , title :: Maybe Text
, description :: Maybe Text , description :: Maybe Text
, owner :: Username , owner :: Username
, tags :: [Text]} , tags :: [Text]
, channels :: [Text] }
bookExists :: (MonadSelda m, MonadMask m, MonadIO m) => BookID -> m Bool bookExists :: (MonadSelda m, MonadMask m, MonadIO m) => BookID -> m Bool
bookExists identifier = not . null <$> query q bookExists identifier = not . null <$> query q
@ -91,12 +93,12 @@ bookOwner' identifier username = do
updateBook :: (MonadSelda m, MonadMask m, MonadIO m) => UpdateBook -> m (Maybe UpdateBook) updateBook :: (MonadSelda m, MonadMask m, MonadIO m) => UpdateBook -> m (Maybe UpdateBook)
updateBook book@UpdateBook{..} = do updateBook book@UpdateBook{..} = do
connectChannels clearTags identifier >> connectTags
connectTags clearChannels identifier >> connectChannels
updateBook' updateBook'
where where
connectTags = mapM_ (attachTag owner identifier) tags connectTags = mapM_ (attachTag owner identifier) tags
connectChannels = return () connectChannels = mapM_ (attachChannel owner identifier) channels
updateBook' = do updateBook' = do
mUserId <- query (bookOwner' identifier owner) mUserId <- query (bookOwner' identifier owner)
forM (listToMaybe mUserId) $ \_userId -> do forM (listToMaybe mUserId) $ \_userId -> do

View File

@ -1,8 +1,11 @@
{-# Language TypeApplications #-} {-# Language TypeApplications #-}
{-# Language DataKinds #-} {-# Language DataKinds #-}
{-# Language NamedFieldPuns #-}
module Database.Channel module Database.Channel
( userChannels ( userChannels
, insertChannel , insertChannel
, attachChannel
, clearChannels
, booksChannels , booksChannels
, Channel(..) , Channel(..)
, ChannelID ) , ChannelID )
@ -12,6 +15,7 @@ import ClassyPrelude
import Database.Schema import Database.Schema
import Database import Database
import Database.Selda import Database.Selda
import Database.Selda.Generic
userChannels :: (MonadMask m, MonadIO m) => Username -> SeldaT m [Channel] userChannels :: (MonadMask m, MonadIO m) => Username -> SeldaT m [Channel]
userChannels username = fromRels <$> query q userChannels username = fromRels <$> query q
@ -44,3 +48,25 @@ booksChannels bookId = fromRels <$> query q
restrict (channelId .== channelId') restrict (channelId .== channelId')
restrict (bookId' .== literal bookId) restrict (bookId' .== literal bookId)
return ch return ch
attachChannel :: (MonadMask m, MonadIO m, MonadSelda m) => Username -> BookID -> Text -> m ()
attachChannel username bookId channel = do
-- XXX: test what happens if channel doesn't exist
[Channel{identifier}] <- fromRels <$> query channelQ
whenM (null <$> query (attachQ identifier)) $
void $ insertGen bookChannels [BookChannel identifier bookId]
where
attachQ channelId = do
(channelId' :*: bookId') <- select (gen bookChannels)
restrict (channelId' .== literal channelId .&& bookId' .== literal bookId)
return channelId'
channelQ = do
userId :*: _ :*: username' :*: _ <- select (gen users)
ch@(_ :*: channel' :*: owner) <- select (gen channels)
restrict (username' .== literal username)
restrict (owner .== userId)
restrict (channel' .== literal channel)
return ch
clearChannels :: (MonadMask m, MonadIO m, MonadSelda m) => BookID -> m Int
clearChannels bookId = deleteFrom (gen bookChannels) (\(_ :*: bookId') -> bookId' .== literal bookId)

View File

@ -8,6 +8,7 @@ module Database.Tag
, booksTags , booksTags
, attachTag , attachTag
, upsertTag , upsertTag
, clearTags
, Tag(..) ) where , Tag(..) ) where
import ClassyPrelude import ClassyPrelude
@ -55,3 +56,7 @@ attachTag username bookId tag = do
(tagId' :*: bookId') <- select (gen bookTags) (tagId' :*: bookId') <- select (gen bookTags)
restrict (tagId' .== literal tagId .&& bookId' .== literal bookId) restrict (tagId' .== literal tagId .&& bookId' .== literal bookId)
return tagId' return tagId'
clearTags :: (MonadMask m, MonadIO m, MonadSelda m) => BookID -> m Int
clearTags bookId = deleteFrom (gen bookTags) (\(_ :*: bookId') -> bookId' .== literal bookId)