diff --git a/db/db.ddl b/db/db.ddl
index ae71eae76c401b591c1141c55d4aa1514e736f58..7d65c0583a5b6ac05c4dc699b1f555d578a324f5 100644
--- a/db/db.ddl
+++ b/db/db.ddl
@@ -95,18 +95,25 @@ CREATE TABLE rounds (
seq int NOT NULL, -- 1=domácí kolo atd.
level int NOT NULL, -- úroveň hierarchie míst
name varchar(255) NOT NULL, -- zobrazované jméno ("Krajské kolo" apod.)
- state round_state NOT NULL DEFAULT 'preparing', -- stav kola
- tasks_file varchar(255) DEFAULT NULL, -- jméno souboru se zadáním úloh
- ct_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy účastníci vidí zadání
- ct_submit_end timestamp with time zone DEFAULT NULL, -- do kdy účastníci mohou regulérně odevzdávat
- pr_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy dozor vidí zadání
- pr_submit_end timestamp with time zone DEFAULT NULL, -- do kdy dozor může regulérně odevzdávat
+ -- termíny, odkaz na zadání a stav odsunuty do round_parts, vždy bude existovat alespoň 1 instance pro kolo
score_mode score_mode NOT NULL DEFAULT 'basic', -- mód výsledkovky
score_winner_limit int DEFAULT NULL, -- bodový limit na označení za vítěze
score_successful_limit int DEFAULT NULL, -- bodový limit na označení za úspěšného řešitele
UNIQUE (year, category, seq)
);
+CREATE TABLE round_parts (
+ round_part_id serial PRIMARY KEY,
+ round_id int NOT NULL REFERENCES rounds(round_id),
+ name varchar(255) NOT NULL, -- jméno části ("I", "1. den" apod.)
+ state round_state NOT NULL DEFAULT 'preparing', -- stav části kola
+ tasks_file varchar(255) DEFAULT NULL, -- jméno souboru se zadáním úloh
+ ct_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy účastníci vidí zadání
+ ct_submit_end timestamp with time zone DEFAULT NULL, -- do kdy účastníci mohou regulérně odevzdávat
+ pr_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy dozor vidí zadání
+ pr_submit_end timestamp with time zone DEFAULT NULL -- do kdy dozor může regulérně odevzdávat
+);
+
-- Soutěže (instance kola v konkrétním místě)
CREATE TABLE contests (
contest_id serial PRIMARY KEY,
@@ -150,6 +157,7 @@ CREATE INDEX participations_contest_id_index ON participations (contest_id, plac
CREATE TABLE tasks (
task_id serial PRIMARY KEY,
round_id int NOT NULL REFERENCES rounds(round_id),
+ round_part_id int DEFAULT NULL REFERENCES round_parts(round_part_id), -- pokud pro úlohu mají platit jiné termíny
code varchar(255) NOT NULL, -- např. "P-I-1"
name varchar(255) NOT NULL,
UNIQUE (round_id, code)
diff --git a/db/upgrade-20210304.sql b/db/upgrade-20210304.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f400ad14a4d2501e2503cc43c1047eef506000d9
--- /dev/null
+++ b/db/upgrade-20210304.sql
@@ -0,0 +1,35 @@
+SET ROLE 'mo_osmo';
+
+CREATE TABLE round_parts (
+ round_part_id serial PRIMARY KEY,
+ round_id int NOT NULL REFERENCES rounds(round_id),
+ name varchar(255) NOT NULL, -- jméno části ("I", "1. den" apod.)
+ -- tato část je identická s částí tabulky rounds
+ state round_state NOT NULL DEFAULT 'preparing', -- stav části kola
+ tasks_file varchar(255) DEFAULT NULL, -- jméno souboru se zadáním úloh
+ ct_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy účastníci vidí zadání
+ ct_submit_end timestamp with time zone DEFAULT NULL, -- do kdy účastníci mohou regulérně odevzdávat
+ pr_tasks_start timestamp with time zone DEFAULT NULL, -- od kdy dozor vidí zadání
+ pr_submit_end timestamp with time zone DEFAULT NULL -- do kdy dozor může regulérně odevzdávat
+);
+
+ALTER TABLE tasks
+ ADD COLUMN round_part_id int DEFAULT NULL REFERENCES round_parts(round_part_id);
+
+-- v tuhle chvíli je potřeba provést migraci dat z tabulek rounds do round_parts
+INSERT INTO round_parts (round_id, name, state, tasks_file, ct_tasks_start, ct_submit_end, pr_tasks_start, pr_submit_end)
+ SELECT round_id, 'default', state, tasks_file, ct_tasks_start, ct_submit_end, pr_tasks_start, pr_submit_end FROM rounds;
+
+-- a update všech úloh, aby obsahovaly odkaz na právě vytvořené round_parts (existuje právě jedna pro kolo)
+UPDATE tasks SET round_part_id=subquery.round_part_id
+ FROM (SELECT round_part_id, round_id FROM round_parts) AS subquery
+ WHERE subquery.round_id=tasks.round_id;
+
+-- odstranění sloupců z rounds (spouštět s opatrností po ověření, že vše funguje!)
+-- ALTER TABLE rounds
+-- DROP COLUMN state,
+-- DROP COLUMN tasks_file,
+-- DROP COLUMN ct_tasks_start,
+-- DROP COLUMN ct_submit_end,
+-- DROP COLUMN pr_tasks_start,
+-- DROP COLUMN pr_submit_end;
diff --git a/mo/db.py b/mo/db.py
index 95184e96b0eb92f939fdc8199f61aa3407b3dc29..4c1ed53f34e71974b88a0ec2c5b14e3109c16290 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -203,18 +203,30 @@ class Round(Base):
seq = Column(Integer, nullable=False)
level = Column(Integer, nullable=False)
name = Column(String(255), nullable=False)
+ score_mode = Column(Enum(RoundScoreMode, name='score_mode'), nullable=False, server_default=text("'basic'::score_mode"))
+ score_winner_limit = Column(Integer)
+ score_successful_limit = Column(Integer)
+
+ parts = relationship('RoundPart', primaryjoin='RoundPart.round_id == Round.round_id')
+
+ def round_code(self):
+ return f"{self.year}-{self.category}-{self.seq}"
+
+
+class RoundPart(Base):
+ __tablename__ = 'round_parts'
+
+ round_part_id = Column(Integer, primary_key=True, server_default=text("nextval('round_parts_round_part_id_seq'::regclass)"))
+ round_id = Column(Integer, ForeignKey('rounds.round_id'), nullable=False)
+ name = Column(String(255), nullable=False)
state = Column(Enum(RoundState, name='round_state'), nullable=False, server_default=text("'preparing'::round_state"))
tasks_file = Column(String(255))
ct_tasks_start = Column(DateTime(True))
ct_submit_end = Column(DateTime(True))
pr_tasks_start = Column(DateTime(True))
pr_submit_end = Column(DateTime(True))
- score_mode = Column(Enum(RoundScoreMode, name='score_mode'), nullable=False, server_default=text("'basic'::score_mode"))
- score_winner_limit = Column(Integer)
- score_successful_limit = Column(Integer)
- def round_code(self):
- return f"{self.year}-{self.category}-{self.seq}"
+ round = relationship('Round', primaryjoin='RoundPart.round_id == Round.round_id')
def has_tasks(self):
return self.tasks_file
@@ -369,10 +381,12 @@ class Task(Base):
task_id = Column(Integer, primary_key=True, server_default=text("nextval('tasks_task_id_seq'::regclass)"))
round_id = Column(Integer, ForeignKey('rounds.round_id'), nullable=False)
+ round_part_id = Column(Integer, ForeignKey('round_parts.round_part_id'), nullable=False)
code = Column(String(255), nullable=False)
name = Column(String(255), nullable=False)
round = relationship('Round')
+ round_part = relationship('RoundPart')
class RoleType(MOEnum):