Skip to content

Commit

Permalink
sim: refactor: add new submissions API
Browse files Browse the repository at this point in the history
  • Loading branch information
varqox committed Nov 2, 2024
1 parent aa386d8 commit 7cd5c73
Show file tree
Hide file tree
Showing 9 changed files with 3,242 additions and 54 deletions.
1 change: 1 addition & 0 deletions subprojects/sim/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ sim_server = executable('sim-server',
'src/web_server/problems/ui.cc',
'src/web_server/server/connection.cc',
'src/web_server/server/server.cc',
'src/web_server/submissions/api.cc',
'src/web_server/ui/ui.cc',
'src/web_server/ui_template.cc',
'src/web_server/users/api.cc',
Expand Down
94 changes: 62 additions & 32 deletions subprojects/sim/src/sim/db/schema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,34 +282,73 @@ const DbSchema& get_schema() {
" `last_judgment_began_at` datetime DEFAULT NULL,"
" `initial_report` mediumblob NOT NULL," // TODO: rename to initial_judgement_protocol
" `final_report` mediumblob NOT NULL," // TODO: rename to full_judgement_protocol
// Submissions API: all
" PRIMARY KEY (`id`),"
// Submissions API: with type
" KEY `type` (`type`,`id`),"
" KEY `problem_final` (`problem_final`,`id`),"
" KEY `contest_problem_final` (`contest_problem_final`,`id`),"
// Submissions API: with user_id
" KEY `user_id` (`user_id`,`id`),"
" KEY `user_id_2` (`user_id`,`type`,`id`),"
" KEY `user_id_3` (`user_id`,`problem_id`,`id`),"
" KEY `user_id_4` (`user_id`,`contest_problem_id`,`id`),"
" KEY `user_id_5` (`user_id`,`contest_round_id`,`id`),"
" KEY `user_id_6` (`user_id`,`contest_id`,`id`),"
" KEY `user_id_7` (`user_id`,`contest_problem_final`,`id`),"
" KEY `user_id_8` (`user_id`,`problem_final`,`id`),"
" KEY `user_id_9` (`user_id`,`problem_id`,`type`,`id`),"
" KEY `user_id_10` (`user_id`,`problem_id`,`problem_final`),"
" KEY `user_id_11` (`user_id`,`contest_problem_id`,`type`,`id`),"
" KEY `user_id_12` (`user_id`,`contest_problem_id`,`contest_problem_final`),"
" KEY `user_id_13` (`user_id`,`contest_round_id`,`type`,`id`),"
" KEY `user_id_14` (`user_id`,`contest_round_id`,`contest_problem_final`,`id`),"
" KEY `user_id_15` (`user_id`,`contest_id`,`type`,`id`),"
" KEY `user_id_16` (`user_id`,`contest_id`,`contest_problem_final`,`id`),"
// Submissions API: without user_id
" KEY `type` (`type`,`id`),"
// Submissions API: with user_id and type
" KEY `user_id_type` (`user_id`,`type`,`id`),"
" KEY `user_id_problem_final` (`user_id`,`problem_final`,`id`),"
" KEY `user_id_contest_problem_final` (`user_id`,`contest_problem_final`,`id`),"
// Submissions API: with problem_id
" KEY `problem_id` (`problem_id`,`id`),"
" KEY `contest_problem_id` (`contest_problem_id`,`id`),"
" KEY `contest_round_id` (`contest_round_id`,`id`),"
// Submissions API: with problem_id and type
" KEY `problem_id_type` (`problem_id`,`type`,`id`),"
" KEY `problem_id_problem_final` (`problem_id`,`problem_final`,`id`),"
" KEY `problem_id_contest_problem_final` (`problem_id`,`contest_problem_final`,`id`),"
// Submissions API: with problem_id and user_id
" KEY `problem_id_user_id` (`problem_id`,`user_id`,`id`),"
// Submissions API: with problem_id and user_id and type
" KEY `problem_id_user_id_type` (`problem_id`,`user_id`,`type`,`id`),"
" KEY `problem_id_user_id_problem_final` (`problem_id`,`user_id`,`problem_final`,`id`),"
" KEY `problem_id_user_id_contest_problem_final` (`problem_id`,`user_id`,`contest_problem_final`,`id`),"
// Submissions API: with contest_id
" KEY `contest_id` (`contest_id`,`id`),"
" KEY `problem_id_2` (`problem_id`,`type`,`id`),"
" KEY `contest_problem_id_2` (`contest_problem_id`,`type`,`id`),"
" KEY `contest_round_id_2` (`contest_round_id`,`type`,`id`),"
" KEY `contest_id_2` (`contest_id`,`type`,`id`),"
// Submissions API: with contest_id and type
" KEY `contest_id_type` (`contest_id`,`type`,`id`),"
// Submissions API: with contest_id and type + Contest ranking API
" KEY `contest_id_contest_problem_final` (`contest_id`,`contest_problem_final`,`id`),"
// Contest ranking API:
" KEY `contest_id_contest_problem_initial_final` (`contest_id`,`contest_problem_initial_final`,`id`),"
// Submissions API: with contest_id and user_id
" KEY `contest_id_user_id` (`contest_id`,`user_id`,`id`),"
// Submissions API: with contest_id and user_id and type
" KEY `contest_id_user_id_type` (`contest_id`,`user_id`,`type`,`id`),"
" KEY `contest_id_user_id_contest_problem_final` (`contest_id`,`user_id`,`contest_problem_final`,`id`),"
" KEY `contest_id_user_id_contest_problem_initial_final` (`contest_id`,`user_id`,`contest_problem_initial_final`,`id`),"
// Submissions API: with contest_round_id
" KEY `contest_round_id` (`contest_round_id`,`id`),"
// Submissions API: with contest_round_id and type
" KEY `contest_round_id_type` (`contest_round_id`,`type`,`id`),"
// Submissions API: with contest_round_id and type + Contest round ranking API
" KEY `contest_round_id_contest_problem_final` (`contest_round_id`,`contest_problem_final`,`id`),"
// Contest round ranking API:
" KEY `contest_round_id_contest_problem_initial_final` (`contest_round_id`,`contest_problem_initial_final`,`id`),"
// Submissions API: with contest_round_id and user_id
" KEY `contest_round_id_user_id` (`contest_round_id`,`user_id`,`id`),"
// Submissions API: with contest_round_id and user_id and type
" KEY `contest_round_id_user_id_type` (`contest_round_id`,`user_id`,`type`,`id`),"
" KEY `contest_round_id_user_id_contest_problem_final` (`contest_round_id`,`user_id`,`contest_problem_final`,`id`),"
" KEY `contest_round_id_user_id_contest_problem_initial_final` (`contest_round_id`,`user_id`,`contest_problem_initial_final`,`id`),"
// Submissions API: with contest_problem_id
" KEY `contest_problem_id` (`contest_problem_id`,`id`),"
// Submissions API: with contest_problem_id and type
" KEY `contest_problem_id_type` (`contest_problem_id`,`type`,`id`),"
// Submissions API: with contest_problem_id and type + Contest problem ranking API
" KEY `contest_problem_id_contest_problem_final` (`contest_problem_id`,`contest_problem_final`,`id`),"
// Contest problem ranking API:
" KEY `contest_problem_id_contest_problem_initial_final` (`contest_problem_id`,`contest_problem_initial_final`,`id`),"
// Submissions API: with contest_problem_id and user_id
" KEY `contest_problem_id_user_id` (`contest_problem_id`,`user_id`,`id`),"
// Submissions API: with contest_problem_id and user_id and type
" KEY `contest_problem_id_user_id_type` (`contest_problem_id`,`user_id`,`type`,`id`),"
// Submissions API: with contest_problem_id and user_id and type + contest / contest round / contest problem API: view coloring
" KEY `contest_problem_id_user_id_contest_problem_final` (`contest_problem_id`,`user_id`,`contest_problem_final`),"
" KEY `contest_problem_id_user_id_contest_problem_initial_final` (`contest_problem_id`,`user_id`,`contest_problem_initial_final`),"
// Needed to efficiently select problem final submission
" KEY `for_problem_final` (`final_candidate`,`user_id`,`problem_id`,`score` DESC,`full_status`,`id` DESC),"
// Needed to efficiently select contest problem final submission
Expand All @@ -320,15 +359,6 @@ const DbSchema& get_schema() {
" KEY `for_contest_initial_problem_final_by_initial_status` (`initial_final_candidate`,`user_id`,`contest_problem_id`,`initial_status`,`id` DESC),"
" KEY `for_contest_initial_problem_final_by_score_and_initial_status` (`initial_final_candidate`,`user_id`,`contest_problem_id`,`score` DESC,`initial_status`,`id` DESC),"
" KEY `for_contest_initial_problem_final_by_score_and_full_status` (`initial_final_candidate`,`user_id`,`contest_problem_id`,`score` DESC,`full_status`,`id` DESC),"
// Needed to efficiently query contest view coloring
" KEY `initial_final` (`user_id`,`contest_problem_id`,`contest_problem_initial_final`),"
// For ranking
" KEY `contest_final` (`contest_id`,`contest_problem_final`),"
" KEY `contest_initial_final` (`contest_id`,`contest_problem_initial_final`),"
" KEY `contest_round_final` (`contest_round_id`,`contest_problem_final`),"
" KEY `contest_initial_round_final` (`contest_round_id`,`contest_problem_initial_final`),"
" KEY `contest_problem_final` (`contest_problem_id`,`contest_problem_final`),"
" KEY `contest_initial_problem_final` (`contest_problem_id`,`contest_problem_initial_final`),"
// For foreign keys
" KEY `file_id` (`file_id`),"
" CONSTRAINT `submissions_ibfk_1` FOREIGN KEY (`file_id`) REFERENCES `internal_files` (`id`) ON UPDATE CASCADE,"
Expand Down
117 changes: 105 additions & 12 deletions subprojects/sim/src/sim_upgrader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,120 @@ run_command(const vector<string>& args, const Spawner::Options& options = {}) {

// Update the below hash and body of the function do_perform_upgrade()
constexpr StringView NORMALIZED_SCHEMA_HASH_BEFORE_UPGRADE =
"935264658c3a283d37e125526d67102dd03f4596fdfb704d970cd227c48d8bda";
"d9ec1b212056603054feaad1a606b234a361a838aa58cd21ee6b67f1f2460f9f";

static void do_perform_upgrade(
[[maybe_unused]] const string& sim_dir, [[maybe_unused]] sim::mysql::Connection& mysql
) {
STACK_UNWINDING_MARK;

// Upgrade here
mysql.execute("ALTER TABLE submissions DROP KEY contest_problem_final");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_2");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_3");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_4");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_5");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_6");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_7");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_8");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_9");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_10");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_11");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_12");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_13");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_14");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_15");
mysql.execute("ALTER TABLE submissions DROP KEY user_id_16");
mysql.execute("ALTER TABLE submissions DROP KEY problem_id_2");
mysql.execute("ALTER TABLE submissions DROP KEY contest_id_2");
mysql.execute("ALTER TABLE submissions DROP KEY contest_problem_id_2");
mysql.execute("ALTER TABLE submissions DROP KEY contest_round_id_2");
mysql.execute("ALTER TABLE submissions DROP KEY contest_final");
mysql.execute("ALTER TABLE submissions DROP KEY contest_initial_final");
mysql.execute("ALTER TABLE submissions DROP KEY contest_round_final");
mysql.execute("ALTER TABLE submissions DROP KEY contest_initial_round_final");
mysql.execute("ALTER TABLE submissions DROP KEY contest_initial_problem_final");
mysql.execute("ALTER TABLE submissions DROP KEY initial_final");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_final` (`problem_final`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_final` (`contest_id`,`contest_problem_final`)"
"ALTER TABLE submissions ADD KEY `contest_problem_final` (`contest_problem_final`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_initial_final` (`contest_id`,"
"`contest_problem_initial_final`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_round_final` (`contest_round_id`,"
"`contest_problem_final`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_initial_round_final` "
"(`contest_round_id`,`contest_problem_initial_final`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_problem_final` (`contest_problem_id`,"
"`contest_problem_final`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_initial_problem_final` "
"(`contest_problem_id`,`contest_problem_initial_final`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `user_id_problem_final` (`user_id`,`problem_final`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `user_id_contest_problem_final` "
"(`user_id`,`contest_problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `user_id_type` (`user_id`,`type`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_problem_final` "
"(`problem_id`,`problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_contest_problem_final` "
"(`problem_id`,`contest_problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_type` (`problem_id`,`type`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `problem_id_user_id` (`problem_id`,`user_id`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_user_id_problem_final` "
"(`problem_id`,`user_id`,`problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_user_id_contest_problem_final` "
"(`problem_id`,`user_id`,`contest_problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `problem_id_user_id_type` "
"(`problem_id`,`user_id`,`type`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_id_type` (`contest_id`,`type`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_id_contest_problem_final` "
"(`contest_id`,`contest_problem_final`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_id_contest_problem_initial_final` "
"(`contest_id`,`contest_problem_initial_final`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_id_user_id` (`contest_id`,`user_id`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_id_user_id_type` "
"(`contest_id`,`user_id`,`type`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_id_user_id_contest_problem_final` "
"(`contest_id`,`user_id`,`contest_problem_final`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_id_user_id_contest_problem_initial_final` "
"(`contest_id`,`user_id`,`contest_problem_initial_final`,`id`)"
);
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_round_id_type` (`contest_round_id`,`type`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_round_id_contest_problem_final` "
"(`contest_round_id`,`contest_problem_final`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_round_id_contest_problem_initial_final` "
"(`contest_round_id`,`contest_problem_initial_final`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_round_id_user_id` "
"(`contest_round_id`,`user_id`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_round_id_user_id_type` "
"(`contest_round_id`,`user_id`,`type`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_round_id_user_id_contest_problem_final` "
"(`contest_round_id`,`user_id`,`contest_problem_final`,`id`)"
);
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_round_id_user_id_contest_problem_initial_final` "
"(`contest_round_id`,`user_id`,`contest_problem_initial_final`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_problem_id_type` "
"(`contest_problem_id`,`type`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_problem_id_contest_problem_final` "
"(`contest_problem_id`,`contest_problem_final`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_problem_id_contest_problem_initial_final` "
"(`contest_problem_id`,`contest_problem_initial_final`,`id`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY `contest_problem_id_user_id` "
"(`contest_problem_id`,`user_id`,`id`)");
mysql.execute("ALTER TABLE submissions ADD KEY `contest_problem_id_user_id_type` "
"(`contest_problem_id`,`user_id`,`type`,`id`)");
mysql.execute(
"ALTER TABLE submissions ADD KEY `contest_problem_id_user_id_contest_problem_final` "
"(`contest_problem_id`,`user_id`,`contest_problem_final`)"
);
mysql.execute("ALTER TABLE submissions ADD KEY "
"`contest_problem_id_user_id_contest_problem_initial_final` "
"(`contest_problem_id`,`user_id`,`contest_problem_initial_final`)");
}

enum class LockKind {
Expand Down
Loading

0 comments on commit 7cd5c73

Please sign in to comment.