Files
yrtv/database/L2/processors/match_processor.py

129 lines
5.5 KiB
Python
Raw Normal View History

2026-01-29 02:21:44 +08:00
"""
Match Processor - Handles fact_matches and fact_match_teams
Responsibilities:
- Extract match basic information from JSON
- Process team data (group1/group2)
- Store raw JSON fields (treat_info, response metadata)
- Set data_source_type marker
"""
import sqlite3
import json
import logging
from typing import Any, Dict
logger = logging.getLogger(__name__)
def safe_int(val):
"""Safely convert value to integer"""
try:
return int(float(val)) if val is not None else 0
except:
return 0
def safe_float(val):
"""Safely convert value to float"""
try:
return float(val) if val is not None else 0.0
except:
return 0.0
def safe_text(val):
"""Safely convert value to text"""
return "" if val is None else str(val)
class MatchProcessor:
@staticmethod
def process(match_data, conn: sqlite3.Connection) -> bool:
"""
Process match basic info and team data
Args:
match_data: MatchData object containing parsed JSON
conn: L2 database connection
Returns:
bool: True if successful
"""
try:
cursor = conn.cursor()
# Build column list and values dynamically to avoid count mismatches
columns = [
'match_id', 'match_code', 'map_name', 'start_time', 'end_time', 'duration',
'winner_team', 'score_team1', 'score_team2', 'server_ip', 'server_port', 'location',
'has_side_data_and_rating2', 'match_main_id', 'demo_url', 'game_mode', 'game_name',
'map_desc', 'location_full', 'match_mode', 'match_status', 'match_flag', 'status', 'waiver',
'year', 'season', 'round_total', 'cs_type', 'priority_show_type', 'pug10m_show_type',
'credit_match_status', 'knife_winner', 'knife_winner_role', 'most_1v2_uid',
'most_assist_uid', 'most_awp_uid', 'most_end_uid', 'most_first_kill_uid',
'most_headshot_uid', 'most_jump_uid', 'mvp_uid', 'response_code', 'response_message',
'response_status', 'response_timestamp', 'response_trace_id', 'response_success',
'response_errcode', 'treat_info_raw', 'round_list_raw', 'leetify_data_raw',
'data_source_type'
]
values = [
match_data.match_id, match_data.match_code, match_data.map_name, match_data.start_time,
match_data.end_time, match_data.duration, match_data.winner_team, match_data.score_team1,
match_data.score_team2, match_data.server_ip, match_data.server_port, match_data.location,
match_data.has_side_data_and_rating2, match_data.match_main_id, match_data.demo_url,
match_data.game_mode, match_data.game_name, match_data.map_desc, match_data.location_full,
match_data.match_mode, match_data.match_status, match_data.match_flag, match_data.status,
match_data.waiver, match_data.year, match_data.season, match_data.round_total,
match_data.cs_type, match_data.priority_show_type, match_data.pug10m_show_type,
match_data.credit_match_status, match_data.knife_winner, match_data.knife_winner_role,
match_data.most_1v2_uid, match_data.most_assist_uid, match_data.most_awp_uid,
match_data.most_end_uid, match_data.most_first_kill_uid, match_data.most_headshot_uid,
match_data.most_jump_uid, match_data.mvp_uid, match_data.response_code,
match_data.response_message, match_data.response_status, match_data.response_timestamp,
match_data.response_trace_id, match_data.response_success, match_data.response_errcode,
match_data.treat_info_raw, match_data.round_list_raw, match_data.leetify_data_raw,
match_data.data_source_type
]
# Build SQL dynamically
placeholders = ','.join(['?' for _ in columns])
columns_sql = ','.join(columns)
sql = f"INSERT OR REPLACE INTO fact_matches ({columns_sql}) VALUES ({placeholders})"
cursor.execute(sql, values)
# Process team data
for team in match_data.teams:
team_row = (
match_data.match_id,
team.group_id,
team.group_all_score,
team.group_change_elo,
team.group_fh_role,
team.group_fh_score,
team.group_origin_elo,
team.group_sh_role,
team.group_sh_score,
team.group_tid,
team.group_uids
)
cursor.execute('''
INSERT OR REPLACE INTO fact_match_teams (
match_id, group_id, group_all_score, group_change_elo,
group_fh_role, group_fh_score, group_origin_elo,
group_sh_role, group_sh_score, group_tid, group_uids
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', team_row)
logger.debug(f"Processed match {match_data.match_id}")
return True
except Exception as e:
logger.error(f"Error processing match {match_data.match_id}: {e}")
import traceback
traceback.print_exc()
return False