{-# LANGUAGE GeneralisedNewtypeDeriving #-}

-- |
-- Module      : Docs.Hasql.Database
-- Description : PostgreSQL Implementation for Document Management
-- License     : AGPL-3
-- Maintainer  : stu235271@mail.uni-kiel.de
--               stu236925@mail.uni-kiel.de
--
-- This module contains an implmenetation of "Docs.Database" for PostgreSQL
-- using Hasql.
module Docs.Hasql.Database
    ( HasqlSession (..)
    , HasqlTransaction (..)
    , run
    , runTransaction
    ) where

import Hasql.Connection (Connection)
import Hasql.Session (Session, SessionError)
import qualified Hasql.Session as Session
import Hasql.Transaction (Transaction, condemn)
import Hasql.Transaction.Sessions
    ( IsolationLevel (..)
    , Mode (..)
    , transaction
    )

import Docs.Database

import qualified UserManagement.Sessions as UserSessions
import qualified UserManagement.Transactions as UserTransactions

import Control.Monad.IO.Class (MonadIO (liftIO))
import qualified Docs.Hasql.Sessions as Sessions
import qualified Docs.Hasql.Transactions as Transactions
import Logging.Logs (Severity (..))
import qualified Logging.Scope as Scope

-- * Session

-- | Wrapper around a Hasql @Session@
newtype HasqlSession a = HasqlSession
    { forall a. HasqlSession a -> Session a
unHasqlSession :: Session a
    }
    deriving ((forall a b. (a -> b) -> HasqlSession a -> HasqlSession b)
-> (forall a b. a -> HasqlSession b -> HasqlSession a)
-> Functor HasqlSession
forall a b. a -> HasqlSession b -> HasqlSession a
forall a b. (a -> b) -> HasqlSession a -> HasqlSession b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> HasqlSession a -> HasqlSession b
fmap :: forall a b. (a -> b) -> HasqlSession a -> HasqlSession b
$c<$ :: forall a b. a -> HasqlSession b -> HasqlSession a
<$ :: forall a b. a -> HasqlSession b -> HasqlSession a
Functor, Functor HasqlSession
Functor HasqlSession =>
(forall a. a -> HasqlSession a)
-> (forall a b.
    HasqlSession (a -> b) -> HasqlSession a -> HasqlSession b)
-> (forall a b c.
    (a -> b -> c)
    -> HasqlSession a -> HasqlSession b -> HasqlSession c)
-> (forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b)
-> (forall a b. HasqlSession a -> HasqlSession b -> HasqlSession a)
-> Applicative HasqlSession
forall a. a -> HasqlSession a
forall a b. HasqlSession a -> HasqlSession b -> HasqlSession a
forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
forall a b.
HasqlSession (a -> b) -> HasqlSession a -> HasqlSession b
forall a b c.
(a -> b -> c) -> HasqlSession a -> HasqlSession b -> HasqlSession c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> HasqlSession a
pure :: forall a. a -> HasqlSession a
$c<*> :: forall a b.
HasqlSession (a -> b) -> HasqlSession a -> HasqlSession b
<*> :: forall a b.
HasqlSession (a -> b) -> HasqlSession a -> HasqlSession b
$cliftA2 :: forall a b c.
(a -> b -> c) -> HasqlSession a -> HasqlSession b -> HasqlSession c
liftA2 :: forall a b c.
(a -> b -> c) -> HasqlSession a -> HasqlSession b -> HasqlSession c
$c*> :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
*> :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
$c<* :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession a
<* :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession a
Applicative, Applicative HasqlSession
Applicative HasqlSession =>
(forall a b.
 HasqlSession a -> (a -> HasqlSession b) -> HasqlSession b)
-> (forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b)
-> (forall a. a -> HasqlSession a)
-> Monad HasqlSession
forall a. a -> HasqlSession a
forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
forall a b.
HasqlSession a -> (a -> HasqlSession b) -> HasqlSession b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b.
HasqlSession a -> (a -> HasqlSession b) -> HasqlSession b
>>= :: forall a b.
HasqlSession a -> (a -> HasqlSession b) -> HasqlSession b
$c>> :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
>> :: forall a b. HasqlSession a -> HasqlSession b -> HasqlSession b
$creturn :: forall a. a -> HasqlSession a
return :: forall a. a -> HasqlSession a
Monad)

instance MonadIO HasqlSession where
    liftIO :: forall a. IO a -> HasqlSession a
liftIO = Session a -> HasqlSession a
forall a. Session a -> HasqlSession a
HasqlSession (Session a -> HasqlSession a)
-> (IO a -> Session a) -> IO a -> HasqlSession a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> Session a
forall a. IO a -> Session a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Runs a @HasqlSession@ and logs potential errors if possible
run :: HasqlSession a -> Connection -> IO (Either SessionError a)
run :: forall a.
HasqlSession a -> Connection -> IO (Either SessionError a)
run HasqlSession a
session Connection
conn = do
    Either SessionError a
result <- HasqlSession a -> Connection -> IO (Either SessionError a)
forall a.
HasqlSession a -> Connection -> IO (Either SessionError a)
runUnlogged HasqlSession a
session Connection
conn
    case Either SessionError a
result of
        Left SessionError
err -> do
            -- If something went wrong here, its fucked up anyway :)
            -- We could cache the result and insert it into the db as soon as the
            -- problem is solved, but i think this is currently not required.
            Right LogMessage
_ <-
                (HasqlSession LogMessage
 -> Connection -> IO (Either SessionError LogMessage))
-> Connection
-> HasqlSession LogMessage
-> IO (Either SessionError LogMessage)
forall a b c. (a -> b -> c) -> b -> a -> c
flip HasqlSession LogMessage
-> Connection -> IO (Either SessionError LogMessage)
forall a.
HasqlSession a -> Connection -> IO (Either SessionError a)
runUnlogged Connection
conn (HasqlSession LogMessage -> IO (Either SessionError LogMessage))
-> HasqlSession LogMessage -> IO (Either SessionError LogMessage)
forall a b. (a -> b) -> a -> b
$
                    Severity
-> Maybe UserID -> Scope -> String -> HasqlSession LogMessage
forall v.
ToJSON v =>
Severity -> Maybe UserID -> Scope -> v -> HasqlSession LogMessage
forall (m :: * -> *) v.
(HasLogMessage m, ToJSON v) =>
Severity -> Maybe UserID -> Scope -> v -> m LogMessage
logMessage Severity
Error Maybe UserID
forall a. Maybe a
Nothing Scope
Scope.database (String -> HasqlSession LogMessage)
-> String -> HasqlSession LogMessage
forall a b. (a -> b) -> a -> b
$
                        SessionError -> String
forall a. Show a => a -> String
show SessionError
err
            Either SessionError a -> IO (Either SessionError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either SessionError a
result
        Right a
_ -> Either SessionError a -> IO (Either SessionError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either SessionError a
result
  where
    runUnlogged :: HasqlSession a -> Connection -> IO (Either SessionError a)
runUnlogged = Session a -> Connection -> IO (Either SessionError a)
forall a. Session a -> Connection -> IO (Either SessionError a)
Session.run (Session a -> Connection -> IO (Either SessionError a))
-> (HasqlSession a -> Session a)
-> HasqlSession a
-> Connection
-> IO (Either SessionError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasqlSession a -> Session a
forall a. HasqlSession a -> Session a
unHasqlSession

-- ** Access Right Queries

instance HasCheckPermission HasqlSession where
    checkDocumentPermission :: UserID -> DocumentID -> Permission -> HasqlSession Bool
checkDocumentPermission = ((Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (Permission -> Session Bool) -> Permission -> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Permission -> Session Bool) -> Permission -> HasqlSession Bool)
-> (DocumentID -> Permission -> Session Bool)
-> DocumentID
-> Permission
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((DocumentID -> Permission -> Session Bool)
 -> DocumentID -> Permission -> HasqlSession Bool)
-> (UserID -> DocumentID -> Permission -> Session Bool)
-> UserID
-> DocumentID
-> Permission
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> DocumentID -> Permission -> Session Bool
Sessions.hasPermission

instance HasIsGroupAdmin HasqlSession where
    isGroupAdmin :: UserID -> GroupID -> HasqlSession Bool
isGroupAdmin = (Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (GroupID -> Session Bool) -> GroupID -> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Session Bool) -> GroupID -> HasqlSession Bool)
-> (UserID -> GroupID -> Session Bool)
-> UserID
-> GroupID
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> GroupID -> Session Bool
Sessions.isGroupAdmin

instance HasIsSuperAdmin HasqlSession where
    isSuperAdmin :: UserID -> HasqlSession Bool
isSuperAdmin = Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (UserID -> Session Bool) -> UserID -> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> Session Bool
UserSessions.checkSuperadmin

-- ** Exists Queries

instance HasExistsDocument HasqlSession where
    existsDocument :: DocumentID -> HasqlSession Bool
existsDocument = Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (DocumentID -> Session Bool) -> DocumentID -> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Session Bool
Sessions.existsDocument

instance HasExistsTextElement HasqlSession where
    existsTextElement :: TextElementRef -> HasqlSession Bool
existsTextElement = Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (TextElementRef -> Session Bool)
-> TextElementRef
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRef -> Session Bool
Sessions.existsTextElement

instance HasExistsTextRevision HasqlSession where
    existsTextRevision :: TextRevisionRef -> HasqlSession Bool
existsTextRevision = Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (TextRevisionRef -> Session Bool)
-> TextRevisionRef
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionRef -> Session Bool
Sessions.existsTextRevision

instance HasExistsTreeRevision HasqlSession where
    existsTreeRevision :: TreeRevisionRef -> HasqlSession Bool
existsTreeRevision = Session Bool -> HasqlSession Bool
forall a. Session a -> HasqlSession a
HasqlSession (Session Bool -> HasqlSession Bool)
-> (TreeRevisionRef -> Session Bool)
-> TreeRevisionRef
-> HasqlSession Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeRevisionRef -> Session Bool
Sessions.existsTreeRevision

-- ** Get Queries

instance HasGetDocument HasqlSession where
    getDocument :: DocumentID -> HasqlSession (Maybe Document)
getDocument = Session (Maybe Document) -> HasqlSession (Maybe Document)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Maybe Document) -> HasqlSession (Maybe Document))
-> (DocumentID -> Session (Maybe Document))
-> DocumentID
-> HasqlSession (Maybe Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Session (Maybe Document)
Sessions.getDocument
    getDocuments :: UserID -> HasqlSession (Vector Document)
getDocuments = Session (Vector Document) -> HasqlSession (Vector Document)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Vector Document) -> HasqlSession (Vector Document))
-> (UserID -> Session (Vector Document))
-> UserID
-> HasqlSession (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> Session (Vector Document)
Sessions.getDocuments
    getDocumentsBy :: Maybe UserID -> Maybe GroupID -> HasqlSession (Vector Document)
getDocumentsBy = (Session (Vector Document) -> HasqlSession (Vector Document)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Vector Document) -> HasqlSession (Vector Document))
-> (Maybe GroupID -> Session (Vector Document))
-> Maybe GroupID
-> HasqlSession (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe GroupID -> Session (Vector Document))
 -> Maybe GroupID -> HasqlSession (Vector Document))
-> (Maybe UserID -> Maybe GroupID -> Session (Vector Document))
-> Maybe UserID
-> Maybe GroupID
-> HasqlSession (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe UserID -> Maybe GroupID -> Session (Vector Document)
Sessions.getDocumentsBy

instance HasGetTreeRevision HasqlSession where
    getTreeRevision :: TreeRevisionRef -> HasqlSession (Maybe (TreeRevision TextElement))
getTreeRevision = Session (Maybe (TreeRevision TextElement))
-> HasqlSession (Maybe (TreeRevision TextElement))
forall a. Session a -> HasqlSession a
HasqlSession (Session (Maybe (TreeRevision TextElement))
 -> HasqlSession (Maybe (TreeRevision TextElement)))
-> (TreeRevisionRef -> Session (Maybe (TreeRevision TextElement)))
-> TreeRevisionRef
-> HasqlSession (Maybe (TreeRevision TextElement))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeRevisionRef -> Session (Maybe (TreeRevision TextElement))
Sessions.getTreeRevision

instance HasGetTextElementRevision HasqlSession where
    getTextElementRevision :: TextRevisionRef -> HasqlSession (Maybe TextElementRevision)
getTextElementRevision = Session (Maybe TextElementRevision)
-> HasqlSession (Maybe TextElementRevision)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Maybe TextElementRevision)
 -> HasqlSession (Maybe TextElementRevision))
-> (TextRevisionRef -> Session (Maybe TextElementRevision))
-> TextRevisionRef
-> HasqlSession (Maybe TextElementRevision)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionRef -> Session (Maybe TextElementRevision)
Sessions.getTextElementRevision

instance HasGetTextHistory HasqlSession where
    getTextHistory :: TextElementRef
-> Maybe UTCTime
-> Maybe UTCTime
-> GroupID
-> HasqlSession TextRevisionHistory
getTextHistory = (((Session TextRevisionHistory -> HasqlSession TextRevisionHistory
forall a. Session a -> HasqlSession a
HasqlSession (Session TextRevisionHistory -> HasqlSession TextRevisionHistory)
-> (GroupID -> Session TextRevisionHistory)
-> GroupID
-> HasqlSession TextRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Session TextRevisionHistory)
 -> GroupID -> HasqlSession TextRevisionHistory)
-> (Maybe UTCTime -> GroupID -> Session TextRevisionHistory)
-> Maybe UTCTime
-> GroupID
-> HasqlSession TextRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UTCTime -> GroupID -> Session TextRevisionHistory)
 -> Maybe UTCTime -> GroupID -> HasqlSession TextRevisionHistory)
-> (Maybe UTCTime
    -> Maybe UTCTime -> GroupID -> Session TextRevisionHistory)
-> Maybe UTCTime
-> Maybe UTCTime
-> GroupID
-> HasqlSession TextRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UTCTime
  -> Maybe UTCTime -> GroupID -> Session TextRevisionHistory)
 -> Maybe UTCTime
 -> Maybe UTCTime
 -> GroupID
 -> HasqlSession TextRevisionHistory)
-> (TextElementRef
    -> Maybe UTCTime
    -> Maybe UTCTime
    -> GroupID
    -> Session TextRevisionHistory)
-> TextElementRef
-> Maybe UTCTime
-> Maybe UTCTime
-> GroupID
-> HasqlSession TextRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRef
-> Maybe UTCTime
-> Maybe UTCTime
-> GroupID
-> Session TextRevisionHistory
Sessions.getTextRevisionHistory

instance HasGetTreeHistory HasqlSession where
    getTreeHistory :: DocumentID
-> Maybe UTCTime -> GroupID -> HasqlSession TreeRevisionHistory
getTreeHistory = ((Session TreeRevisionHistory -> HasqlSession TreeRevisionHistory
forall a. Session a -> HasqlSession a
HasqlSession (Session TreeRevisionHistory -> HasqlSession TreeRevisionHistory)
-> (GroupID -> Session TreeRevisionHistory)
-> GroupID
-> HasqlSession TreeRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Session TreeRevisionHistory)
 -> GroupID -> HasqlSession TreeRevisionHistory)
-> (Maybe UTCTime -> GroupID -> Session TreeRevisionHistory)
-> Maybe UTCTime
-> GroupID
-> HasqlSession TreeRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UTCTime -> GroupID -> Session TreeRevisionHistory)
 -> Maybe UTCTime -> GroupID -> HasqlSession TreeRevisionHistory)
-> (DocumentID
    -> Maybe UTCTime -> GroupID -> Session TreeRevisionHistory)
-> DocumentID
-> Maybe UTCTime
-> GroupID
-> HasqlSession TreeRevisionHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID
-> Maybe UTCTime -> GroupID -> Session TreeRevisionHistory
Sessions.getTreeRevisionHistory

instance HasGetDocumentHistory HasqlSession where
    getDocumentHistory :: DocumentID
-> Maybe UTCTime -> GroupID -> HasqlSession DocumentHistory
getDocumentHistory = ((Session DocumentHistory -> HasqlSession DocumentHistory
forall a. Session a -> HasqlSession a
HasqlSession (Session DocumentHistory -> HasqlSession DocumentHistory)
-> (GroupID -> Session DocumentHistory)
-> GroupID
-> HasqlSession DocumentHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Session DocumentHistory)
 -> GroupID -> HasqlSession DocumentHistory)
-> (Maybe UTCTime -> GroupID -> Session DocumentHistory)
-> Maybe UTCTime
-> GroupID
-> HasqlSession DocumentHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UTCTime -> GroupID -> Session DocumentHistory)
 -> Maybe UTCTime -> GroupID -> HasqlSession DocumentHistory)
-> (DocumentID
    -> Maybe UTCTime -> GroupID -> Session DocumentHistory)
-> DocumentID
-> Maybe UTCTime
-> GroupID
-> HasqlSession DocumentHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Maybe UTCTime -> GroupID -> Session DocumentHistory
Sessions.getDocumentRevisionHistory

instance HasGetComments HasqlSession where
    getComments :: TextElementRef -> HasqlSession (Vector Comment)
getComments = Session (Vector Comment) -> HasqlSession (Vector Comment)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Vector Comment) -> HasqlSession (Vector Comment))
-> (TextElementRef -> Session (Vector Comment))
-> TextElementRef
-> HasqlSession (Vector Comment)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRef -> Session (Vector Comment)
Sessions.getComments

instance HasGetLogs HasqlSession where
    getLogs :: Maybe UTCTime -> GroupID -> HasqlSession (Vector LogMessage)
getLogs = (Session (Vector LogMessage) -> HasqlSession (Vector LogMessage)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Vector LogMessage) -> HasqlSession (Vector LogMessage))
-> (GroupID -> Session (Vector LogMessage))
-> GroupID
-> HasqlSession (Vector LogMessage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Session (Vector LogMessage))
 -> GroupID -> HasqlSession (Vector LogMessage))
-> (Maybe UTCTime -> GroupID -> Session (Vector LogMessage))
-> Maybe UTCTime
-> GroupID
-> HasqlSession (Vector LogMessage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe UTCTime -> GroupID -> Session (Vector LogMessage)
Sessions.getLogs

instance HasGetRevisionKey HasqlSession where
    getRevisionKey :: RevisionRef -> HasqlSession (Maybe RevisionKey)
getRevisionKey = Session (Maybe RevisionKey) -> HasqlSession (Maybe RevisionKey)
forall a. Session a -> HasqlSession a
HasqlSession (Session (Maybe RevisionKey) -> HasqlSession (Maybe RevisionKey))
-> (RevisionRef -> Session (Maybe RevisionKey))
-> RevisionRef
-> HasqlSession (Maybe RevisionKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RevisionRef -> Session (Maybe RevisionKey)
Sessions.getRevisionKey

-- ** Create Queries

instance HasCreateDocument HasqlSession where
    createDocument :: Text -> GroupID -> UserID -> HasqlSession Document
createDocument = ((Session Document -> HasqlSession Document
forall a. Session a -> HasqlSession a
HasqlSession (Session Document -> HasqlSession Document)
-> (UserID -> Session Document) -> UserID -> HasqlSession Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((UserID -> Session Document) -> UserID -> HasqlSession Document)
-> (GroupID -> UserID -> Session Document)
-> GroupID
-> UserID
-> HasqlSession Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> UserID -> Session Document)
 -> GroupID -> UserID -> HasqlSession Document)
-> (Text -> GroupID -> UserID -> Session Document)
-> Text
-> GroupID
-> UserID
-> HasqlSession Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> GroupID -> UserID -> Session Document
Sessions.createDocument

instance HasCreateTextElement HasqlSession where
    createTextElement :: DocumentID -> Text -> Text -> HasqlSession TextElement
createTextElement = ((Session TextElement -> HasqlSession TextElement
forall a. Session a -> HasqlSession a
HasqlSession (Session TextElement -> HasqlSession TextElement)
-> (Text -> Session TextElement)
-> Text
-> HasqlSession TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Session TextElement) -> Text -> HasqlSession TextElement)
-> (Text -> Text -> Session TextElement)
-> Text
-> Text
-> HasqlSession TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Text -> Session TextElement)
 -> Text -> Text -> HasqlSession TextElement)
-> (DocumentID -> Text -> Text -> Session TextElement)
-> DocumentID
-> Text
-> Text
-> HasqlSession TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Text -> Text -> Session TextElement
Sessions.createTextElement

instance HasLogMessage HasqlSession where
    logMessage :: forall v.
ToJSON v =>
Severity -> Maybe UserID -> Scope -> v -> HasqlSession LogMessage
logMessage = (((Session LogMessage -> HasqlSession LogMessage
forall a. Session a -> HasqlSession a
HasqlSession (Session LogMessage -> HasqlSession LogMessage)
-> (v -> Session LogMessage) -> v -> HasqlSession LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((v -> Session LogMessage) -> v -> HasqlSession LogMessage)
-> (Scope -> v -> Session LogMessage)
-> Scope
-> v
-> HasqlSession LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Scope -> v -> Session LogMessage)
 -> Scope -> v -> HasqlSession LogMessage)
-> (Maybe UserID -> Scope -> v -> Session LogMessage)
-> Maybe UserID
-> Scope
-> v
-> HasqlSession LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UserID -> Scope -> v -> Session LogMessage)
 -> Maybe UserID -> Scope -> v -> HasqlSession LogMessage)
-> (Severity -> Maybe UserID -> Scope -> v -> Session LogMessage)
-> Severity
-> Maybe UserID
-> Scope
-> v
-> HasqlSession LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Severity -> Maybe UserID -> Scope -> v -> Session LogMessage
forall v.
ToJSON v =>
Severity -> Maybe UserID -> Scope -> v -> Session LogMessage
Sessions.logMessage

-- * Transaction

-- | Wrapper around a Hasql @Transaction@
newtype HasqlTransaction a = HasqlTransaction
    { forall a. HasqlTransaction a -> Transaction a
unHasqlTransaction :: Transaction a
    }
    deriving ((forall a b. (a -> b) -> HasqlTransaction a -> HasqlTransaction b)
-> (forall a b. a -> HasqlTransaction b -> HasqlTransaction a)
-> Functor HasqlTransaction
forall a b. a -> HasqlTransaction b -> HasqlTransaction a
forall a b. (a -> b) -> HasqlTransaction a -> HasqlTransaction b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> HasqlTransaction a -> HasqlTransaction b
fmap :: forall a b. (a -> b) -> HasqlTransaction a -> HasqlTransaction b
$c<$ :: forall a b. a -> HasqlTransaction b -> HasqlTransaction a
<$ :: forall a b. a -> HasqlTransaction b -> HasqlTransaction a
Functor, Functor HasqlTransaction
Functor HasqlTransaction =>
(forall a. a -> HasqlTransaction a)
-> (forall a b.
    HasqlTransaction (a -> b)
    -> HasqlTransaction a -> HasqlTransaction b)
-> (forall a b c.
    (a -> b -> c)
    -> HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction c)
-> (forall a b.
    HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b)
-> (forall a b.
    HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction a)
-> Applicative HasqlTransaction
forall a. a -> HasqlTransaction a
forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction a
forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
forall a b.
HasqlTransaction (a -> b)
-> HasqlTransaction a -> HasqlTransaction b
forall a b c.
(a -> b -> c)
-> HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> HasqlTransaction a
pure :: forall a. a -> HasqlTransaction a
$c<*> :: forall a b.
HasqlTransaction (a -> b)
-> HasqlTransaction a -> HasqlTransaction b
<*> :: forall a b.
HasqlTransaction (a -> b)
-> HasqlTransaction a -> HasqlTransaction b
$cliftA2 :: forall a b c.
(a -> b -> c)
-> HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction c
liftA2 :: forall a b c.
(a -> b -> c)
-> HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction c
$c*> :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
*> :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
$c<* :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction a
<* :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction a
Applicative, Applicative HasqlTransaction
Applicative HasqlTransaction =>
(forall a b.
 HasqlTransaction a
 -> (a -> HasqlTransaction b) -> HasqlTransaction b)
-> (forall a b.
    HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b)
-> (forall a. a -> HasqlTransaction a)
-> Monad HasqlTransaction
forall a. a -> HasqlTransaction a
forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
forall a b.
HasqlTransaction a
-> (a -> HasqlTransaction b) -> HasqlTransaction b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b.
HasqlTransaction a
-> (a -> HasqlTransaction b) -> HasqlTransaction b
>>= :: forall a b.
HasqlTransaction a
-> (a -> HasqlTransaction b) -> HasqlTransaction b
$c>> :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
>> :: forall a b.
HasqlTransaction a -> HasqlTransaction b -> HasqlTransaction b
$creturn :: forall a. a -> HasqlTransaction a
return :: forall a. a -> HasqlTransaction a
Monad)

-- | Runs a @HasqlTransaction@ and logs errors if possible.
runTransaction :: HasqlTransaction a -> Connection -> IO (Either SessionError a)
runTransaction :: forall a.
HasqlTransaction a -> Connection -> IO (Either SessionError a)
runTransaction HasqlTransaction a
tx Connection
conn = do
    Either SessionError a
result <- HasqlTransaction a -> Connection -> IO (Either SessionError a)
forall a.
HasqlTransaction a -> Connection -> IO (Either SessionError a)
runUnlogged HasqlTransaction a
tx Connection
conn
    case Either SessionError a
result of
        Left SessionError
err -> do
            -- If something went wrong here, its fucked up anyway :)
            -- We could cache the result and insert it into the db as soon as the
            -- problem is solved, but i think this is currently not required.
            Right LogMessage
_ <-
                (HasqlTransaction LogMessage
 -> Connection -> IO (Either SessionError LogMessage))
-> Connection
-> HasqlTransaction LogMessage
-> IO (Either SessionError LogMessage)
forall a b c. (a -> b -> c) -> b -> a -> c
flip HasqlTransaction LogMessage
-> Connection -> IO (Either SessionError LogMessage)
forall a.
HasqlTransaction a -> Connection -> IO (Either SessionError a)
runUnlogged Connection
conn (HasqlTransaction LogMessage
 -> IO (Either SessionError LogMessage))
-> HasqlTransaction LogMessage
-> IO (Either SessionError LogMessage)
forall a b. (a -> b) -> a -> b
$
                    Severity
-> Maybe UserID -> Scope -> String -> HasqlTransaction LogMessage
forall v.
ToJSON v =>
Severity
-> Maybe UserID -> Scope -> v -> HasqlTransaction LogMessage
forall (m :: * -> *) v.
(HasLogMessage m, ToJSON v) =>
Severity -> Maybe UserID -> Scope -> v -> m LogMessage
logMessage Severity
Error Maybe UserID
forall a. Maybe a
Nothing Scope
Scope.database (String -> HasqlTransaction LogMessage)
-> String -> HasqlTransaction LogMessage
forall a b. (a -> b) -> a -> b
$
                        SessionError -> String
forall a. Show a => a -> String
show SessionError
err
            Either SessionError a -> IO (Either SessionError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either SessionError a
result
        Right a
_ -> Either SessionError a -> IO (Either SessionError a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Either SessionError a
result
  where
    runUnlogged :: HasqlTransaction a -> Connection -> IO (Either SessionError a)
runUnlogged =
        (Session a -> Connection -> IO (Either SessionError a)
forall a. Session a -> Connection -> IO (Either SessionError a)
Session.run (Session a -> Connection -> IO (Either SessionError a))
-> (Transaction a -> Session a)
-> Transaction a
-> Connection
-> IO (Either SessionError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IsolationLevel -> Mode -> Transaction a -> Session a
forall a. IsolationLevel -> Mode -> Transaction a -> Session a
transaction IsolationLevel
Serializable Mode
Write)
            (Transaction a -> Connection -> IO (Either SessionError a))
-> (HasqlTransaction a -> Transaction a)
-> HasqlTransaction a
-> Connection
-> IO (Either SessionError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasqlTransaction a -> Transaction a
forall a. HasqlTransaction a -> Transaction a
unHasqlTransaction

instance HasRollback HasqlTransaction where
    rollback :: HasqlTransaction ()
rollback = Transaction () -> HasqlTransaction ()
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction Transaction ()
condemn

-- ** Access Right Queries

instance HasCheckPermission HasqlTransaction where
    checkDocumentPermission :: UserID -> DocumentID -> Permission -> HasqlTransaction Bool
checkDocumentPermission = ((Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (Permission -> Transaction Bool)
-> Permission
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Permission -> Transaction Bool)
 -> Permission -> HasqlTransaction Bool)
-> (DocumentID -> Permission -> Transaction Bool)
-> DocumentID
-> Permission
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((DocumentID -> Permission -> Transaction Bool)
 -> DocumentID -> Permission -> HasqlTransaction Bool)
-> (UserID -> DocumentID -> Permission -> Transaction Bool)
-> UserID
-> DocumentID
-> Permission
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> DocumentID -> Permission -> Transaction Bool
Transactions.hasPermission

instance HasIsGroupAdmin HasqlTransaction where
    isGroupAdmin :: UserID -> GroupID -> HasqlTransaction Bool
isGroupAdmin = (Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (GroupID -> Transaction Bool)
-> GroupID
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> Transaction Bool) -> GroupID -> HasqlTransaction Bool)
-> (UserID -> GroupID -> Transaction Bool)
-> UserID
-> GroupID
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> GroupID -> Transaction Bool
Transactions.isGroupAdmin

instance HasIsSuperAdmin HasqlTransaction where
    isSuperAdmin :: UserID -> HasqlTransaction Bool
isSuperAdmin = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (UserID -> Transaction Bool) -> UserID -> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> Transaction Bool
UserTransactions.checkSuperadmin

instance HasNow HasqlTransaction where
    now :: HasqlTransaction UTCTime
now = Transaction UTCTime -> HasqlTransaction UTCTime
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction Transaction UTCTime
Transactions.now

-- ** Exists Queries

instance HasExistsDocument HasqlTransaction where
    existsDocument :: DocumentID -> HasqlTransaction Bool
existsDocument = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (DocumentID -> Transaction Bool)
-> DocumentID
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Transaction Bool
Transactions.existsDocument

instance HasExistsTextElement HasqlTransaction where
    existsTextElement :: TextElementRef -> HasqlTransaction Bool
existsTextElement = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (TextElementRef -> Transaction Bool)
-> TextElementRef
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRef -> Transaction Bool
Transactions.existsTextElement

instance HasExistsTextRevision HasqlTransaction where
    existsTextRevision :: TextRevisionRef -> HasqlTransaction Bool
existsTextRevision = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (TextRevisionRef -> Transaction Bool)
-> TextRevisionRef
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionRef -> Transaction Bool
Transactions.existsTextRevision

instance HasExistsComment HasqlTransaction where
    existsComment :: CommentRef -> HasqlTransaction Bool
existsComment = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (CommentRef -> Transaction Bool)
-> CommentRef
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommentRef -> Transaction Bool
Transactions.existsComment

-- ** Get Queries

instance HasGetTextElementRevision HasqlTransaction where
    getTextElementRevision :: TextRevisionRef -> HasqlTransaction (Maybe TextElementRevision)
getTextElementRevision = Transaction (Maybe TextElementRevision)
-> HasqlTransaction (Maybe TextElementRevision)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe TextElementRevision)
 -> HasqlTransaction (Maybe TextElementRevision))
-> (TextRevisionRef -> Transaction (Maybe TextElementRevision))
-> TextRevisionRef
-> HasqlTransaction (Maybe TextElementRevision)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionRef -> Transaction (Maybe TextElementRevision)
Transactions.getTextElementRevision

instance HasGetTextElement HasqlTransaction where
    getTextElement :: TextElementID -> HasqlTransaction (Maybe TextElement)
getTextElement = Transaction (Maybe TextElement)
-> HasqlTransaction (Maybe TextElement)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe TextElement)
 -> HasqlTransaction (Maybe TextElement))
-> (TextElementID -> Transaction (Maybe TextElement))
-> TextElementID
-> HasqlTransaction (Maybe TextElement)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementID -> Transaction (Maybe TextElement)
Transactions.getTextElement

instance HasGetTreeRevision HasqlTransaction where
    getTreeRevision :: TreeRevisionRef
-> HasqlTransaction (Maybe (TreeRevision TextElement))
getTreeRevision = Transaction (Maybe (TreeRevision TextElement))
-> HasqlTransaction (Maybe (TreeRevision TextElement))
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe (TreeRevision TextElement))
 -> HasqlTransaction (Maybe (TreeRevision TextElement)))
-> (TreeRevisionRef
    -> Transaction (Maybe (TreeRevision TextElement)))
-> TreeRevisionRef
-> HasqlTransaction (Maybe (TreeRevision TextElement))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeRevisionRef -> Transaction (Maybe (TreeRevision TextElement))
Transactions.getTreeRevision

instance HasExistsTreeRevision HasqlTransaction where
    existsTreeRevision :: TreeRevisionRef -> HasqlTransaction Bool
existsTreeRevision = Transaction Bool -> HasqlTransaction Bool
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Bool -> HasqlTransaction Bool)
-> (TreeRevisionRef -> Transaction Bool)
-> TreeRevisionRef
-> HasqlTransaction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TreeRevisionRef -> Transaction Bool
Transactions.existsTreeRevision

instance HasGetRevisionKey HasqlTransaction where
    getRevisionKey :: RevisionRef -> HasqlTransaction (Maybe RevisionKey)
getRevisionKey = Transaction (Maybe RevisionKey)
-> HasqlTransaction (Maybe RevisionKey)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe RevisionKey)
 -> HasqlTransaction (Maybe RevisionKey))
-> (RevisionRef -> Transaction (Maybe RevisionKey))
-> RevisionRef
-> HasqlTransaction (Maybe RevisionKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RevisionRef -> Transaction (Maybe RevisionKey)
Transactions.getRevisionKey

instance HasGetDocument HasqlTransaction where
    getDocument :: DocumentID -> HasqlTransaction (Maybe Document)
getDocument = Transaction (Maybe Document) -> HasqlTransaction (Maybe Document)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe Document) -> HasqlTransaction (Maybe Document))
-> (DocumentID -> Transaction (Maybe Document))
-> DocumentID
-> HasqlTransaction (Maybe Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Transaction (Maybe Document)
Transactions.getDocument
    getDocuments :: UserID -> HasqlTransaction (Vector Document)
getDocuments = Transaction (Vector Document) -> HasqlTransaction (Vector Document)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Vector Document)
 -> HasqlTransaction (Vector Document))
-> (UserID -> Transaction (Vector Document))
-> UserID
-> HasqlTransaction (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> Transaction (Vector Document)
Transactions.getDocuments
    getDocumentsBy :: Maybe UserID -> Maybe GroupID -> HasqlTransaction (Vector Document)
getDocumentsBy = (Transaction (Vector Document) -> HasqlTransaction (Vector Document)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Vector Document)
 -> HasqlTransaction (Vector Document))
-> (Maybe GroupID -> Transaction (Vector Document))
-> Maybe GroupID
-> HasqlTransaction (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe GroupID -> Transaction (Vector Document))
 -> Maybe GroupID -> HasqlTransaction (Vector Document))
-> (Maybe UserID -> Maybe GroupID -> Transaction (Vector Document))
-> Maybe UserID
-> Maybe GroupID
-> HasqlTransaction (Vector Document)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe UserID -> Maybe GroupID -> Transaction (Vector Document)
Transactions.getDocumentsBy

-- ** Create Queries

instance HasCreateTextRevision HasqlTransaction where
    updateTextRevision :: TextRevisionID
-> Text -> Vector CommentAnchor -> HasqlTransaction TextRevision
updateTextRevision = ((Transaction TextRevision -> HasqlTransaction TextRevision
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction TextRevision -> HasqlTransaction TextRevision)
-> (Vector CommentAnchor -> Transaction TextRevision)
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Vector CommentAnchor -> Transaction TextRevision)
 -> Vector CommentAnchor -> HasqlTransaction TextRevision)
-> (Text -> Vector CommentAnchor -> Transaction TextRevision)
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Vector CommentAnchor -> Transaction TextRevision)
 -> Text -> Vector CommentAnchor -> HasqlTransaction TextRevision)
-> (TextRevisionID
    -> Text -> Vector CommentAnchor -> Transaction TextRevision)
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextRevisionID
-> Text -> Vector CommentAnchor -> Transaction TextRevision
Transactions.updateTextRevision
    createTextRevision :: UserID
-> TextElementRef
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
createTextRevision = (((Transaction TextRevision -> HasqlTransaction TextRevision
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction TextRevision -> HasqlTransaction TextRevision)
-> (Vector CommentAnchor -> Transaction TextRevision)
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Vector CommentAnchor -> Transaction TextRevision)
 -> Vector CommentAnchor -> HasqlTransaction TextRevision)
-> (Text -> Vector CommentAnchor -> Transaction TextRevision)
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Vector CommentAnchor -> Transaction TextRevision)
 -> Text -> Vector CommentAnchor -> HasqlTransaction TextRevision)
-> (TextElementRef
    -> Text -> Vector CommentAnchor -> Transaction TextRevision)
-> TextElementRef
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementRef
  -> Text -> Vector CommentAnchor -> Transaction TextRevision)
 -> TextElementRef
 -> Text
 -> Vector CommentAnchor
 -> HasqlTransaction TextRevision)
-> (UserID
    -> TextElementRef
    -> Text
    -> Vector CommentAnchor
    -> Transaction TextRevision)
-> UserID
-> TextElementRef
-> Text
-> Vector CommentAnchor
-> HasqlTransaction TextRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID
-> TextElementRef
-> Text
-> Vector CommentAnchor
-> Transaction TextRevision
Transactions.createTextRevision
    getLatestTextRevisionID :: TextElementRef -> HasqlTransaction (Maybe TextRevisionID)
getLatestTextRevisionID = Transaction (Maybe TextRevisionID)
-> HasqlTransaction (Maybe TextRevisionID)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe TextRevisionID)
 -> HasqlTransaction (Maybe TextRevisionID))
-> (TextElementRef -> Transaction (Maybe TextRevisionID))
-> TextElementRef
-> HasqlTransaction (Maybe TextRevisionID)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRef -> Transaction (Maybe TextRevisionID)
Transactions.getLatestTextRevisionID
    updateLatestTitle :: TextElementID -> Text -> HasqlTransaction ()
updateLatestTitle = (Transaction () -> HasqlTransaction ()
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction () -> HasqlTransaction ())
-> (Text -> Transaction ()) -> Text -> HasqlTransaction ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Transaction ()) -> Text -> HasqlTransaction ())
-> (TextElementID -> Text -> Transaction ())
-> TextElementID
-> Text
-> HasqlTransaction ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementID -> Text -> Transaction ()
Transactions.updateLatestTitle

instance HasCreateTreeRevision HasqlTransaction where
    createTreeRevision :: UserID
-> DocumentID
-> Node TextElementID
-> HasqlTransaction (TreeRevision TextElementID)
createTreeRevision = ((Transaction (TreeRevision TextElementID)
-> HasqlTransaction (TreeRevision TextElementID)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (TreeRevision TextElementID)
 -> HasqlTransaction (TreeRevision TextElementID))
-> (Node TextElementID -> Transaction (TreeRevision TextElementID))
-> Node TextElementID
-> HasqlTransaction (TreeRevision TextElementID)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Node TextElementID -> Transaction (TreeRevision TextElementID))
 -> Node TextElementID
 -> HasqlTransaction (TreeRevision TextElementID))
-> (DocumentID
    -> Node TextElementID -> Transaction (TreeRevision TextElementID))
-> DocumentID
-> Node TextElementID
-> HasqlTransaction (TreeRevision TextElementID)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((DocumentID
  -> Node TextElementID -> Transaction (TreeRevision TextElementID))
 -> DocumentID
 -> Node TextElementID
 -> HasqlTransaction (TreeRevision TextElementID))
-> (UserID
    -> DocumentID
    -> Node TextElementID
    -> Transaction (TreeRevision TextElementID))
-> UserID
-> DocumentID
-> Node TextElementID
-> HasqlTransaction (TreeRevision TextElementID)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID
-> DocumentID
-> Node TextElementID
-> Transaction (TreeRevision TextElementID)
Transactions.createTreeRevision
    existsTextElementInDocument :: DocumentID -> HasqlTransaction (TextElementID -> Bool)
existsTextElementInDocument =
        Transaction (TextElementID -> Bool)
-> HasqlTransaction (TextElementID -> Bool)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (TextElementID -> Bool)
 -> HasqlTransaction (TextElementID -> Bool))
-> (DocumentID -> Transaction (TextElementID -> Bool))
-> DocumentID
-> HasqlTransaction (TextElementID -> Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Transaction (TextElementID -> Bool)
Transactions.isTextElementInDocument

instance HasCreateComment HasqlTransaction where
    createComment :: UserID -> TextElementID -> Text -> HasqlTransaction Comment
createComment = ((Transaction Comment -> HasqlTransaction Comment
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Comment -> HasqlTransaction Comment)
-> (Text -> Transaction Comment)
-> Text
-> HasqlTransaction Comment
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Transaction Comment) -> Text -> HasqlTransaction Comment)
-> (TextElementID -> Text -> Transaction Comment)
-> TextElementID
-> Text
-> HasqlTransaction Comment
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementID -> Text -> Transaction Comment)
 -> TextElementID -> Text -> HasqlTransaction Comment)
-> (UserID -> TextElementID -> Text -> Transaction Comment)
-> UserID
-> TextElementID
-> Text
-> HasqlTransaction Comment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> TextElementID -> Text -> Transaction Comment
Transactions.createComment
    resolveComment :: CommentID -> HasqlTransaction ()
resolveComment = Transaction () -> HasqlTransaction ()
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction () -> HasqlTransaction ())
-> (CommentID -> Transaction ())
-> CommentID
-> HasqlTransaction ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommentID -> Transaction ()
Transactions.resolveComment
    createReply :: UserID -> CommentID -> Text -> HasqlTransaction Message
createReply = ((Transaction Message -> HasqlTransaction Message
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Message -> HasqlTransaction Message)
-> (Text -> Transaction Message)
-> Text
-> HasqlTransaction Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Transaction Message) -> Text -> HasqlTransaction Message)
-> (CommentID -> Text -> Transaction Message)
-> CommentID
-> Text
-> HasqlTransaction Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((CommentID -> Text -> Transaction Message)
 -> CommentID -> Text -> HasqlTransaction Message)
-> (UserID -> CommentID -> Text -> Transaction Message)
-> UserID
-> CommentID
-> Text
-> HasqlTransaction Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> CommentID -> Text -> Transaction Message
Transactions.createReply

instance HasDraftTextRevision HasqlTransaction where
    createDraftTextRevision :: UserID
-> TextElementRef
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
createDraftTextRevision = ((((Transaction DraftRevision -> HasqlTransaction DraftRevision
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction DraftRevision -> HasqlTransaction DraftRevision)
-> (Vector CommentAnchor -> Transaction DraftRevision)
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Vector CommentAnchor -> Transaction DraftRevision)
 -> Vector CommentAnchor -> HasqlTransaction DraftRevision)
-> (Text -> Vector CommentAnchor -> Transaction DraftRevision)
-> Text
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Vector CommentAnchor -> Transaction DraftRevision)
 -> Text -> Vector CommentAnchor -> HasqlTransaction DraftRevision)
-> (TextRevisionID
    -> Text -> Vector CommentAnchor -> Transaction DraftRevision)
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextRevisionID
  -> Text -> Vector CommentAnchor -> Transaction DraftRevision)
 -> TextRevisionID
 -> Text
 -> Vector CommentAnchor
 -> HasqlTransaction DraftRevision)
-> (TextElementRef
    -> TextRevisionID
    -> Text
    -> Vector CommentAnchor
    -> Transaction DraftRevision)
-> TextElementRef
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementRef
  -> TextRevisionID
  -> Text
  -> Vector CommentAnchor
  -> Transaction DraftRevision)
 -> TextElementRef
 -> TextRevisionID
 -> Text
 -> Vector CommentAnchor
 -> HasqlTransaction DraftRevision)
-> (UserID
    -> TextElementRef
    -> TextRevisionID
    -> Text
    -> Vector CommentAnchor
    -> Transaction DraftRevision)
-> UserID
-> TextElementRef
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> HasqlTransaction DraftRevision
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID
-> TextElementRef
-> TextRevisionID
-> Text
-> Vector CommentAnchor
-> Transaction DraftRevision
Transactions.createDraftTextRevision
    getDraftTextRevision :: UserID -> TextElementRef -> HasqlTransaction (Maybe DraftRevision)
getDraftTextRevision = (Transaction (Maybe DraftRevision)
-> HasqlTransaction (Maybe DraftRevision)
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction (Maybe DraftRevision)
 -> HasqlTransaction (Maybe DraftRevision))
-> (TextElementRef -> Transaction (Maybe DraftRevision))
-> TextElementRef
-> HasqlTransaction (Maybe DraftRevision)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementRef -> Transaction (Maybe DraftRevision))
 -> TextElementRef -> HasqlTransaction (Maybe DraftRevision))
-> (UserID -> TextElementRef -> Transaction (Maybe DraftRevision))
-> UserID
-> TextElementRef
-> HasqlTransaction (Maybe DraftRevision)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> TextElementRef -> Transaction (Maybe DraftRevision)
Transactions.getDraftTextRevision
    deleteDraftTextRevision :: UserID -> TextElementRef -> HasqlTransaction ()
deleteDraftTextRevision = (Transaction () -> HasqlTransaction ()
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction () -> HasqlTransaction ())
-> (TextElementRef -> Transaction ())
-> TextElementRef
-> HasqlTransaction ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((TextElementRef -> Transaction ())
 -> TextElementRef -> HasqlTransaction ())
-> (UserID -> TextElementRef -> Transaction ())
-> UserID
-> TextElementRef
-> HasqlTransaction ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserID -> TextElementRef -> Transaction ()
Transactions.deleteDraftTextRevision

instance HasLogMessage HasqlTransaction where
    logMessage :: forall v.
ToJSON v =>
Severity
-> Maybe UserID -> Scope -> v -> HasqlTransaction LogMessage
logMessage = (((Transaction LogMessage -> HasqlTransaction LogMessage
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction LogMessage -> HasqlTransaction LogMessage)
-> (v -> Transaction LogMessage)
-> v
-> HasqlTransaction LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((v -> Transaction LogMessage) -> v -> HasqlTransaction LogMessage)
-> (Scope -> v -> Transaction LogMessage)
-> Scope
-> v
-> HasqlTransaction LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Scope -> v -> Transaction LogMessage)
 -> Scope -> v -> HasqlTransaction LogMessage)
-> (Maybe UserID -> Scope -> v -> Transaction LogMessage)
-> Maybe UserID
-> Scope
-> v
-> HasqlTransaction LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Maybe UserID -> Scope -> v -> Transaction LogMessage)
 -> Maybe UserID -> Scope -> v -> HasqlTransaction LogMessage)
-> (Severity
    -> Maybe UserID -> Scope -> v -> Transaction LogMessage)
-> Severity
-> Maybe UserID
-> Scope
-> v
-> HasqlTransaction LogMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Severity -> Maybe UserID -> Scope -> v -> Transaction LogMessage
forall v.
ToJSON v =>
Severity -> Maybe UserID -> Scope -> v -> Transaction LogMessage
Transactions.logMessage

instance HasCreateDocument HasqlTransaction where
    createDocument :: Text -> GroupID -> UserID -> HasqlTransaction Document
createDocument = ((Transaction Document -> HasqlTransaction Document
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction Document -> HasqlTransaction Document)
-> (UserID -> Transaction Document)
-> UserID
-> HasqlTransaction Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((UserID -> Transaction Document)
 -> UserID -> HasqlTransaction Document)
-> (GroupID -> UserID -> Transaction Document)
-> GroupID
-> UserID
-> HasqlTransaction Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((GroupID -> UserID -> Transaction Document)
 -> GroupID -> UserID -> HasqlTransaction Document)
-> (Text -> GroupID -> UserID -> Transaction Document)
-> Text
-> GroupID
-> UserID
-> HasqlTransaction Document
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> GroupID -> UserID -> Transaction Document
Transactions.createDocument

instance HasCreateTextElement HasqlTransaction where
    createTextElement :: DocumentID -> Text -> Text -> HasqlTransaction TextElement
createTextElement = ((Transaction TextElement -> HasqlTransaction TextElement
forall a. Transaction a -> HasqlTransaction a
HasqlTransaction (Transaction TextElement -> HasqlTransaction TextElement)
-> (Text -> Transaction TextElement)
-> Text
-> HasqlTransaction TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Transaction TextElement)
 -> Text -> HasqlTransaction TextElement)
-> (Text -> Text -> Transaction TextElement)
-> Text
-> Text
-> HasqlTransaction TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((Text -> Text -> Transaction TextElement)
 -> Text -> Text -> HasqlTransaction TextElement)
-> (DocumentID -> Text -> Text -> Transaction TextElement)
-> DocumentID
-> Text
-> Text
-> HasqlTransaction TextElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Text -> Text -> Transaction TextElement
Transactions.createTextElement