-
Notifications
You must be signed in to change notification settings - Fork 278
Use external ID in UI everywhere instead of internal database ID #3263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
821b1b8
64de025
31b5d06
f09e488
6371dc7
3c8895d
75e1799
fefba55
ea354b6
2c22819
d01e393
e1970f3
b510a51
7fb7b92
15fccb6
5222b7a
b3f4661
1a12659
38f2975
6702b9c
d590c34
02bd5cb
2d9333d
dd0d6dd
928befb
c2121c5
2a97bfd
7368c00
290fa58
13b1945
3960c35
7ff7b0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -624,7 +624,7 @@ | |
|
|
||
| private function judgingDirectory(string $workdirpath, array $judgeTask): string | ||
| { | ||
| if (filter_var($judgeTask['submitid'], FILTER_VALIDATE_INT) === false || | ||
| if (filter_var($judgeTask['submitid'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-zA-Z0-9_.-]+$/']]) === false || | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we define this somewhere more generally?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, what do submission URLs look like after this change? |
||
| filter_var($judgeTask['jobid'], FILTER_VALIDATE_INT) === false) { | ||
| error("Malformed data returned in judgeTask IDs: " . var_export($judgeTask, true)); | ||
| } | ||
|
|
@@ -857,7 +857,7 @@ | |
| return trim(ob_get_clean()); | ||
| } | ||
|
|
||
| private function runCommandSafe(array $command_parts, & $retval = DONT_CARE, $log_nonzero_exitcode = true): bool | ||
| { | ||
| if (empty($command_parts)) { | ||
| logmsg(LOG_WARNING, "Need at least the command that should be called."); | ||
|
|
@@ -869,7 +869,7 @@ | |
|
|
||
| logmsg(LOG_DEBUG, "Executing command: $command"); | ||
| system($command, $retval_local); | ||
| if ($retval !== DONT_CARE) $retval = $retval_local; | ||
|
|
||
| if ($retval_local !== 0) { | ||
| if ($log_nonzero_exitcode) { | ||
|
|
@@ -889,7 +889,7 @@ | |
| int $judgeTaskId, | ||
| bool $combined_run_compare = false | ||
| ): array | ||
| { | ||
| [$execrunpath, $error, $buildlogpath] = $this->fetchExecutableInternal($workdirpath, $type, $execid, $hash, $combined_run_compare); | ||
| if (isset($error)) { | ||
| $extra_log = null; | ||
|
|
@@ -918,7 +918,7 @@ | |
| string $hash, | ||
| bool $combined_run_compare = false | ||
| ): array | ||
| { | ||
| $execdir = join('/', [ | ||
| $workdirpath, | ||
| 'executable', | ||
|
|
@@ -1123,12 +1123,12 @@ | |
| private function disable( | ||
| string $kind, | ||
| string $idcolumn, | ||
| $id, | ||
| string $description, | ||
| ?int $judgeTaskId = null, | ||
| ?string $extra_log = null | ||
| ): void | ||
| { | ||
| $disabled = dj_json_encode(['kind' => $kind, $idcolumn => $id]); | ||
| $judgehostlog = $this->readJudgehostLog(); | ||
| if (isset($extra_log)) { | ||
|
|
@@ -1198,7 +1198,7 @@ | |
| ?string $daemonid, | ||
| int $output_storage_limit | ||
| ): bool | ||
| { | ||
| // Reuse compilation if it already exists. | ||
| if (file_exists("$workdir/compile.success")) { | ||
| return true; | ||
|
|
@@ -1289,7 +1289,7 @@ | |
|
|
||
| // Revoke readablity for domjudge-run user to this workdir. | ||
| chmod($workdir, 0700); | ||
| logmsg(LOG_NOTICE, "Judging s$judgeTask[submitid], task $judgeTask[judgetaskid]: compile error"); | ||
| logmsg(LOG_NOTICE, "Judging $judgeTask[submitid], task $judgeTask[judgetaskid]: compile error"); | ||
| return false; | ||
| } | ||
|
|
||
|
|
@@ -1353,7 +1353,7 @@ | |
| // What does the exitcode mean? | ||
| if (!isset($this->EXITCODES[$retval])) { | ||
| alert('error'); | ||
| $description = "Unknown exitcode from compile.sh for s$judgeTask[submitid]: $retval"; | ||
| $description = "Unknown exitcode from compile.sh for $judgeTask[submitid]: $retval"; | ||
| logmsg(LOG_ERR, $description); | ||
| $this->disable('compile_script', 'compile_script_id', $judgeTask['compile_script_id'], $description, $judgeTask['judgetaskid'], $compile_output); | ||
|
|
||
|
|
@@ -1568,7 +1568,7 @@ | |
| // What does the exitcode mean? | ||
| if (!isset($this->EXITCODES[$retval])) { | ||
| alert('error'); | ||
| error("Unknown exitcode ($retval) from testcase_run.sh for s$judgeTask[submitid]"); | ||
| error("Unknown exitcode ($retval) from testcase_run.sh for $judgeTask[submitid]"); | ||
| } | ||
| $result = $this->EXITCODES[$retval]; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace DoctrineMigrations; | ||
|
|
||
| use Doctrine\DBAL\Schema\Schema; | ||
| use Doctrine\Migrations\AbstractMigration; | ||
|
|
||
| /** | ||
| * Auto-generated Migration: Please modify to your needs! | ||
| */ | ||
| final class Version20251024122021 extends AbstractMigration | ||
| { | ||
| public function getDescription(): string | ||
| { | ||
| return 'Change language ID to be an auto increment integer'; | ||
| } | ||
|
|
||
| public function up(Schema $schema): void | ||
| { | ||
| // We need to do some juggling to get this to work: | ||
| // - First we drop the foreign keys from tables referencing langid. We also drop compound | ||
| // - Then we add a temporary integer langid column to all these tables, since we can't | ||
| // change the langid column itself, because MySQL will try to convert the strings to | ||
| // integers and fail. We set the langid column in the language table to auto increment, | ||
| // so it's filled by MySQL. | ||
| // - Now we copy the langid_int values to other tables. | ||
| // - Then we drop the old langid columns and drop any (compound) primary keys that use it. | ||
| // - Next, we rename the langid_int columns back to langid. | ||
| // - Finally we add back all primary and foreign keys. | ||
|
|
||
| $this->addSql('ALTER TABLE submission DROP FOREIGN KEY submission_ibfk_4'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP FOREIGN KEY FK_46B150BB2271845'); | ||
| $this->addSql('ALTER TABLE version DROP FOREIGN KEY FK_BF1CD3C32271845'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP FOREIGN KEY FK_ADCB43232271845'); | ||
|
|
||
| $this->addSql('ALTER TABLE language ADD langid_int INT UNSIGNED AUTO_INCREMENT UNIQUE AFTER langid'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD langid_int INT UNSIGNED NOT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD langid_int INT UNSIGNED NOT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE submission ADD langid_int INT UNSIGNED DEFAULT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE version ADD langid_int INT UNSIGNED DEFAULT NULL AFTER langid'); | ||
|
|
||
| $this->addSql('UPDATE contestlanguage c JOIN language l ON c.langid = l.langid SET c.langid_int = l.langid_int'); | ||
| $this->addSql('UPDATE problemlanguage p JOIN language l ON p.langid = l.langid SET p.langid_int = l.langid_int'); | ||
| $this->addSql('UPDATE submission s JOIN language l ON s.langid = l.langid SET s.langid_int = l.langid_int WHERE s.langid IS NOT NULL'); | ||
| $this->addSql('UPDATE version v JOIN language l ON v.langid = l.langid SET v.langid_int = l.langid_int WHERE v.langid IS NOT NULL'); | ||
| $this->addSql('UPDATE auditlog a JOIN language l ON a.dataid = l.langid AND a.datatype = "language" SET a.dataid = l.langid_int WHERE a.dataid IS NOT NULL'); | ||
|
|
||
| $this->addSql('ALTER TABLE language DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE language DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE submission DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE version DROP COLUMN langid'); | ||
|
|
||
| $this->addSql('ALTER TABLE language CHANGE langid_int langid INT UNSIGNED AUTO_INCREMENT NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE contestlanguage CHANGE langid_int langid INT UNSIGNED NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE problemlanguage CHANGE langid_int langid INT UNSIGNED NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE submission CHANGE langid_int langid INT UNSIGNED DEFAULT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE version CHANGE langid_int langid INT UNSIGNED DEFAULT NULL COMMENT \'Language ID\''); | ||
|
|
||
| $this->addSql('ALTER TABLE language ADD PRIMARY KEY (langid), DROP INDEX langid_int'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD PRIMARY KEY (cid, langid)'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD PRIMARY KEY (probid, langid)'); | ||
|
|
||
| $this->addSql('ALTER TABLE submission ADD INDEX langid (langid), ADD CONSTRAINT submission_ibfk_4 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD INDEX IDX_46B150BB2271845 (langid), ADD CONSTRAINT FK_46B150BB2271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE version ADD INDEX IDX_BF1CD3C32271845 (langid), ADD CONSTRAINT FK_BF1CD3C32271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD INDEX IDX_ADCB43232271845 (langid), ADD CONSTRAINT FK_ADCB43232271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| } | ||
|
|
||
| public function down(Schema $schema): void | ||
| { | ||
| // When migrating back, we do the logic in reverse but we have custom logic for setting | ||
| // the string langid. We set it to the external ID except for a set of 10 known languages | ||
| // where the external ID differs from our previously used langid. | ||
|
|
||
| $this->addSql('ALTER TABLE submission DROP FOREIGN KEY submission_ibfk_4'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP FOREIGN KEY FK_46B150BB2271845'); | ||
| $this->addSql('ALTER TABLE version DROP FOREIGN KEY FK_BF1CD3C32271845'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP FOREIGN KEY FK_ADCB43232271845'); | ||
|
|
||
| $this->addSql('ALTER TABLE language ADD langid_str VARCHAR(32) NOT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD langid_str VARCHAR(32) NOT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD langid_str VARCHAR(32) NOT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE submission ADD langid_str VARCHAR(32) DEFAULT NULL AFTER langid'); | ||
| $this->addSql('ALTER TABLE version ADD langid_str VARCHAR(32) DEFAULT NULL AFTER langid'); | ||
|
|
||
| $this->addSql("UPDATE language SET langid_str = CASE externalid | ||
| WHEN 'ada' THEN 'adb' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. huh, ada -> adb? Is that what you want? |
||
| WHEN 'haskell' THEN 'hs' | ||
| WHEN 'javascript' THEN 'js' | ||
| WHEN 'kotlin' THEN 'kt' | ||
| WHEN 'pascal' THEN 'pas' | ||
| WHEN 'prolog' THEN 'plg' | ||
| WHEN 'python3' THEN 'py3' | ||
| WHEN 'python2' THEN 'py2' | ||
| WHEN 'ruby' THEN 'rb' | ||
| WHEN 'rust' THEN 'rs' | ||
| ELSE externalid | ||
| END"); | ||
|
|
||
| $this->addSql('UPDATE contestlanguage c JOIN language l ON c.langid = l.langid SET c.langid_str = l.langid_str'); | ||
| $this->addSql('UPDATE problemlanguage p JOIN language l ON p.langid = l.langid SET p.langid_str = l.langid_str'); | ||
| $this->addSql('UPDATE submission s JOIN language l ON s.langid = l.langid SET s.langid_str = l.langid_str WHERE s.langid IS NOT NULL'); | ||
| $this->addSql('UPDATE version v JOIN language l ON v.langid = l.langid SET v.langid_str = l.langid_str WHERE v.langid IS NOT NULL'); | ||
| $this->addSql('UPDATE auditlog a JOIN language l ON a.dataid = l.langid AND a.datatype = "language" SET a.dataid = l.langid_str WHERE a.dataid IS NOT NULL'); | ||
|
|
||
| $this->addSql('ALTER TABLE language DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE language DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE contestlanguage DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP PRIMARY KEY'); | ||
| $this->addSql('ALTER TABLE problemlanguage DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE submission DROP COLUMN langid'); | ||
| $this->addSql('ALTER TABLE version DROP COLUMN langid'); | ||
|
|
||
| $this->addSql('ALTER TABLE language CHANGE langid_str langid VARCHAR(32) NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE contestlanguage CHANGE langid_str langid VARCHAR(32) NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE problemlanguage CHANGE langid_str langid VARCHAR(32) NOT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE submission CHANGE langid_str langid VARCHAR(32) DEFAULT NULL COMMENT \'Language ID\''); | ||
| $this->addSql('ALTER TABLE version CHANGE langid_str langid VARCHAR(32) DEFAULT NULL COMMENT \'Language ID\''); | ||
|
|
||
| $this->addSql('ALTER TABLE language ADD PRIMARY KEY (langid)'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD PRIMARY KEY (cid, langid)'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD PRIMARY KEY (probid, langid)'); | ||
|
|
||
| $this->addSql('ALTER TABLE submission ADD INDEX langid (langid), ADD CONSTRAINT submission_ibfk_4 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE problemlanguage ADD INDEX IDX_46B150BB2271845 (langid), ADD CONSTRAINT FK_46B150BB2271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE version ADD INDEX IDX_BF1CD3C32271845 (langid), ADD CONSTRAINT FK_BF1CD3C32271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| $this->addSql('ALTER TABLE contestlanguage ADD INDEX IDX_ADCB43232271845 (langid), ADD CONSTRAINT FK_ADCB43232271845 FOREIGN KEY (langid) REFERENCES language (langid) ON DELETE CASCADE'); | ||
| } | ||
|
|
||
| public function isTransactional(): bool | ||
| { | ||
| return false; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace DoctrineMigrations; | ||
|
|
||
| use Doctrine\DBAL\Schema\Schema; | ||
| use Doctrine\Migrations\AbstractMigration; | ||
| use phpDocumentor\Reflection\Types\Static_; | ||
|
|
||
| final class Version20251026092516 extends AbstractMigration | ||
| { | ||
| protected const ENTITIES = [ | ||
| 'clarification' => 'clarid', | ||
| 'contest' => 'cid', | ||
| 'language' => 'langid', | ||
| 'problem' => 'probid', | ||
| 'submission' => 'submitid', | ||
| 'team' => 'teamid', | ||
| 'team_affiliation' => 'affilid', | ||
| 'team_category' => 'categoryid', | ||
| 'user' => ['userid', 'username'], | ||
| ]; | ||
|
|
||
| public function getDescription(): string | ||
| { | ||
| return 'Make auditlog IDs reference external IDs'; | ||
| } | ||
|
|
||
| public function up(Schema $schema): void | ||
| { | ||
| // Note: this migration only works for entities that still exist. For others, it will not work but there is nothing we can do | ||
| $this->addSql('ALTER TABLE auditlog CHANGE cid cid VARCHAR(255) DEFAULT NULL COMMENT \'External contest ID associated to this entry\', CHANGE dataid dataid VARCHAR(64) DEFAULT NULL COMMENT \'(External) identifier in reference table\''); | ||
| $this->addSql('UPDATE auditlog INNER JOIN contest ON CAST(contest.cid AS CHAR) = auditlog.cid SET auditlog.cid = contest.externalid'); | ||
| foreach (static::ENTITIES as $table => $fields) { | ||
| if (!is_array($fields)) { | ||
| $fields = [$fields]; | ||
| } | ||
| foreach ($fields as $field) { | ||
| $this->addSql(sprintf( | ||
| 'UPDATE auditlog INNER JOIN %s ON CAST(%s.%s AS CHAR) = auditlog.dataid AND auditlog.datatype = "%s" SET auditlog.dataid = %s.externalid', | ||
| $table, $table, $field, $table, $table | ||
| )); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public function down(Schema $schema): void | ||
| { | ||
| // Note: this migration only works for entities that still exist. For others, it will not work but there is nothing we can do | ||
| $this->addSql('UPDATE auditlog INNER JOIN contest ON contest.externalid = auditlog.cid SET auditlog.cid = contest.cid'); | ||
| foreach (static::ENTITIES as $table => $fields) { | ||
| $field = is_array($fields) ? $fields[0] : $fields; | ||
| $this->addSql(sprintf( | ||
| 'UPDATE auditlog INNER JOIN %s ON %s.externalid = auditlog.dataid AND auditlog.datatype = "%s" SET auditlog.dataid = %s.%s', | ||
| $table, $table, $table, $table, $field | ||
| )); | ||
| } | ||
| $this->addSql('ALTER TABLE auditlog CHANGE cid cid INT UNSIGNED DEFAULT NULL COMMENT \'Contest ID associated to this entry\', CHANGE dataid dataid VARCHAR(64) DEFAULT NULL COMMENT \'Identifier in reference table\''); | ||
| } | ||
|
|
||
| public function isTransactional(): bool | ||
| { | ||
| return false; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might deserve a changelog entry :-)