35 \ JOIN rating_players as o ON (p.gameid = o.gameid AND p.userid <> o.userid AND (p.place = 0 OR (p.place <> o.place))) \ |
35 \ JOIN rating_players as o ON (p.gameid = o.gameid AND p.userid <> o.userid AND (p.place = 0 OR (p.place <> o.place))) \ |
36 \ LEFT OUTER JOIN rating_values as vp ON (vp.epoch = e.epoch AND vp.userid = p.userid) \ |
36 \ LEFT OUTER JOIN rating_values as vp ON (vp.epoch = e.epoch AND vp.userid = p.userid) \ |
37 \ LEFT OUTER JOIN rating_values as vo ON (vo.epoch = e.epoch AND vo.userid = o.userid) \ |
37 \ LEFT OUTER JOIN rating_values as vo ON (vo.epoch = e.epoch AND vo.userid = o.userid) \ |
38 \ GROUP BY p.userid, p.gameid, p.place \ |
38 \ GROUP BY p.userid, p.gameid, p.place \ |
39 \ ORDER BY p.userid" |
39 \ ORDER BY p.userid" |
40 insertNewRatings = "INSERT INTO rating_values (userid, epoch, rating, rd, volatility) VALUES (?, ?, ?, ?, ?)" |
40 insertNewRatings = "INSERT INTO rating_values (userid, epoch, rating, rd, volatility, games) VALUES (?, ?, ?, ?, ?, ?)" |
41 insertNewEpoch = "INSERT INTO rating_epochs (epoch, todatetime) VALUES (?, ?)" |
41 insertNewEpoch = "INSERT INTO rating_epochs (epoch, todatetime) VALUES (?, ?)" |
42 |
42 |
43 mergeRatingData :: Map.Map Int (RatingData, [GameData]) -> [(Int, (RatingData, [GameData]))] -> Map.Map Int (RatingData, [GameData]) |
43 mergeRatingData :: Map.Map Int (RatingData, [GameData]) -> [(Int, (RatingData, [GameData]))] -> Map.Map Int (RatingData, [GameData]) |
44 mergeRatingData m s = foldr (unc0rry (Map.insertWith mf)) m s |
44 mergeRatingData m s = foldr (uncurry (Map.insertWith mf)) m s |
45 where |
45 where |
46 mf (rd, gds) (_, gds2) = (rd, gds ++ gds2) |
46 mf (rd, gds) (_, gds2) = (rd, gds ++ gds2) |
47 unc0rry f (a, b) c = f a b c |
|
48 |
47 |
49 calculateRatings dbConn = do |
48 calculateRatings dbConn = do |
50 [(epochNum :: Int, fromDate :: UTCTime, toDate :: UTCTime)] <- query_ dbConn queryEpochDates |
49 [(epochNum :: Int, fromDate :: UTCTime, toDate :: UTCTime)] <- query_ dbConn queryEpochDates |
51 initRatingData <- (Map.fromList . map fromDBrating) `fmap` query_ dbConn queryPreviousRatings |
50 initRatingData <- (Map.fromList . map fromDBrating) `fmap` query_ dbConn queryPreviousRatings |
52 gameData <- map fromGameResult `fmap` query_ dbConn queryGameResults |
51 gameData <- map fromGameResult `fmap` query_ dbConn queryGameResults |
53 let mData = map getNewRating . Map.toList $ mergeRatingData initRatingData gameData |
52 let mData = map getNewRating . Map.toList $ mergeRatingData initRatingData gameData |
54 executeMany dbConn insertNewRatings $ map (toInsert epochNum) mData |
53 executeMany dbConn insertNewRatings $ map (toInsert epochNum) mData |
55 execute dbConn insertNewEpoch (epochNum + 1, toDate) |
54 execute dbConn insertNewEpoch (epochNum + 1, toDate) |
56 return () |
55 return () |
57 where |
56 where |
58 toInsert e (i, RatingData r rd v) = (i, e + 1, r, rd, v) |
57 toInsert e (i, (g, RatingData r rd v)) = (i, e + 1, r, rd, v, g) |
59 getNewRating (a, d) = (a, uncurry calcNewRating d) |
58 getNewRating (a, d) = (a, uncurry calcNewRating d) |
60 convPlace :: Int -> Double |
59 convPlace :: Int -> Double |
61 convPlace 0 = 0.5 |
60 convPlace 0 = 0.5 |
62 convPlace 1 = 1.0 |
61 convPlace 1 = 1.0 |
63 convPlace 2 = 0.0 |
62 convPlace 2 = 0.0 |