Skip to content

Commit 831efc9

Browse files
committed
Prepare the database for the output
1 parent 488267d commit 831efc9

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20251117185929 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return '';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{
22+
// this up() migration is auto-generated, please modify it to your needs
23+
$this->addSql('CREATE TABLE generic_task (taskid INT UNSIGNED AUTO_INCREMENT NOT NULL COMMENT \'Task ID\', judgetaskid INT UNSIGNED DEFAULT NULL COMMENT \'JudgeTask ID\', runtime DOUBLE PRECISION DEFAULT NULL COMMENT \'Running time for this task\', endtime NUMERIC(32, 9) UNSIGNED DEFAULT NULL COMMENT \'Time task ended\', start_time NUMERIC(32, 9) UNSIGNED DEFAULT NULL COMMENT \'Time task started\', INDEX IDX_680437B63CBA64F2 (judgetaskid), PRIMARY KEY(taskid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Result of a generic task\' ');
24+
$this->addSql('CREATE TABLE generic_task_output (taskid INT UNSIGNED NOT NULL COMMENT \'Task ID\', output_task LONGBLOB DEFAULT NULL COMMENT \'Output of running the program(DC2Type:blobtext)\', output_error LONGBLOB DEFAULT NULL COMMENT \'Standard error output of the program(DC2Type:blobtext)\', INDEX taskid (taskid), PRIMARY KEY(taskid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Stores output of generic task\' ');
25+
$this->addSql('ALTER TABLE generic_task ADD CONSTRAINT FK_680437B63CBA64F2 FOREIGN KEY (judgetaskid) REFERENCES judgetask (judgetaskid) ON DELETE CASCADE');
26+
$this->addSql('ALTER TABLE generic_task_output ADD CONSTRAINT FK_6425C7BE46CBEE95 FOREIGN KEY (taskid) REFERENCES generic_task (taskid) ON DELETE CASCADE');
27+
}
28+
29+
public function down(Schema $schema): void
30+
{
31+
// this down() migration is auto-generated, please modify it to your needs
32+
$this->addSql('ALTER TABLE generic_task DROP FOREIGN KEY FK_680437B63CBA64F2');
33+
$this->addSql('ALTER TABLE generic_task_output DROP FOREIGN KEY FK_6425C7BE46CBEE95');
34+
$this->addSql('DROP TABLE generic_task');
35+
$this->addSql('DROP TABLE generic_task_output');
36+
}
37+
38+
public function isTransactional(): bool
39+
{
40+
return false;
41+
}
42+
}

webapp/src/Controller/Jury/JudgehostController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ private function helperGenericTask(string $execid, ?JudgeHost $judgehost = null)
342342
$judgeTask = new JudgeTask();
343343
$judgeTask
344344
->setType(JudgeTaskType::GENERIC_TASK)
345+
->setJudgehost($judgehost)
345346
->setPriority(JudgeTask::PRIORITY_HIGH)
346347
->setRunScriptId($executable->getImmutableExecId())
347348
->setRunConfig(Utils::jsonEncode(['hash' => $executable->getHash()]));

webapp/src/Entity/GenericTask.php

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<?php declare(strict_types=1);
2+
namespace App\Entity;
3+
4+
use App\Utils\Utils;
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
use Doctrine\Common\Collections\Collection;
7+
use Doctrine\ORM\Mapping as ORM;
8+
use JMS\Serializer\Annotation as Serializer;
9+
10+
/**
11+
* Result of a generic task.
12+
*/
13+
#[ORM\Entity]
14+
#[ORM\Table(options: [
15+
'collation' => 'utf8mb4_unicode_ci',
16+
'charset' => 'utf8mb4',
17+
'comment' => 'Result of a generic task',
18+
])]
19+
class GenericTask extends BaseApiEntity
20+
{
21+
#[ORM\Id]
22+
#[ORM\GeneratedValue]
23+
#[ORM\Column(options: ['comment' => 'Task ID', 'unsigned' => true])]
24+
#[Serializer\SerializedName('id')]
25+
#[Serializer\Type('string')]
26+
protected int $taskid;
27+
28+
#[ORM\Column(
29+
nullable: true,
30+
options: ['comment' => 'JudgeTask ID', 'unsigned' => true, 'default' => null]
31+
)]
32+
#[Serializer\Exclude]
33+
private ?int $judgetaskid = null;
34+
35+
#[ORM\Column(
36+
nullable: true,
37+
options: ['comment' => 'Running time for this task']
38+
)]
39+
#[Serializer\Exclude]
40+
private string|float|null $runtime = null;
41+
42+
#[ORM\Column(
43+
type: 'decimal',
44+
precision: 32,
45+
scale: 9,
46+
nullable: true,
47+
options: ['comment' => 'Time task ended', 'unsigned' => true]
48+
)]
49+
#[Serializer\Exclude]
50+
private string|float|null $endtime = null;
51+
52+
#[ORM\Column(
53+
type: 'decimal',
54+
precision: 32,
55+
scale: 9,
56+
nullable: true,
57+
options: ['comment' => 'Time task started', 'unsigned' => true]
58+
)]
59+
#[Serializer\Exclude]
60+
private string|float|null $startTime = null;
61+
62+
/**
63+
* @var Collection<int, JudgingRunOutput>
64+
*
65+
* We use a OneToMany instead of a OneToOne here, because otherwise this
66+
* relation will always be loaded. See the commit message of commit
67+
* 9e421f96691ec67ed62767fe465a6d8751edd884 for a more elaborate explanation
68+
*/
69+
#[ORM\OneToMany(mappedBy: 'run', targetEntity: GenericTaskOutput::class, cascade: ['persist'], orphanRemoval: true)]
70+
#[Serializer\Exclude]
71+
private Collection $output;
72+
73+
#[ORM\ManyToOne(inversedBy: 'judging_runs')]
74+
#[ORM\JoinColumn(name: 'judgetaskid', referencedColumnName: 'judgetaskid', onDelete: 'CASCADE')]
75+
#[Serializer\Exclude]
76+
private ?JudgeTask $judgetask = null;
77+
78+
public function __construct()
79+
{
80+
$this->output = new ArrayCollection();
81+
}
82+
83+
public function getTaskid(): int
84+
{
85+
return $this->taskid;
86+
}
87+
88+
public function setJudgeTaskId(int $judgetaskid): GenericTask
89+
{
90+
$this->judgetaskid = $judgetaskid;
91+
return $this;
92+
}
93+
94+
public function getJudgeTaskId(): ?int
95+
{
96+
return $this->judgetaskid;
97+
}
98+
99+
public function getJudgeTask(): ?JudgeTask
100+
{
101+
return $this->judgetask;
102+
}
103+
104+
public function setJudgeTask(JudgeTask $judgeTask): GenericTask
105+
{
106+
$this->judgetask = $judgeTask;
107+
return $this;
108+
}
109+
110+
public function setRuntime(string|float $runtime): GenericTask
111+
{
112+
$this->runtime = $runtime;
113+
return $this;
114+
}
115+
116+
#[Serializer\VirtualProperty]
117+
#[Serializer\SerializedName('run_time')]
118+
#[Serializer\Type('float')]
119+
public function getRuntime(): string|float|null
120+
{
121+
return Utils::roundedFloat($this->runtime);
122+
}
123+
124+
public function setEndtime(string|float $endtime): GenericTask
125+
{
126+
$this->endtime = $endtime;
127+
return $this;
128+
}
129+
130+
public function setStarttime(string|float $startTime): GenericTask
131+
{
132+
$this->startTime = $startTime;
133+
return $this;
134+
}
135+
136+
public function getStarttime(): string|float|null
137+
{
138+
return $this->startTime;
139+
}
140+
141+
public function getEndtime(): string|float|null
142+
{
143+
return $this->endtime;
144+
}
145+
146+
#[Serializer\VirtualProperty]
147+
#[Serializer\SerializedName('time')]
148+
#[Serializer\Type('string')]
149+
public function getAbsoluteEndTime(): string
150+
{
151+
return Utils::absTime($this->getEndtime());
152+
}
153+
154+
public function setOutput(GenericTaskOutput $output): GenericTask
155+
{
156+
$this->output->clear();
157+
$this->output->add($output);
158+
$output->setRun($this);
159+
160+
return $this;
161+
}
162+
163+
public function getOutput(): ?GenericTaskOutput
164+
{
165+
return $this->output->first() ?: null;
166+
}
167+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
/**
8+
* Output of a generic task.
9+
*/
10+
#[ORM\Entity]
11+
#[ORM\Table(options: [
12+
'collation' => 'utf8mb4_unicode_ci',
13+
'charset' => 'utf8mb4',
14+
'comment' => 'Stores output of generic task',
15+
])]
16+
#[ORM\Index(columns: ['taskid'], name: 'taskid')]
17+
class GenericTaskOutput
18+
{
19+
/**
20+
* We use a ManyToOne instead of a OneToOne here, because otherwise the
21+
* reverse of this relation will always be loaded. See the commit message of commit
22+
* 9e421f96691ec67ed62767fe465a6d8751edd884 for a more elaborate explanation
23+
*/
24+
#[ORM\Id]
25+
#[ORM\ManyToOne(inversedBy: 'output')]
26+
#[ORM\JoinColumn(name: 'taskid', referencedColumnName: 'taskid', onDelete: 'CASCADE')]
27+
private GenericTask $task;
28+
29+
#[ORM\Column(
30+
type: 'blobtext',
31+
nullable: true,
32+
options: ['comment' => 'Output of running the program']
33+
)]
34+
private ?string $output_task = null;
35+
36+
#[ORM\Column(
37+
type: 'blobtext',
38+
nullable: true,
39+
options: ['comment' => 'Standard error output of the program']
40+
)]
41+
private ?string $output_error = null;
42+
43+
public function setGenericTask(GenericTask $task): GenericTaskOutput
44+
{
45+
$this->task = $task;
46+
return $this;
47+
}
48+
49+
public function getGenericTask(): GenericTask
50+
{
51+
return $this->task;
52+
}
53+
54+
public function setOutputTask(?string $outputTask): GenericTaskOutput
55+
{
56+
$this->output_task = $outputTask;
57+
return $this;
58+
}
59+
60+
public function getOutputTask(): string
61+
{
62+
return $this->output_task;
63+
}
64+
65+
public function setOutputError(string $outputError): GenericTaskOutput
66+
{
67+
$this->output_error = $outputError;
68+
return $this;
69+
}
70+
71+
public function getOutputError(): string
72+
{
73+
return $this->output_error;
74+
}
75+
}

webapp/src/Entity/JudgeTask.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public function getSubmitid(): ?int
169169
public function __construct()
170170
{
171171
$this->judging_runs = new ArrayCollection();
172+
$this->generic_tasks = new ArrayCollection();
172173
}
173174

174175
public function getJudgetaskid(): int
@@ -375,6 +376,20 @@ public function getJudgingRuns(): Collection
375376
return $this->judging_runs;
376377
}
377378

379+
public function addGenericTask(GenericTask $genericTask): GenericTask
380+
{
381+
$this->generic_tasks[] = $genericTask;
382+
return $this;
383+
}
384+
385+
/**
386+
* @return Collection<int, GenericTask>
387+
*/
388+
public function getGenericTasks(): Collection
389+
{
390+
return $this->generic_tasks;
391+
}
392+
378393
/**
379394
* Gets the first judging run for this judgetask.
380395
*

0 commit comments

Comments
 (0)