{-# LANGUAGE TypeApplications #-}
module BtcLsp.Storage.Model.User
( createVerifySql,
)
where
import BtcLsp.Data.Orphan ()
import BtcLsp.Import hiding (Storage (..))
import qualified BtcLsp.Import.Psql as Psql
import qualified BtcLsp.Storage.Util as Util
createVerifySql ::
( MonadIO m
) =>
NodePubKey ->
Nonce ->
ReaderT Psql.SqlBackend m (Either Failure (Entity User))
createVerifySql :: forall (m :: * -> *).
MonadIO m =>
NodePubKey
-> Nonce -> ReaderT SqlBackend m (Either Failure (Entity User))
createVerifySql NodePubKey
pub Nonce
nonce = do
UTCTime
ct <- ReaderT SqlBackend m UTCTime
forall (m :: * -> *). MonadIO m => m UTCTime
getCurrentTime
let zeroRow :: User
zeroRow =
User :: NodePubKey -> Nonce -> UTCTime -> UTCTime -> User
User
{ userNodePubKey :: NodePubKey
userNodePubKey = NodePubKey
pub,
userLatestNonce :: Nonce
userLatestNonce = forall source target.
(From source target, 'False ~ (source == target)) =>
source -> target
from @Word64 Word64
0,
userInsertedAt :: UTCTime
userInsertedAt = UTCTime
ct,
userUpdatedAt :: UTCTime
userUpdatedAt = UTCTime
ct
}
Key User
rowId <-
Entity User -> Key User
forall record. Entity record -> Key record
entityKey
(Entity User -> Key User)
-> ReaderT SqlBackend m (Entity User)
-> ReaderT SqlBackend m (Key User)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unique User
-> User
-> [SqlExpr (Entity User) -> SqlExpr Update]
-> ReaderT SqlBackend m (Entity User)
forall (m :: * -> *) record.
(MonadIO m, PersistEntity record,
IsPersistBackend (PersistEntityBackend record)) =>
Unique record
-> record
-> [SqlExpr (Entity record) -> SqlExpr Update]
-> ReaderT SqlBackend m (Entity record)
Psql.upsertBy
(NodePubKey -> Unique User
UniqueUser NodePubKey
pub)
User
zeroRow
[ EntityField User UTCTime
forall typ. (typ ~ UTCTime) => EntityField User typ
UserUpdatedAt EntityField User UTCTime
-> SqlExpr (Value UTCTime)
-> SqlExpr (Entity User)
-> SqlExpr Update
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr Update
Psql.=. UTCTime -> SqlExpr (Value UTCTime)
forall typ. PersistField typ => typ -> SqlExpr (Value typ)
Psql.val UTCTime
ct
]
User
existingRow <- Key User -> SqlPersistT m User
forall (m :: * -> *) a.
(MonadIO m, HasTable a, ToBackendKey SqlBackend a) =>
Key a -> SqlPersistT m a
Util.lockByRow Key User
rowId
if (User
existingRow User -> User -> Bool
forall a. Eq a => a -> a -> Bool
== User
zeroRow)
Bool -> Bool -> Bool
|| (User -> Nonce
userLatestNonce User
existingRow Nonce -> Nonce -> Bool
forall a. Ord a => a -> a -> Bool
< Nonce
nonce)
then
Entity User -> Either Failure (Entity User)
forall a b. b -> Either a b
Right
(Entity User -> Either Failure (Entity User))
-> ReaderT SqlBackend m (Entity User)
-> ReaderT SqlBackend m (Either Failure (Entity User))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unique User
-> User
-> [SqlExpr (Entity User) -> SqlExpr Update]
-> ReaderT SqlBackend m (Entity User)
forall (m :: * -> *) record.
(MonadIO m, PersistEntity record,
IsPersistBackend (PersistEntityBackend record)) =>
Unique record
-> record
-> [SqlExpr (Entity record) -> SqlExpr Update]
-> ReaderT SqlBackend m (Entity record)
Psql.upsertBy
(NodePubKey -> Unique User
UniqueUser NodePubKey
pub)
User
zeroRow
{ userLatestNonce :: Nonce
userLatestNonce = Nonce
nonce
}
[ EntityField User Nonce
forall typ. (typ ~ Nonce) => EntityField User typ
UserLatestNonce EntityField User Nonce
-> SqlExpr (Value Nonce) -> SqlExpr (Entity User) -> SqlExpr Update
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr Update
Psql.=. Nonce -> SqlExpr (Value Nonce)
forall typ. PersistField typ => typ -> SqlExpr (Value typ)
Psql.val Nonce
nonce,
EntityField User UTCTime
forall typ. (typ ~ UTCTime) => EntityField User typ
UserUpdatedAt EntityField User UTCTime
-> SqlExpr (Value UTCTime)
-> SqlExpr (Entity User)
-> SqlExpr Update
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr Update
Psql.=. UTCTime -> SqlExpr (Value UTCTime)
forall typ. PersistField typ => typ -> SqlExpr (Value typ)
Psql.val UTCTime
ct
]
else
Either Failure (Entity User)
-> ReaderT SqlBackend m (Either Failure (Entity User))
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(Either Failure (Entity User)
-> ReaderT SqlBackend m (Either Failure (Entity User)))
-> (Failure -> Either Failure (Entity User))
-> Failure
-> ReaderT SqlBackend m (Either Failure (Entity User))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Failure -> Either Failure (Entity User)
forall a b. a -> Either a b
Left
(Failure -> ReaderT SqlBackend m (Either Failure (Entity User)))
-> Failure -> ReaderT SqlBackend m (Either Failure (Entity User))
forall a b. (a -> b) -> a -> b
$ FailureInput -> Failure
FailureInp FailureInput
FailureNonce