2019-04-15 20:23:25 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module Model.User where
|
|
|
|
|
2019-07-21 13:02:59 +00:00
|
|
|
import Data.Text as T hiding (head, foldl)
|
2019-04-15 20:23:25 +00:00
|
|
|
import Data.Time.Calendar
|
|
|
|
import Data.Time.Clock
|
2019-04-21 15:27:15 +00:00
|
|
|
|
2019-09-14 21:03:04 +00:00
|
|
|
import Data.Profunctor.Product (p6)
|
2019-04-15 20:23:25 +00:00
|
|
|
|
2019-04-17 14:14:44 +00:00
|
|
|
import Data.Int (Int64)
|
|
|
|
|
2019-04-15 20:23:25 +00:00
|
|
|
import qualified Database.PostgreSQL.Simple as PGS
|
|
|
|
|
|
|
|
import Control.Arrow ((<<<))
|
|
|
|
|
2019-05-09 14:53:19 +00:00
|
|
|
import Control.Monad.IO.Class (liftIO)
|
|
|
|
|
2019-04-15 20:23:25 +00:00
|
|
|
import Opaleye as O
|
|
|
|
import qualified Opaleye.Constant as C
|
|
|
|
|
|
|
|
-- internal imports
|
|
|
|
|
2019-04-17 14:14:44 +00:00
|
|
|
import Types.User
|
2019-04-17 05:51:15 +00:00
|
|
|
import Types.Refine
|
2019-05-09 14:53:19 +00:00
|
|
|
import Types.Reader
|
2019-04-17 05:51:15 +00:00
|
|
|
|
2019-04-16 11:03:07 +00:00
|
|
|
initUser :: PGS.Query
|
2019-07-21 14:05:05 +00:00
|
|
|
initUser = mconcat
|
2019-08-10 09:43:33 +00:00
|
|
|
[ "CREATE TABLE IF NOT EXISTS \"user\" ("
|
|
|
|
, "user_id SERIAL PRIMARY KEY,"
|
|
|
|
, "user_ident TEXT NOT NULL,"
|
|
|
|
, "user_balance INTEGER NOT NULL,"
|
|
|
|
, "user_timestamp DATE NOT NULL,"
|
|
|
|
, "user_email TEXT,"
|
2019-09-14 21:03:04 +00:00
|
|
|
, "user_avatar INTEGER REFERENCES \"avatar\"(\"avatar_id\") ON DELETE CASCADE"
|
2019-07-21 13:02:59 +00:00
|
|
|
, ")"
|
|
|
|
]
|
2019-04-16 11:03:07 +00:00
|
|
|
|
2019-04-15 20:23:25 +00:00
|
|
|
userTable :: Table
|
|
|
|
( Maybe (Field SqlInt4)
|
|
|
|
, Field SqlText
|
|
|
|
, Field SqlInt4
|
|
|
|
, Field SqlDate
|
|
|
|
, FieldNullable SqlText
|
|
|
|
, FieldNullable SqlInt4
|
|
|
|
)
|
|
|
|
( Field SqlInt4
|
|
|
|
, Field SqlText
|
|
|
|
, Field SqlInt4
|
|
|
|
, Field SqlDate
|
|
|
|
, FieldNullable SqlText
|
|
|
|
, FieldNullable SqlInt4
|
|
|
|
)
|
|
|
|
userTable = table "user" (
|
2019-09-14 21:03:04 +00:00
|
|
|
p6
|
2019-04-21 15:27:15 +00:00
|
|
|
( tableField "user_id"
|
|
|
|
, tableField "user_ident"
|
|
|
|
, tableField "user_balance"
|
|
|
|
, tableField "user_timestamp"
|
|
|
|
, tableField "user_email"
|
|
|
|
, tableField "user_avatar"
|
2019-04-15 20:23:25 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
userSelect
|
2019-09-11 02:04:06 +00:00
|
|
|
:: UserRefine
|
2019-09-06 19:44:47 +00:00
|
|
|
-> PGS.Connection
|
2019-09-09 10:54:56 +00:00
|
|
|
-> MateHandler [UserSummary]
|
2019-09-06 19:44:47 +00:00
|
|
|
userSelect ref conn = do
|
2019-10-14 21:34:45 +00:00
|
|
|
today <- utctDay <$> liftIO getCurrentTime
|
2019-05-09 14:53:19 +00:00
|
|
|
users <- liftIO $ runSelect conn (case ref of
|
2019-09-11 02:04:06 +00:00
|
|
|
AllUsers -> selectTable userTable
|
2019-09-14 21:03:04 +00:00
|
|
|
ActiveUsers -> keepWhen (\(_, _, _, ts, _, _) ->
|
2019-04-15 20:23:25 +00:00
|
|
|
ts .>= C.constant (addDays (-30) today)
|
|
|
|
) <<< queryTable userTable
|
2019-09-14 21:03:04 +00:00
|
|
|
OldUsers -> keepWhen (\(_, _, _, ts, _, _) ->
|
2019-04-15 20:23:25 +00:00
|
|
|
ts .<= C.constant (addDays (-30) today)
|
|
|
|
) <<< queryTable userTable
|
2019-05-09 14:53:19 +00:00
|
|
|
) :: MateHandler
|
2019-04-17 08:45:48 +00:00
|
|
|
[ ( Int
|
|
|
|
, Text
|
|
|
|
, Int
|
|
|
|
, Day
|
|
|
|
, Maybe Text
|
|
|
|
, Maybe Int
|
|
|
|
)
|
|
|
|
]
|
2019-04-17 05:51:15 +00:00
|
|
|
mapM
|
2019-10-14 21:34:45 +00:00
|
|
|
(\(i1, i2, _, _, _, i6) -> return $
|
2019-09-09 10:54:56 +00:00
|
|
|
UserSummary i1 i2 i6
|
2019-04-15 20:23:25 +00:00
|
|
|
)
|
2019-04-17 05:51:15 +00:00
|
|
|
users
|
2019-04-15 20:23:25 +00:00
|
|
|
|
2019-05-16 16:37:04 +00:00
|
|
|
userDetailsSelect
|
2019-09-06 19:44:47 +00:00
|
|
|
:: Int
|
|
|
|
-> PGS.Connection
|
2019-05-16 16:37:04 +00:00
|
|
|
-> MateHandler UserDetails
|
2019-09-07 00:48:16 +00:00
|
|
|
userDetailsSelect uid conn = do
|
2019-05-16 16:37:04 +00:00
|
|
|
users <- liftIO $ runSelect conn (
|
2019-09-14 21:03:04 +00:00
|
|
|
keepWhen (\(uuid, _, _, _, _, _) ->
|
2019-09-07 00:48:16 +00:00
|
|
|
uuid .== C.constant uid
|
2019-05-16 16:37:04 +00:00
|
|
|
) <<< queryTable userTable
|
|
|
|
) :: MateHandler
|
|
|
|
[ ( Int
|
|
|
|
, Text
|
|
|
|
, Int
|
|
|
|
, Day
|
|
|
|
, Maybe Text
|
|
|
|
, Maybe Int
|
|
|
|
)
|
|
|
|
]
|
|
|
|
head <$> mapM
|
2019-09-14 21:03:04 +00:00
|
|
|
(\(i1, i2, i3, _, i5, i6) -> return $
|
|
|
|
UserDetails i1 i2 i3 i5 i6
|
2019-05-16 16:37:04 +00:00
|
|
|
)
|
|
|
|
users
|
|
|
|
|
2019-07-20 16:36:47 +00:00
|
|
|
|
|
|
|
userBalanceSelect
|
|
|
|
:: PGS.Connection
|
|
|
|
-> Int
|
|
|
|
-> MateHandler Int
|
2019-09-07 00:48:16 +00:00
|
|
|
userBalanceSelect conn uid = do
|
2019-07-20 16:36:47 +00:00
|
|
|
users <- liftIO $ runSelect conn (
|
2019-09-14 21:03:04 +00:00
|
|
|
keepWhen (\(uuid, _, _, _, _, _) ->
|
2019-09-07 00:48:16 +00:00
|
|
|
uuid .== C.constant uid
|
2019-07-20 16:36:47 +00:00
|
|
|
) <<< queryTable userTable
|
|
|
|
) :: MateHandler
|
|
|
|
[ ( Int
|
|
|
|
, Text
|
|
|
|
, Int
|
|
|
|
, Day
|
|
|
|
, Maybe Text
|
|
|
|
, Maybe Int
|
|
|
|
)
|
|
|
|
]
|
|
|
|
head <$> mapM
|
2019-10-14 20:50:42 +00:00
|
|
|
(\(_, _, i3, _, _, _) -> return i3)
|
2019-07-20 16:36:47 +00:00
|
|
|
users
|
|
|
|
|
|
|
|
|
2019-07-28 09:55:22 +00:00
|
|
|
insertUser
|
2019-09-15 14:11:56 +00:00
|
|
|
:: T.Text
|
|
|
|
-> Maybe T.Text
|
2019-07-28 09:55:22 +00:00
|
|
|
-> Day
|
|
|
|
-> PGS.Connection
|
|
|
|
-> MateHandler Int
|
2019-09-15 14:11:56 +00:00
|
|
|
insertUser ident email now conn = fmap head $ liftIO $ runInsert_ conn $ Insert
|
2019-04-15 20:23:25 +00:00
|
|
|
{ iTable = userTable
|
|
|
|
, iRows =
|
|
|
|
[
|
|
|
|
( C.constant (Nothing :: Maybe Int)
|
2019-09-15 14:11:56 +00:00
|
|
|
, C.constant ident
|
2019-04-15 20:23:25 +00:00
|
|
|
, C.constant (0 :: Int)
|
|
|
|
, C.constant now
|
2019-09-15 14:11:56 +00:00
|
|
|
, C.constant email
|
2019-04-15 20:23:25 +00:00
|
|
|
, C.constant (Nothing :: Maybe Int)
|
|
|
|
)
|
|
|
|
]
|
2019-09-14 21:03:04 +00:00
|
|
|
, iReturning = rReturning (\(uid, _, _, _, _, _) -> uid)
|
2019-04-15 20:23:25 +00:00
|
|
|
, iOnConflict = Nothing
|
2019-04-16 04:23:08 +00:00
|
|
|
}
|
|
|
|
|
2019-07-28 09:55:22 +00:00
|
|
|
updateUserDetails
|
|
|
|
:: Int
|
|
|
|
-> UserDetailsSubmit
|
|
|
|
-> Day
|
|
|
|
-> PGS.Connection
|
|
|
|
-> MateHandler Int64
|
|
|
|
updateUserDetails uid uds now conn = liftIO $ runUpdate_ conn $ Update
|
2019-07-20 16:36:47 +00:00
|
|
|
{ uTable = userTable
|
2019-09-14 21:03:04 +00:00
|
|
|
, uUpdateWith = updateEasy (\(id_, _, i3, _, _, _) ->
|
2019-04-16 04:23:08 +00:00
|
|
|
( id_
|
2019-05-16 16:37:04 +00:00
|
|
|
, C.constant (userDetailsSubmitIdent uds)
|
2019-05-17 16:37:35 +00:00
|
|
|
, i3
|
2019-05-09 14:53:19 +00:00
|
|
|
, C.constant now
|
2019-05-16 16:37:04 +00:00
|
|
|
, C.constant (userDetailsSubmitEmail uds)
|
|
|
|
, C.constant (userDetailsSubmitAvatar uds)
|
2019-04-16 04:23:08 +00:00
|
|
|
)
|
|
|
|
)
|
2019-10-14 20:50:42 +00:00
|
|
|
, uWhere = \(i1, _, _, _, _, _) -> i1 .== C.constant uid
|
2019-07-20 16:36:47 +00:00
|
|
|
, uReturning = rCount
|
|
|
|
}
|
|
|
|
|
|
|
|
addToUserBalance
|
|
|
|
:: Int
|
|
|
|
-> Int
|
2019-07-28 09:55:22 +00:00
|
|
|
-> PGS.Connection
|
|
|
|
-> MateHandler Int64
|
|
|
|
addToUserBalance uid amount conn = liftIO $ runUpdate_ conn $ Update
|
2019-07-20 16:36:47 +00:00
|
|
|
{ uTable = userTable
|
2019-09-14 21:03:04 +00:00
|
|
|
, uUpdateWith = updateEasy (\(id_, i2, i3, i4, i5, i6) ->
|
2019-07-20 16:36:47 +00:00
|
|
|
( id_
|
|
|
|
, i2
|
|
|
|
, i3 + C.constant amount
|
|
|
|
, i4
|
|
|
|
, i5
|
|
|
|
, i6
|
|
|
|
)
|
|
|
|
)
|
2019-10-14 20:50:42 +00:00
|
|
|
, uWhere = \(i1, _, _, _, _, _) -> i1 .== C.constant uid
|
2019-07-20 16:36:47 +00:00
|
|
|
, uReturning = rCount
|
2019-04-16 04:23:08 +00:00
|
|
|
}
|