From c75139ba2f67709c0925e82d0ccedf186f7ce76f Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sun, 10 Jan 2021 20:21:18 +0100
Subject: [PATCH] =?UTF-8?q?DB:=20Tabulka=20pro=20asynchronn=C3=AD=20=C3=BA?=
 =?UTF-8?q?lohy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 db/db.ddl | 30 +++++++++++++++++++++++++++++-
 mo/db.py  | 31 +++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/db/db.ddl b/db/db.ddl
index 31617961..418019ce 100644
--- a/db/db.ddl
+++ b/db/db.ddl
@@ -225,4 +225,32 @@ CREATE TABLE log (
 	details		jsonb		NOT NULL					-- detaily (závislé na typu)
 );
 
--- FIXME: Indexy
+-- Asynchronní úlohy
+
+CREATE TYPE job_type AS ENUM (
+	'download_submits',
+	'upload_feedback'
+);
+
+CREATE TYPE job_state AS ENUM (
+	'ready',
+	'running',
+	'done',				-- Hotovo, out_json a out_file jsou platné
+	'failed'			-- Interní chyba při zpracování, viz log
+);
+
+CREATE TABLE jobs (
+	job_id		serial		PRIMARY KEY,
+	type		job_type	NOT NULL,
+	state		job_state	NOT NULL,
+	user_id		int		NOT NULL REFERENCES users(user_id),			-- komu patří
+	created_at	timestamp with time zone	NOT NULL DEFAULT CURRENT_TIMESTAMP,	-- kdy byl založen
+	finished_at	timestamp with time zone	DEFAULT NULL,				-- kdy doběhl
+	expires_at	timestamp with time zone	DEFAULT NULL,				-- kdy bude automaticky smazán
+	description	text		NOT NULL DEFAULT '',
+	in_json		jsonb		DEFAULT NULL,
+	out_json	jsonb		DEFAULT NULL,
+	-- Soubory jsou součástí úlohy a po jejím ukončení budou smazány
+	in_file		varchar(255)	DEFAULT NULL,
+	out_file	varchar(255)	DEFAULT NULL
+);
diff --git a/mo/db.py b/mo/db.py
index e382be0f..3583a27f 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -459,6 +459,37 @@ class Solution(Base):
     user = relationship('User')
 
 
+class JobType(MOEnum):
+    download_submits = auto()
+    upload_feedback = auto()
+
+
+class JobState(MOEnum):
+    ready = auto()
+    running = auto()
+    done = auto()
+    failed = auto()
+
+
+class Job(Base):
+    __tablename__ = 'jobs'
+
+    job_id = Column(Integer, primary_key=True, server_default=text("nextval('jobs_job_id_seq'::regclass)"))
+    type = Column(Enum(JobType, name='job_type'), nullable=False)
+    state = Column(Enum(JobState, name='job_state'), nullable=False)
+    user_id = Column(Integer, ForeignKey('users.user_id'), nullable=False)
+    description = Column(Text, nullable=False, server_default=text("''::text"))
+    created_at = Column(DateTime(True), nullable=False, server_default=text("CURRENT_TIMESTAMP"))
+    finished_at = Column(DateTime(True))
+    expires_at = Column(DateTime(True))
+    in_json = Column(JSONB)
+    in_file = Column(String(255), server_default=text("NULL::character varying"))
+    out_json = Column(JSONB)
+    out_file = Column(String(255), server_default=text("NULL::character varying"))
+
+    user = relationship('User')
+
+
 _engine: Optional[Engine] = None
 _session: Optional[Session] = None
 flask_db: Any = None
-- 
GitLab