def rinsert(): query_do( c, '''INSERT INTO low_xl_rune_finds (player, start_time, rune_time, rune, xl) VALUES (%s, %s, %s, %s, %s)''', g['name'], g['start'], g['time'], rune, xl) dirty_page('overview')
def update_gkills(c, g): if scload.is_ghost_kill(g): dirty_page('gkills', 1) ghost = scload.extract_ghost_name(g['killer']) if ghost != g['name']: query_do(c, '''INSERT INTO ghost_victims (ghost, victim) VALUES (%s, %s)''', ghost, g['name'])
def insert(): query_do( c, '''INSERT INTO ziggurats (player, deepest, place, zig_time, start_time) VALUES (%s, %s, %s, %s, %s)''', player, depth, place, g['time'], g['start']) player_ziggurat_deepest.flush_key(player) dirty_page('overview', 1)
def update_player_stats(c, g): global player_stats_cache, all_recent_games_cache, streaks_cache global player_recent_cache, player_best_cache, wins_cache winc = game_is_win(g) and 1 or 0 if player_recent_cache.game_key_exists(c, g): error("Ignoring duplicate game '%s' from logfile '%s'" % (g.get('game_key'), g.get('source_file'))) return False player_recent_cache.update(g) if winc: dirty_page('best-players-total-score') dirty_page('all-players') dirty_player(g['name']) else: if g['sc'] > 0: factor = int(g['sc'] / 40000) + 1 dirty_page('best-players-total-score', factor) dirty_page('all-players', factor) dirty_player(g['name'], factor) else: dirty_player(g['name'], 1) player_stats_cache.update(g) streaks_cache.init_from_db(c) # TODO: could do this somewhere else streaks_cache.update(g) player_best_cache.update(g) all_recent_games_cache.update(g) wins_cache.update(g) update_player_first_game(c, g) return True
def update_all_recent_games(c, g): if is_junk_game(g): return dirty_page('recent', 1) dirty_page('per-day', 1) insert_game(c, g, 'all_recent_games') if all_recent_game_count.has_key(): all_recent_game_count.set_key(all_recent_game_count(c) + 1) if all_recent_game_count(c) > MAX_ALL_RECENT_GAMES + 50: extra = all_recent_game_count(c) - MAX_ALL_RECENT_GAMES ids = query_first_col( c, '''SELECT id FROM all_recent_games ORDER BY id LIMIT %s''', extra) scload.delete_table_rows_by_id(c, 'all_recent_games', ids) all_recent_game_count.flush_key()
def update_killer_stats(c, g): ckiller = g['ckiller'] if ckiller != 'winning': dirty_page('killers', 1) query_do( c, '''INSERT INTO top_killers (ckiller, kills, most_recent_victim) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE kills = kills + 1, most_recent_victim = %s''', ckiller, 1, g['name'], g['name']) if ckiller_record_exists(c, ckiller): query_do(c, '''DELETE FROM killer_recent_kills WHERE ckiller = %s''', ckiller) else: ckiller_record_exists.set_key(True, ckiller) insert_game(c, g, 'killer_recent_kills')
def update_player_stats(c, g): winc = game_is_win(g) and 1 or 0 if winc: dirty_page('best-players-total-score') dirty_page('all-players') dirty_player(g['name']) else: if g['sc'] > 0: factor = int(g['sc'] / 40000) + 1 dirty_page('best-players-total-score', factor) dirty_page('all-players', factor) dirty_player(g['name'], factor) else: dirty_player(g['name'], 1) query_do( c, '''INSERT INTO players (name, games_played, games_won, total_score, best_score, best_xl, first_game_start, last_game_end, max_runes) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE games_played = games_played + 1, games_won = games_won + %s, total_score = total_score + %s, best_score = CASE WHEN best_score < %s THEN %s ELSE best_score END, best_xl = CASE WHEN best_xl < %s THEN %s ELSE best_xl END, max_runes = CASE WHEN max_runes < %s THEN %s ELSE max_runes END, last_game_end = %s, current_combo = NULL''', g['name'], 1, winc, g['sc'], g['sc'], g['xl'], g['start_time'], g['end_time'], g['urune'], winc, g['sc'], g['sc'], g['sc'], g['xl'], g['xl'], g['urune'], g['urune'], g['end_time']) # Must be first! update_player_streak(c, g) update_player_best_games(c, g) update_player_char_stats(c, g) update_player_recent_games(c, g) update_all_recent_games(c, g) update_player_first_game(c, g) update_player_last_game(c, g) update_wins_table(c, g)
def add_ziggurat_milestone(c, g): if not g['type'].startswith('zig'): return place = g['place'] mtype = g['type'] place_matches = scload.R_PLACE_DEPTH.findall(place) or ['1'] level = int(place_matches[0]) depth = level * 2 # Leaving a ziggurat level by the exit gets more props than merely # entering the level. if mtype == 'zig.exit': depth += 1 player = g['name'] deepest = player_ziggurat_deepest(c, player) def insert(): query_do( c, '''INSERT INTO ziggurats (player, deepest, place, zig_time, start_time) VALUES (%s, %s, %s, %s, %s)''', player, depth, place, g['time'], g['start']) player_ziggurat_deepest.flush_key(player) dirty_page('overview', 1) if deepest: if depth >= deepest: query_do( c, '''UPDATE ziggurats SET deepest = %s, place = %s, zig_time = %s, start_time = %s WHERE player = %s''', depth, place, g['time'], g['start'], player) dirty_page('overview', 1) else: if ziggurat_entry_count(c) >= MAX_ZIGGURAT_VISITS: row = ziggurat_row_inferior_to(c, depth) if row: query_do(c, '''DELETE FROM ziggurats WHERE id = %s''', row) ziggurat_row_inferior_to.flush_key(depth) insert() else: ziggurat_entry_count.flush() insert()
def insert(self, c): dirty_page('killers', len(self.killer_stats)) killcounts_l = [(k, self.killer_stats[k][0], self.killer_stats[k][1]['name']) for k in self.killer_stats.keys()] c.executemany('''INSERT INTO top_killers (ckiller, kills, most_recent_victim) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE kills = kills + VALUES(kills), most_recent_victim = VALUES(most_recent_victim)''', killcounts_l) killgames_del = [(ckiller,) for ckiller in self.killer_stats.keys()] killgames_ins = [self.killer_stats[k][1] for k in self.killer_stats.keys()] c.executemany('''DELETE FROM killer_recent_kills WHERE ckiller = %s''', killgames_del) insert_games(c, killgames_ins, 'killer_recent_kills') self.clear()
def insert(self, c): # TODO: this goes once per commit, so that the db is in a # consistent state at each commit. But it could be even faster to do it # once per update cycle... if len(self.games) >= MAX_ALL_RECENT_GAMES: # on a bulk insert, we will be continually swapping these out -- no need # for subtlety. Note that this will wipe out ids entirely. c.execute("TRUNCATE TABLE all_recent_games") all_recent_game_count.set_key(MAX_ALL_RECENT_GAMES) else: extra = all_recent_game_count(c) + len( self.games) - MAX_ALL_RECENT_GAMES # old version first selected ids, then deleted by ids -- not sure if there # is any good reason for that? if extra > 0: c.execute("DELETE FROM all_recent_games ORDER BY id LIMIT %d" % extra) all_recent_game_count.set_key(MAX_ALL_RECENT_GAMES) else: all_recent_game_count.flush_key( ) # why do we even bother with this case? insert_games(c, self.games, 'all_recent_games') dirty_page('recent', len(self.games)) # TODO: why are these here and not with the per-day stats? dirty_page('per-day', len(self.games)) dirty_page('per-day-monthly', len(self.games)) self.clear()
def update_topscore_table_for(c, g, fn, table, thing): sc = g['sc'] value = g[thing] if sc > fn(c, value): fn.set_key(sc, value) query_do(c, "DELETE FROM " + table + " WHERE " + thing + " = %s", value) insert_game(c, g, table) dirty_page('top-combo-scores', 25) dirty_page('combo-scoreboard', 25) dirty_page('overview', 5)