@@ -596,9 +596,10 @@ usersPost conn fuid uinfo = do
596596 { Servant. errBody = BL. fromStrict $ T. encodeUtf8 e }
597597 Right user -> pure user
598598 liftIO (dbCreateUser iface userId user) >>= \ case
599- Left () -> Servant. throwError $ Servant. err409
600- { Servant. errBody = Aeson. encode (Item userId user) }
601- Right () -> pure $ Item userId user
599+ Left () ->
600+ Servant. throwError $ Servant. err409
601+ { Servant. errBody = Aeson. encode (Item userId user) }
602+ Right user' -> pure $ Item userId user'
602603
603604userInfoToUser :: UserInfo -> Either T. Text User
604605userInfoToUser uinfo = User <$>
@@ -618,7 +619,7 @@ emailToUsername t = case T.breakOn "@" t of
618619 c | isAscii c && isAlphaNum c -> T. singleton c
619620 | otherwise -> " "
620621
621- usersPostSession :: UserId -> User -> HS. Session (Either () () )
622+ usersPostSession :: UserId -> User -> HS. Session (Either () User )
622623usersPostSession uid u = do
623624 HS. sql " BEGIN"
624625 liftIO $ putStrLn " Creating user in DB"
@@ -628,19 +629,27 @@ usersPostSession uid u = do
628629 case userUsername u of
629630 Just uname -> do
630631 liftIO $ putStrLn " Creating username"
632+ let success unam = do
633+ liftIO $ putStrLn " User created successfully"
634+ HS. sql " COMMIT"
635+ pure $ Right $ u { userUsername = Just unam }
631636 HS. statement (uname, uid) usersPostStatement' >>= \ case
632- 1 -> do
633- liftIO $ putStrLn " User created successfully"
634- HS. sql " COMMIT"
635- pure $ Right ()
637+ 1 -> success uname
636638 _ -> do
637639 liftIO $ putStrLn " Couldn't create username"
638- HS. sql " ROLLBACK"
639- pure $ Left ()
640+ rand <- liftIO $ randomText 4 [' 0' .. ' 9' ]
641+ let uname' = Username $ unUsername uname <> rand
642+ liftIO $ putStrLn $ " Retrying with username " <> (T. unpack $ unUsername uname')
643+ HS. statement (uname', uid) usersPostStatement' >>= \ case
644+ 1 -> success uname'
645+ _ -> do
646+ liftIO $ putStrLn " Couldn't create username again"
647+ HS. sql " ROLLBACK"
648+ pure $ Left ()
640649 Nothing -> do
641650 liftIO $ putStrLn " No username"
642651 HS. sql " COMMIT"
643- pure $ Right ()
652+ pure $ Right u
644653 _ -> do
645654 liftIO $ putStrLn " Couldn't create exactly one user"
646655 HS. sql " ROLLBACK"
@@ -662,12 +671,11 @@ usersPostStatement = Statement sql encoder decoder True
662671 contramap (unFirebaseId . userFirebaseId . view _2) (HE. param HE. text)
663672 decoder = HD. rowsAffected
664673
665- -- TODO: deal with conflict error
666674usersPostStatement' :: Statement (Username , UserId ) Int64
667675usersPostStatement' = Statement sql encoder decoder True
668676 where
669677 sql = BS8. unwords
670- [ " UPDATE account SET username = $1 WHERE id = $2" ]
678+ [ " UPDATE account SET username = $1 WHERE id = $2 AND NOT EXISTS (SELECT 1 FROM account WHERE username = $1) " ]
671679 encoder =
672680 contramap
673681 (unUsername . view _1)
@@ -835,7 +843,7 @@ instance Aeson.FromJSON PresResponse where
835843data DbInterface = DbInterface
836844 { dbGetAllUsers :: IO [Item UserId User ]
837845 , dbGetUserById :: UserId -> IO (Maybe (Item UserId User ))
838- , dbCreateUser :: UserId -> User -> IO (Either () () )
846+ , dbCreateUser :: UserId -> User -> IO (Either () User )
839847 , dbUpdateUser :: UserId -> User -> IO UserUpdateResult
840848 , dbDeleteUser :: UserId -> IO (Either () () )
841849
0 commit comments