Changeset 1110


Ignore:
Timestamp:
03/17/10 00:06:03 (2 years ago)
Author:
savin.tiberiu@…
Message:

The long awaited moment. *drumroll*

Split ia score.

Scores are now separated from the ratings. Also the rankings macro can take detail_round and detail_task parameters to add more columns.

REVIEW URL: http://reviewboard.infoarena.ro/r/64/

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/common/db/db.php

    r997 r1110  
    246246} 
    247247 
     248// Escape an array of strings. 
     249function db_escape_array($array) { 
     250    $ret = implode(',', array_map('db_quote', $array)); 
     251 
     252    return $ret; 
     253} 
     254 
    248255// Executes query, fetches only FIRST result row 
    249256function db_fetch($query) { 
  • trunk/common/db/round.php

    r1109 r1110  
    5252        _round_cache_delete($round); 
    5353        return false; 
     54    } 
     55} 
     56 
     57function round_recompute_score($round_id) { 
     58    $query = "SELECT * FROM `ia_score_user_round` 
     59        WHERE `round_id` = ".db_quote($round_id); 
     60    $rows = db_fetch_all($query); 
     61    $users = array(); 
     62    foreach ($rows as $row) { 
     63      $users[] = $row['user_id']; 
     64    } 
     65 
     66    $query = "SELECT SUM(`score`) AS score, user_id 
     67            FROM ia_score_user_round_task 
     68            WHERE `user_id` IN ('".implode("', '", $users)."') AND 
     69                  `round_id` = ".db_quote($round_id)." 
     70            GROUP BY `user_id`"; 
     71    $rows = db_fetch_all($query); 
     72    foreach($rows as $row) { 
     73        $user_id = $row['user_id']; 
     74        $score = $row['score']; 
     75 
     76        $query = "UPDATE `ia_score_user_round` 
     77                    SET `score` = ".db_quote($score)." 
     78                    WHERE `user_id` = ".db_quote($user_id)." && 
     79                          `round_id` = ".db_quote($round_id); 
     80        db_query($query); 
    5481    } 
    5582} 
     
    77104// 
    78105// if user_id is non-null a join is done on $score 
    79 function round_get_tasks($round_id, $first = 0, $count = null, $user_id = null, $score_name = null, $filter = null) { 
     106function round_get_tasks($round_id, $first = 0, $count = null, $user_id = null, $fetch_scores = false, $filter = null) { 
    80107    if ($count === null) { 
    81108        $count = 666013; 
     
    90117               task.`open_source` AS `open_source`, 
    91118               task.`open_tests` AS `open_tests`"; 
    92  
    93     if ($score_name === null || $user_id === null) { 
     119    if ($user_id == null || $fetch_scores == false) { 
    94120        $query = sprintf("SELECT $fields 
    95121                          FROM ia_round_task as round_task 
     
    97123                          WHERE `round_task`.`round_id` = '%s' 
    98124                          ORDER BY task.`order` LIMIT %d, %d", 
    99                          db_escape($round_id), db_escape($first), db_escape($count)); 
     125                          db_escape($round_id), db_escape($first), db_escape($count)); 
    100126    } else { 
    101127        $filter_clause = db_get_task_filter_clause($filter, 'score'); 
    102128        log_assert(is_whole_number($user_id)); 
    103         $query = sprintf("SELECT $fields, score.score as score 
     129        $query = sprintf("SELECT $fields, score.`score` AS `score` 
    104130                          FROM ia_round_task as round_task 
    105131                          LEFT JOIN ia_task as task ON task.id = round_task.task_id 
    106                           LEFT JOIN ia_score as score ON 
    107                                 score.user_id = %s AND 
    108                                 score.name = '%s' AND 
    109                                 score.round_id = '%s' AND 
    110                                 score.task_id = round_task.task_id 
     132                          LEFT JOIN ia_score_user_round_task as score ON 
     133                                score.round_id = round_task.round_id AND 
     134                                score.task_id = round_task.task_id AND 
     135                                score.user_id = '%s' 
    111136                          WHERE `round_task`.`round_id` = '%s' 
    112                               AND %s 
     137                            AND %s 
    113138                          ORDER BY task.`order` LIMIT %d, %d", 
    114                          db_escape($user_id), db_escape($score_name), db_escape($round_id), 
     139                         db_escape($user_id), 
    115140                         db_escape($round_id), db_escape($filter_clause), 
    116141                         db_escape($first), db_escape($count)); 
     
    119144} 
    120145 
    121 function round_get_task_count($round_id, $user_id, $scores, $filter) 
     146function round_get_task_count($round_id, $user_id, $filter) 
    122147{ 
    123     if ($user_id && $filter && $scores) { 
    124         $filter_clause = db_get_task_filter_clause($filter, 'ia_score'); 
     148    if ($user_id && $filter) { 
     149        $filter_clause = db_get_task_filter_clause($filter, 'ia_score_user_round_task'); 
    125150        $query = sprintf("SELECT COUNT(*) FROM ia_round_task " . 
    126                          "LEFT JOIN ia_score " . 
    127                          "ON ia_round_task.round_id = ia_score.round_id " . 
    128                          "AND ia_round_task.task_id = ia_score.task_id " . 
    129                          "AND ia_score.user_id = %s " . 
    130                          "AND ia_score.name = '%s' " . 
     151                         "LEFT JOIN ia_score_user_round_task " . 
     152                         "ON ia_round_task.round_id = ia_score_user_round_task.round_id " . 
     153                         "AND ia_round_task.task_id = ia_score_user_round_task.task_id " . 
     154                         "AND ia_score_user_round_task.user_id = %s " . 
    131155                         "WHERE ia_round_task.round_id = '%s' " . 
    132156                         "AND %s", 
    133157                         db_escape($user_id), 
    134                          db_escape($scores), 
    135158                         db_escape($round_id), 
    136159                         db_escape($filter_clause) 
  • trunk/common/db/score.php

    r1082 r1110  
    66require_once(IA_ROOT_DIR."common/rating.php"); 
    77 
    8 // Escape an array of strings. 
    9 function db_escape_array($array) 
     8// Updates a user's rating and deviation 
     9function score_update_rating($user_id, $round_id, $deviation, $rating) 
    1010{ 
    11     $ret = ''; 
    12     foreach ($array as $element) { 
    13         if ($ret) { 
    14             $ret .= ", "; 
    15         } 
    16         $ret .= "'" . db_escape($element) . "'"; 
    17     } 
    18     return $ret; 
    19 } 
    20  
    21 // Update a score. 
    22 // user/task/round can be null. 
    23 function score_update($name, $user_id, $task_id, $round_id, $value) 
    24 { 
    25     log_assert(is_score_name($name), "Bad score name '$name'"); 
    26     log_assert(is_null($user_id) || is_user_id($user_id), "Bad user id '$user_id'"); 
    27     log_assert(is_null($task_id) || is_task_id($task_id), "Bad task id '$task_id'"); 
    28     log_assert(is_null($round_id) || is_round_id($round_id), "Bad round id '$round_id'"); 
    29     $query = sprintf(" 
    30             INSERT INTO ia_score (`name`, `score`, `user_id`, `task_id`, `round_id`) 
    31             VALUES ('%s', %s, %s, %s, %s) ON DUPLICATE KEY UPDATE `score`=%s", 
    32             db_escape($name), $value, 
    33             ($user_id === null ? 'NULL' : $user_id), 
    34             ($task_id === null ? 'NULL' : "'".db_escape($task_id)."'"), 
    35             ($round_id === null ? 'NULL' : "'".db_escape($round_id)."'"), 
    36             $value); 
    37     return db_query($query); 
     11    $query = "INSERT INTO `ia_rating` (`user_id`, `round_id`, `deviation`, `rating`) 
     12             VALUES (".implode(',', 
     13             array(db_quote($user_id), 
     14                 db_quote($round_id), 
     15                 db_quote($deviation), 
     16                 db_quote($rating) 
     17             )).") ON DUPLICATE KEY UPDATE ". 
     18                 "`rating` = ". $rating .", 
     19                 `deviation` = ".$deviation; 
     20    db_query($query); 
     21    return db_affected_rows(); 
     22} 
     23 
     24// Updates user's task score 
     25function score_update($user_id, $task_id, $round_id, $value) { 
     26    log_assert(is_user_id($user_id), "Bad user id '$user_id'"); 
     27    log_assert(is_task_id($task_id), "Bad task id '$task_id'"); 
     28    log_assert(is_round_id($round_id), "Bad round id '$round_id'"); 
     29 
     30    // Update user_id score for task_id at round_id 
     31    $query = "INSERT INTO `ia_score_user_round_task` (`user_id`, `round_id`, `task_id`, `score`) 
     32            VALUES (".implode(',', 
     33            array(db_quote($user_id), 
     34                db_quote($round_id), 
     35                db_quote($task_id), 
     36                db_quote($value) 
     37            )).") ON DUPLICATE KEY UPDATE 
     38                `score` = ".db_quote($value); 
     39    db_query($query); 
     40 
     41    // update score for round_id 
     42    $subquery = "( SELECT SUM(`score`) AS 'score' FROM `ia_score_user_round_task` 
     43            WHERE 
     44                `round_id` = ".db_quote($round_id)." && 
     45                `user_id` = ".db_quote($user_id)." 
     46            GROUP BY `user_id` )"; 
     47 
     48    $query = "INSERT INTO `ia_score_user_round` (`user_id`, `round_id`, `score`) 
     49            VALUES (".implode(',', 
     50            array(db_quote($user_id), 
     51                db_quote($round_id), 
     52                $subquery 
     53            )).") ON DUPLICATE KEY UPDATE 
     54                `score` = ".$subquery; 
     55    db_query($query); 
    3856} 
    3957 
     
    86104} 
    87105 
    88 // Build a query for a certain score. 
    89 // Can be used as a subquery. 
    90 function score_build_query($score, $user, $task, $round) 
    91 { 
    92     $cond = score_build_where_clauses($user, $task, $round); 
    93     $cond[] = "(id = '".db_escape($score['name'])."')"; 
    94     $query = "SELECT SUM(score) FROM ia_score WHERE " . implode(" AND ", $cond); 
    95 } 
    96  
    97 // Get scores. 
    98 // $user, $task, $round can be null, string or an array. 
    99 // If null it's ignored, otherwise only scores for those users/tasks/rounds 
    100 // are counted. 
    101 function score_get_range($score_name, $user, $task, $round, $groupby = "user_id", $start = 0, $count = 999999, $with_rankings = false) 
    102 { 
    103     log_assert(is_score_name($score_name)); 
     106// Count function to be used for score_get_rankings 
     107function score_get_count($user, $task, $round) { 
    104108    $where = score_build_where_clauses($user, $task, $round); 
    105     $where[] = sprintf("ia_score.`name` = '%s'", db_escape($score_name)); 
    106     $query = sprintf("SELECT 
    107                 ia_score.`name` AS `score_name`, `user_id`, `task_id`, `round_id`, SUM(`score`) AS score,  
    108                 ia_user.username AS user_name, ia_user.full_name AS user_full, 
    109                 ia_user.rating_cache AS user_rating 
    110             FROM ia_score 
    111                 LEFT JOIN ia_user ON ia_user.id = ia_score.user_id 
    112             WHERE %s GROUP BY %s 
    113             ORDER BY `score` DESC LIMIT %s, %s", 
    114             join($where, " AND "), $groupby, $start, $count); 
    115     $scores = db_fetch_all($query); 
    116  
    117     if ($with_rankings && count($scores)) { 
    118         $first_score = $scores[0]['score']; 
    119  
    120         // We need to count all users with a greater score than the first user 
    121         // in the requested range. 
    122         $where = score_build_where_clauses($user, $task, $round); 
    123         $where[] = sprintf("ia_score.`name` = '%s'", db_escape($score_name)); 
    124         $query = sprintf("SELECT SUM(`score`) AS score  
    125                           FROM ia_score 
    126                           WHERE %s GROUP BY %s 
    127                           HAVING score > %s", 
    128                          join($where, " AND "), $groupby, $first_score); 
    129         $users_before = db_num_rows(db_query($query)); 
    130  
    131         // store rankings in result 
    132         $scores[0]['ranking'] = $users_before + 1; 
    133         $equal_scores = $start - $users_before + 1; 
    134         for ($i = 1; $i < count($scores); ++$i) { 
    135             $last_row = $scores[$i - 1]; 
    136             $row =& $scores[$i]; 
    137             if ($row['score'] == $last_row['score']) { 
    138                 $row['ranking'] = $last_row['ranking']; 
    139                 $equal_scores = $equal_scores + 1; 
    140             } 
    141             else { 
    142                 $row['ranking'] = $last_row['ranking'] + $equal_scores; 
    143                 $equal_scores = 1; 
    144             } 
    145         } 
    146     } 
    147  
    148     return $scores; 
    149 } 
    150  
    151 // Count function for score_get_range 
    152 function score_get_count($score_name, $user, $task, $round, $groupby) { 
    153     log_assert(is_score_name($score_name)); 
    154     $where = score_build_where_clauses($user, $task, $round); 
    155     $where[] = sprintf("ia_score.`name` = '%s'", db_escape($score_name)); 
    156     if ($user !== null) { 
    157         $join = "LEFT JOIN ia_user ON ia_user.id = ia_score.user_id"; 
    158     } else { 
    159         $join = ""; 
    160     } 
    161109    $query = sprintf("SELECT COUNT(DISTINCT user_id) AS `cnt` 
    162             FROM ia_score $join 
     110            FROM ia_score_user_round 
    163111            WHERE %s", 
    164             join($where, " AND "), $groupby); 
     112            join($where, " AND ")); 
    165113    $res = db_fetch($query); 
    166114    return $res['cnt']; 
    167 } 
    168  
    169 // Get a score value. 
    170 // Returns 0 or null (if missing). 
    171 function score_get_value($score_name, $user_id, $task_id, $round_id) 
    172 { 
    173     log_assert(is_score_name($score_name)); 
    174     log_assert(is_whole_number($user_id)); 
    175     log_assert(is_task_id($task_id)); 
    176     log_assert(is_user_id($round_id)); 
    177  
    178     $query = sprintf("SELECT score FROM ia_score 
    179                 WHERE name = '%s', task_id='%s', round_id='%s', user_id = %s", 
    180                 $score_name, $task_id, $round_id, $user_id); 
    181     $res = db_fetch($query); 
    182     return getattr($res, 'score', null); 
    183115} 
    184116 
     
    204136 
    205137    // get user scores 
    206     $query = sprintf("SELECT * FROM `ia_score` 
     138    $query = sprintf("SELECT * FROM `ia_rating` 
    207139                      LEFT JOIN ia_round ON round_id = ia_round.id 
    208                       WHERE `name` IN ('deviation', 'rating') 
    209                             AND ia_score.user_id = '%s' 
     140                      WHERE ia_rating.user_id = '%s' 
    210141                            AND ia_round.state = 'complete' 
    211                      ", 
    212                      db_escape($user_id)); 
    213     $rows = db_fetch_all($query); 
    214  
    215     // process user scores 
     142                     ", db_escape($user_id)); 
     143    $rows = db_fetch_all($query); 
     144 
    216145    foreach ($rows as $row) { 
    217146        $round_id = $row['round_id']; 
    218         log_assert(isset($history[$round_id])); 
    219  
    220         switch ($row['name']) { 
    221             case 'rating': 
    222                 $history[$round_id]['rating'] = $row['score']; 
    223                 break; 
    224             case 'deviation': 
    225                 $history[$round_id]['deviation'] = $row['score']; 
    226                 break; 
    227             default: 
    228                 log_error("Query returned invalid rating scores"); 
    229         } 
     147        $history[$round_id]['rating'] = $row['rating']; 
     148        $history[$round_id]['deviation'] = $row['deviation']; 
    230149    } 
    231150 
     
    255174//  ); 
    256175function rating_rounds() { 
    257     $query = " 
    258         SELECT 
     176    $query = "SELECT 
    259177               object_id AS round_id, `value` AS `timestamp`, 
    260178               ia_round.page_name AS round_page_name, 
     
    329247    // FIXME: horrible query 
    330248    $query = "SELECT 
    331         ia_score.name AS `name`, ia_score.score AS score, 
    332                ia_score.user_id, ia_score.round_id, 
     249        ia_rating.rating AS `rating`, ia_rating.deviation AS deviation, 
     250               ia_rating.user_id, ia_rating.round_id, 
    333251               pv.`value` AS `timestamp`, ia_user.username 
    334         FROM ia_score 
     252        FROM ia_rating 
    335253        LEFT JOIN ia_parameter_value AS pv 
    336             ON pv.object_type = 'round' AND pv.object_id = ia_score.round_id 
     254            ON pv.object_type = 'round' AND pv.object_id = ia_rating.round_id 
    337255            AND pv.parameter_id = 'rating_timestamp' 
    338         LEFT JOIN ia_user ON ia_user.id = ia_score.user_id 
    339         WHERE ia_score.name IN ('rating', 'deviation') 
    340         ORDER BY `timestamp` DESC, ia_score.round_id DESC 
     256        LEFT JOIN ia_user ON ia_user.id = ia_rating.user_id 
     257        ORDER BY `timestamp` DESC, ia_rating.round_id DESC 
    341258    "; 
    342259    $rows = db_fetch_all($query); 
    343260 
    344     // FIXME: We should filter out rounds having rating_update off 
    345     // but these should not have any ratings stored in database anyway... 
    346  
    347     // parse rows  
    348261    $users = array(); 
    349262    foreach ($rows as $row) { 
    350263        $username = $row['username']; 
    351         $field = $row['name']; 
    352264        if (isset($users[$username])) { 
    353             if (isset($users[$username][$field])) { 
    354                 // FIXME: This is currently a hack. 
    355                 // Query shouldn't return more then one rating for each user 
    356                 continue; 
    357             } 
    358             else { 
    359                 $users[$username][$field] = $row['score']; 
    360             } 
    361         } 
    362         else { 
    363             $users[$username] = array( 
    364                 $field => $row['score'], 
    365                 'timestamp' => parameter_decode('rating_timestamp', 
    366                                                 $row['timestamp']) 
    367             ); 
    368         } 
     265            continue; 
     266        } 
     267 
     268        $users[$username] = array( 
     269                'rating' => $row['rating'], 
     270                'deviation' => $row['deviation'], 
     271                'timestamp' => $row['timestamp']); 
    369272    } 
    370273 
     
    429332 
    430333        $rows[0]['position'] = $users_before + 1; 
    431         $equal_scores = $start - $users_before + 1;           
     334        $equal_scores = $start - $users_before + 1; 
    432335        for ($i = 1; $i < count($rows); ++$i) { 
    433336            $last_row = $rows[$i - 1]; 
     
    459362// Clears ALL user ratings & rating history 
    460363function rating_clear() { 
    461     db_query("DELETE FROM ia_score WHERE `name` IN ('rating', 'deviation')"); 
     364    db_query("DELETE FROM ia_rating"); 
    462365    db_query("UPDATE ia_user SET rating_cache = NULL"); 
    463366} 
    464367 
     368// Computes rankings for $rounds 
     369// returns entries from start to count 
     370// if detail_task == true, extra columns for each task will be created 
     371// if detail_round == true, extra columns for each round will be created 
     372function score_get_rankings($rounds, $tasks, $start = 0, $count = 999999, $detail_task = false, $detail_round = false) 
     373{ 
     374    $where = score_build_where_clauses(null, null, $rounds); 
     375 
     376    // Get the total score for all rounds 
     377    $query = "SELECT SUM(score) AS score, user_id, ia_user.username AS user_name, ia_user.full_name AS user_full, 
     378                    ia_user.rating_cache AS user_rating 
     379                FROM ia_score_user_round 
     380                LEFT JOIN ia_user ON ia_user.id = ia_score_user_round.user_id 
     381                WHERE ".implode('AND', $where)." 
     382                GROUP BY `user_id` 
     383                ORDER BY score DESC 
     384                LIMIT ".db_escape($start).", ".db_escape($count); 
     385 
     386    $rankings = db_fetch_all($query); 
     387    if (count($rankings) == 0) { 
     388        return $rankings; 
     389    } 
     390 
     391    $users = array(); 
     392    foreach ($rankings as $ranking) { 
     393        array_push($users, $ranking['user_id']); 
     394    } 
     395 
     396    // Further queries concern only the users that are in this rankings page 
     397    $filter_users = score_build_where_clauses($users, null, null); 
     398    $where[] = $filter_users[0]; 
     399 
     400    // Detailed scores are mapped in an array with the following form 
     401    // Array[user_id][object_id] = user score for object 
     402    // Object can be round or task 
     403 
     404    if ($detail_round == true) { 
     405        // Get scores for each round 
     406        $query = "SELECT round_id, user_id, score 
     407                FROM ia_score_user_round 
     408                WHERE ".implode('AND', $where); 
     409        $scores = db_fetch_all($query); 
     410        foreach ($scores as $score) { 
     411            $user_id = $score['user_id']; 
     412            $round_id = $score['round_id']; 
     413            $rscore = $score['score']; 
     414            $round_scores[$user_id][$round_id] = $rscore; 
     415        } 
     416    } 
     417 
     418    if ($detail_task == true) { 
     419        // Get scores for each task 
     420        $query = "SELECT task_id, user_id, score 
     421                FROM ia_score_user_round_task 
     422                WHERE ".implode('AND', $where); 
     423        $scores = db_fetch_all($query); 
     424        foreach ($scores as $score) { 
     425            $user_id = $score['user_id']; 
     426            $task_id = $score['task_id']; 
     427            $tscore = $score['score']; 
     428            $task_scores[$user_id][$task_id] = $tscore; 
     429        } 
     430    } 
     431 
     432    // Compute rank for the first entry 
     433    $top_score = $rankings[0]['score']; 
     434    $where = score_build_where_clauses(null, null, $rounds); 
     435    $query = "SELECT SUM(score) AS score 
     436                FROM ia_score_user_round 
     437                WHERE ".implode(' AND ', $where)." 
     438                GROUP BY user_id 
     439                HAVING score > ".db_quote($top_score); 
     440    $first_rank = db_num_rows(db_query($query)) + 1; 
     441 
     442    //create all entries 
     443    for ($i = 0; $i < count($rankings); $i++) { 
     444        $user_id = $rankings[$i]['user_id']; 
     445 
     446        //task columns 
     447        if ($detail_task == true) { 
     448            foreach ($tasks as $task) { 
     449                $task_id = $task['id']; 
     450                if (isset($task_scores[$user_id][$task_id])) { 
     451                    $score = $task_scores[$user_id][$task_id]; 
     452                } else { 
     453                    $score = 0; 
     454                } 
     455                $rankings[$i][$task_id] = $score; 
     456            } 
     457        } 
     458 
     459        //round columns 
     460        if ($detail_round == true) { 
     461            foreach ($rounds as $round_id) { 
     462                if (isset($round_scores[$user_id][$round_id])) { 
     463                    $score = $round_scores[$user_id][$round_id]; 
     464                } else { 
     465                    $score = 0; 
     466                } 
     467                $rankings[$i][$round_id] = $score; 
     468            } 
     469        } 
     470 
     471        if ($i == 0) { 
     472            $rankings[$i]['ranking'] = $first_rank; 
     473            continue; 
     474        } 
     475 
     476        // Users with the same score should be on the same rank 
     477        if ($rankings[$i]['score'] == $rankings[$i - 1]['score']) { 
     478            $rankings[$i]['ranking'] = $rankings[$i - 1]['ranking']; 
     479        } else { 
     480            $rankings[$i]['ranking'] = $start + $i + 1; 
     481        } 
     482    } 
     483 
     484    return $rankings; 
     485} 
     486 
     487 
    465488?> 
  • trunk/common/db/task.php

    r1095 r1110  
    6666    textblock_delete($task["page_name"]); 
    6767 
     68    // Delete all scores received on task 
     69    db_query("DELETE FROM `ia_score_user_round_task` 
     70              WHERE `task_id` = " . db_quote($task["id"])); 
     71 
     72    // Recompute round scores 
     73    $query = "SELECT `round_id` FROM `ia_round_task` 
     74                WHERE `task_id` = ".db_quote($task['id']); 
     75    $rounds = db_fetch_all($query); 
     76 
     77    foreach ($rounds as $round) { 
     78        round_recompute_score($round['round_id']); 
     79    } 
     80 
    6881    // Remove task from all rounds 
    6982    db_query("DELETE FROM `ia_round_task` 
    70               WHERE `task_id` = " . db_quote($task["id"])); 
    71  
    72     // Delete all scores received on task 
    73     db_query("DELETE FROM `ia_score` 
    7483              WHERE `task_id` = " . db_quote($task["id"])); 
    7584 
  • trunk/common/db/user.php

    r1094 r1110  
    218218    } 
    219219    elseif ($solved) { 
    220         $where = 'AND ia_score.score = 100'; 
     220        $where = 'AND ia_score_user_round_task.score = 100'; 
    221221    } 
    222222    elseif ($failed) { 
    223         $where = 'AND ia_score.score < 100'; 
     223        $where = 'AND ia_score_user_round_task.score < 100'; 
    224224    } 
    225225    else { 
     
    229229 
    230230    $query = sprintf("SELECT * 
    231         FROM ia_score 
    232         LEFT JOIN ia_task ON ia_task.id = ia_score.task_id 
    233         WHERE ia_score.`name` = 'score' AND ia_score.user_id = '%s' 
    234               AND ia_score.round_id = 'arhiva' AND NOT ia_task.id IS NULL %s 
     231        FROM ia_score_user_round_task 
     232        LEFT JOIN ia_task ON ia_task.id = ia_score_user_round_task.task_id 
     233        WHERE ia_score_user_round_task.user_id = '%s' 
     234              AND ia_score_user_round_task.round_id = 'arhiva' AND NOT ia_task.id IS NULL %s 
    235235        GROUP BY ia_task.id 
    236236        ORDER BY ia_task.`order`", $user_id, $where); 
     
    243243    // FIXME: Find a way to remove the hard-coded "<> 'arhiva'" 
    244244    $query = "SELECT * 
    245         FROM ia_score 
    246         LEFT JOIN ia_round ON ia_round.id = ia_score.round_id 
    247         WHERE ia_score.`name` = 'score' AND ia_score.user_id = '%s' 
     245        FROM ia_score_user_round_task 
     246        LEFT JOIN ia_round ON ia_round.id = ia_score_user_round_task.round_id 
     247        WHERE ia_score_user_round_task.user_id = '%s' 
    248248              AND NOT ia_round.id IS NULL AND ia_round.id <> 'arhiva' 
    249249        GROUP BY ia_round.id"; 
  • trunk/common/score.php

    r1046 r1110  
    1919    $rduration = getattr($rparams, 'duration', 10000000) * 60 * 60; 
    2020    if ($time >= $rstart && $time <= $rstart + $rduration) { 
    21         score_update('score', $user_id, $task_id, $round['id'], $score); 
     21        score_update($user_id, $task_id, $round['id'], $score); 
    2222    } 
    2323} 
  • trunk/scripts/db-strip

    r1100 r1110  
    9494        "OR (ia_score.task_id IS NOT NULL AND ia_task.id IS NULL) ". 
    9595        "OR (ia_score.round_id IS NOT NULL AND ia_round.id IS NULL)"); 
     96 
     97db_query("DELETE ia_score_user_round_task FROM ia_score_user_round_task ". 
     98         "LEFT JOIN ia_user on ia_user.id = ia_score_user_round_task.user_id ". 
     99         "LEFT JOIN ia_task on ia_task.id = ia_score_user_round_task.task_id ". 
     100         "LEFT JOIN ia_round on ia_round.id = ia_score_user_round_task.round_id ". 
     101         "WHERE (ia_score_user_round_task.user_id IS NOT NULL AND ia_user.id IS NULL) ". 
     102         "OR (ia_score_user_round_task.task_id IS NOT NULL AND ia_task.id IS NULL) ". 
     103         "OR (ia_score_user_round_task.round_id IS NOT NULL AND ia_round.id IS NULL)"); 
     104 
     105// Recompute ia_score_user_round 
     106db_query("DELETE FROM ia_score_user_round"); 
     107$rounds = db_fetch_all("SELECT id FROM ia_round"); 
     108 
     109foreach ($rounds as $round) { 
     110    round_recompute_score($round['round_id']); 
     111} 
     112 
     113// Delete orphan rating entries 
     114db_query("DELETE ia_rating FROM ia_rating ". 
     115        "LEFT JOIN ia_user on ia_user.id = ia_rating.user_id ". 
     116        "LEFT JOIN ia_round on ia_round.id = ia_rating.round_id ". 
     117        "WHERE (ia_rating.user_id IS NOT NULL AND ia_user.id IS NULL) ". 
     118        "OR (ia_rating.round_id IS NOT NULL AND ia_round.id IS NULL)"); 
    96119 
    97120// Delete orphan jobs. 
  • trunk/scripts/round-statistics

    r1001 r1110  
    6161$query = sprintf(' 
    6262SELECT COUNT(DISTINCT(`user_id`)) 
    63     FROM `ia_score` 
    64     WHERE `name` = "score" AND 
    65           `score` > 0 AND 
     63    FROM `ia_score_user_round` 
     64    WHERE `score` > 0 AND 
    6665          `round_id` LIKE %s', db_quote($round_like)); 
    6766 
     
    8180    FROM ( 
    8281        SELECT `user_id`, `task_id`, `score` 
    83         FROM `ia_score` 
    84         WHERE `name` = "score" AND 
    85               `round_id` LIKE %s 
     82        FROM `ia_score_user_round_task` 
     83        WHERE `round_id` LIKE %s 
    8684        GROUP BY `user_id`, `task_id` 
    8785        ) AS `grouped_by_tasks` 
     
    10199    FROM ( 
    102100        SELECT `user_id`, `task_id`, `score` 
    103         FROM `ia_score` 
    104         WHERE `name` = "score" AND 
    105               `round_id` LIKE %s AND 
     101        FROM `ia_score_user_round_task` 
     102        WHERE `round_id` LIKE %s AND 
    106103              `score` > 0 
    107104        GROUP BY `user_id`, `task_id` 
  • trunk/scripts/task-difficulty

    r852 r1110  
    6363    $query = <<<SQL 
    6464        SELECT COUNT(*) 
    65         FROM ia_score 
     65        FROM ia_score_user_round_task 
    6666        LEFT JOIN ia_user ON ia_user.id = user_id 
    67         WHERE rating_cache > 0 AND ia_score.name='score' AND round_id='arhiva' 
     67        WHERE rating_cache > 0 AND round_id='arhiva' 
    6868                AND task_id='%s' 
    6969SQL; 
     
    8080        SELECT AVG(rating_cache) FROM ( 
    8181            SELECT rating_cache 
    82             FROM ia_score 
     82            FROM ia_score_user_round_task 
    8383            LEFT JOIN ia_user ON ia_user.id = user_id 
    84             WHERE rating_cache > 0 AND ia_score.name='score' AND round_id='arhiva' 
     84            WHERE rating_cache > 0 AND round_id='arhiva' 
    8585                    AND task_id='%s' 
    8686            ORDER BY rating_cache 
  • trunk/scripts/update-ratings

    r1071 r1110  
    8080// read round scores 
    8181log_print("Reading round scores..."); 
    82 $round_rows = score_get_range("score", null, null, $round_id, "user_id", 0, $usercount); 
     82$round_rows = score_get_rankings($round_id, null, 0, $usercount); 
    8383log_print(count($round_rows) . " users were scored in this round."); 
    8484foreach ($round_rows as $row) { 
     
    9898    $user_id = $row['user_id']; 
    9999    // for this round (history) 
    100     score_update("rating", $user_id, null, $round_id, 
    101                  $users[$username]['rating']); 
    102     score_update("deviation", $user_id, null, $round_id, 
    103                  $users[$username]['deviation']); 
     100    score_update_rating($user_id, $round_id, $users[$username]['deviation'], $users[$username]['rating']); 
     101 
    104102    // cache rating 
    105103    $user = $ucheck[$username]; 
  • trunk/www/macros/macro_rankings.php

    r992 r1110  
    1010// 
    1111// Arguments: 
    12 //     rounds   (required) a | (pipe) separated list of round names. 
     12//     rounds   (required) a | (pipe) separated list of round_id : round_name. 
     13//              Round name is the name which will appear in the column dedicated 
     14//              to that round in case detail_round == true 
     15//              If detail_round == false you can leave just the round_id (see examples) 
    1316//     count    (optional) how many to display at once, defaults to infinity 
     17//     detail_task   (optional) true/false print score columns for each task 
     18//     detail_round  (optional) true/false  print score columns for each round 
     19// Examples: 
     20//      Macro: Rankings(rounds="preONI2007/1/a | preONI2007/2/a" count = "10") 
     21//      Columns: | pos | name | score | 
    1422// 
    15 // Examples: 
    16 //      Rankings(rounds="preONI2007/1/a | preONI2007/2/a") 
    17 //      Rankings(rounds="preONI2007/1/a | preONI2007/2/a" count="10") 
     23//      Rankings(rounds="preONI2007/1/a : round 1 | preONI2007/2/a : round 2" detail_round = "true") 
     24//      Columns: | pos | name | round 1 | round 2 | total | 
     25// 
     26//      Rankings(rounds="preONI2007/1/a : round 1 | preONI2007/2/a : round 2" detail_round = "true" detail_task = "true") 
     27//      Columns: | pos | name | task | task | task | round 1 | task | task | task | round 2 | total | 
    1828function macro_rankings($args) { 
    1929    $args['param_prefix'] = 'rankings_'; 
     
    2131        $args['display_entries'] = $args['count']; 
    2232    } 
     33 
     34    // Detail parameters 
     35    $detail_round = getattr($args, 'detail_round', 'false'); 
     36    $detail_task = getattr($args, 'detail_task', 'false'); 
     37 
     38    $detail_round = ($detail_round == 'true'); 
     39    $detail_task = ($detail_task == 'true'); 
     40 
     41    // Paginator options 
    2342    $options = pager_init_options($args); 
    2443    $options['show_count'] = true; 
     
    2948        return macro_error("Parameters 'rounds' is required."); 
    3049    } 
    31     $rounds = preg_split('/\s*\|\s*/', $roundstr); 
     50    $round_param = preg_split('/\s*\|\s*/', $roundstr); 
     51    $rounds = array(); 
     52    foreach ($round_param as $param) { 
     53        $round = preg_split('/\s*\:\s*/', $param); 
     54        array_push($rounds, array( 
     55            'round_id' => $round[0], 
     56            'round_name' => getattr($round, 1, ' ') 
     57            ) 
     58        ); 
     59    } 
    3260 
    33     // FIXME: user / task parameters. 
    34     $rankings = score_get_range("score", null, null, $rounds, "user_id", $options['first_entry'], $options['display_entries'], true); 
     61    // Generating Table 
    3562 
    3663    $column_infos = array( 
     
    4774                                         'return format_user_normal($row["user_name"], $row["user_full"], $row["user_rating"]);'), 
    4875        ), 
    49         array( 
    50             'title' => 'Scor', 
     76    ); 
     77 
     78    $columns = array(); 
     79    $tasks = array(); 
     80    if ($detail_round == true || $detail_task == true) { 
     81        foreach ($rounds as $round) { 
     82            $round_id = $round['round_id']; 
     83 
     84            if ($detail_task == true) { 
     85            $new_tasks = round_get_tasks($round_id, null, null, null, null, null); 
     86            foreach ($new_tasks as $task) { 
     87                array_push($columns, array( 
     88                    'name' => $task['id'], 
     89                    'type' => 'task', 
     90                    'title' => $task['title'] 
     91                )); 
     92                array_push($tasks, $task); 
     93                } 
     94            } 
     95 
     96            if ($detail_round == true) { 
     97                array_push($columns, array( 
     98                    'name' => $round['round_id'], 
     99                    'type' => 'round', 
     100                    'title' => $round['round_name'] 
     101                )); 
     102            } 
     103        } 
     104    } 
     105 
     106    foreach ($columns as $column) { 
     107        array_push($column_infos, array( 
     108            'title' => $column['title'], 
     109            'key' => $column['name'], 
     110            'rowform' => create_function_cached('$row', 'return round($row[\''.$column['name'].'\']);'), 
     111            'css_class' => 'number score' 
     112            )); 
     113    } 
     114 
     115    $total = 'Scor'; 
     116    if ($detail_round == true || $detail_task == true) { 
     117        $total = 'Total'; 
     118    } 
     119    array_push($column_infos, array( 
     120            'title' => $total, 
    51121            'key' => 'score', 
    52122            'rowform' => create_function_cached('$row', 'return round($row[\'score\']);'), 
    53123            'css_class' => 'number score' 
    54         ), 
     124        ) 
    55125    ); 
    56126 
     127    $round_ids = array(); 
     128    foreach ($rounds as $round) { 
     129        array_push($round_ids, $round['round_id']); 
     130    } 
     131    $rankings = score_get_rankings($round_ids, $tasks, $options['first_entry'], $options['display_entries'], $detail_task, $detail_round); 
     132 
    57133    if (pager_needs_total_entries($options)) { 
    58         $options['total_entries'] = score_get_count("score", null, null, $rounds, 'user_id'); 
     134        $options['total_entries'] = score_get_count(null, null, $round_ids); 
    59135    } 
    60136 
  • trunk/www/macros/macro_tasks.php

    r1099 r1110  
    131131             $options['first_entry'], 
    132132             $options['display_entries'], 
    133              $user_id, ($scores ? 'score' : null), 
     133             $user_id, $scores, 
    134134             $filter); 
    135135    $options['total_entries'] = round_get_task_count( 
    136              $round_id, $user_id, ($scores ? 'score' : null), $filter); 
     136             $round_id, $user_id, $filter); 
    137137    $options['row_style'] = 'task_row_style'; 
    138138    $options['css_class'] = 'tasks'; 
Note: See TracChangeset for help on using the changeset viewer.