diff --git a/migrations/000005_alter_task_table_updated_at.down.sql b/migrations/000005_alter_task_table_updated_at.down.sql new file mode 100644 index 0000000..c2a5250 --- /dev/null +++ b/migrations/000005_alter_task_table_updated_at.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE tasks +DROP updated_at; \ No newline at end of file diff --git a/migrations/000005_alter_task_table_updated_at.up.sql b/migrations/000005_alter_task_table_updated_at.up.sql new file mode 100644 index 0000000..4fd2ea5 --- /dev/null +++ b/migrations/000005_alter_task_table_updated_at.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE tasks +ADD updated_at TIMESTAMP NOT NULL DEFAULT current_timestamp; \ No newline at end of file diff --git a/migrations/000006_create_function_update_updated_at_column.down.sql b/migrations/000006_create_function_update_updated_at_column.down.sql new file mode 100644 index 0000000..b9fe238 --- /dev/null +++ b/migrations/000006_create_function_update_updated_at_column.down.sql @@ -0,0 +1 @@ +DROP FUNCTION update_updated_at_column; \ No newline at end of file diff --git a/migrations/000006_create_function_update_updated_at_column.up.sql b/migrations/000006_create_function_update_updated_at_column.up.sql new file mode 100644 index 0000000..92ab0b9 --- /dev/null +++ b/migrations/000006_create_function_update_updated_at_column.up.sql @@ -0,0 +1,7 @@ +CREATE OR REPLACE FUNCTION update_updated_at_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = clock_timestamp(); + RETURN NEW; +END; +$$ language 'plpgsql'; \ No newline at end of file diff --git a/migrations/000007_create_trigger_update_task_timestamp.down.sql b/migrations/000007_create_trigger_update_task_timestamp.down.sql new file mode 100644 index 0000000..acf5b95 --- /dev/null +++ b/migrations/000007_create_trigger_update_task_timestamp.down.sql @@ -0,0 +1 @@ +DROP TRIGGER update_tasks_timestamp; \ No newline at end of file diff --git a/migrations/000007_create_trigger_update_task_timestamp.up.sql b/migrations/000007_create_trigger_update_task_timestamp.up.sql new file mode 100644 index 0000000..4ad951c --- /dev/null +++ b/migrations/000007_create_trigger_update_task_timestamp.up.sql @@ -0,0 +1 @@ +CREATE TRIGGER update_tasks_timestamp BEFORE UPDATE ON tasks FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column(); \ No newline at end of file diff --git a/migrations/000008_alter_files_table_updated_at.down.sql b/migrations/000008_alter_files_table_updated_at.down.sql new file mode 100644 index 0000000..60f8fb6 --- /dev/null +++ b/migrations/000008_alter_files_table_updated_at.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE files +DROP updated_at; \ No newline at end of file diff --git a/migrations/000008_alter_files_table_updated_at.up.sql b/migrations/000008_alter_files_table_updated_at.up.sql new file mode 100644 index 0000000..bbc50da --- /dev/null +++ b/migrations/000008_alter_files_table_updated_at.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE files +ADD updated_at TIMESTAMP NOT NULL DEFAULT current_timestamp; \ No newline at end of file diff --git a/migrations/000009_create_trigger_update_files_timestamp.down.sql b/migrations/000009_create_trigger_update_files_timestamp.down.sql new file mode 100644 index 0000000..153e8fa --- /dev/null +++ b/migrations/000009_create_trigger_update_files_timestamp.down.sql @@ -0,0 +1 @@ +DROP TRIGGER update_files_timestamp; \ No newline at end of file diff --git a/migrations/000009_create_trigger_update_files_timestamp.up.sql b/migrations/000009_create_trigger_update_files_timestamp.up.sql new file mode 100644 index 0000000..d2bb539 --- /dev/null +++ b/migrations/000009_create_trigger_update_files_timestamp.up.sql @@ -0,0 +1 @@ +CREATE TRIGGER update_files_timestamp BEFORE UPDATE ON files FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column(); \ No newline at end of file diff --git a/server/library.go b/server/library.go index 690c7f0..dca25ad 100644 --- a/server/library.go +++ b/server/library.go @@ -5,6 +5,7 @@ import ( "fmt" "log/slog" "net/http" + "time" "git.lastassault.de/speatzle/morffix/constants" "github.com/jackc/pgx/v5" @@ -16,21 +17,23 @@ type LibraryData struct { } type File struct { - ID int `db:"id"` - Path string `db:"path"` - Size int64 `db:"size"` - Status constants.FileStatus `db:"status"` - Health constants.FileHealth `db:"health"` - MD5 []byte `db:"md5"` + ID int `db:"id"` + Path string `db:"path"` + Size int64 `db:"size"` + Status constants.FileStatus `db:"status"` + Health constants.FileHealth `db:"health"` + MD5 []byte `db:"md5"` + UpdatedAt time.Time `db:"updated_at"` } type FileDisplay struct { - ID int - Path string - Size int64 - Status string - Health string - MD5 string + ID int + Path string + Size int64 + Status string + Health string + MD5 string + UpdatedAt string `db:"updated_at"` } func handleLibrary(w http.ResponseWriter, r *http.Request) { @@ -62,7 +65,7 @@ func handleLibrary(w http.ResponseWriter, r *http.Request) { // TODO } - rows, err := db.Query(r.Context(), "SELECT id, path, size, status, health, md5 FROM files where library_id = $1", id) + rows, err := db.Query(r.Context(), "SELECT id, path, size, status, health, md5, updated_at FROM files where library_id = $1", id) if err != nil { slog.ErrorContext(r.Context(), "Query Files", "err", err) http.Error(w, "Error Query Files: "+err.Error(), http.StatusInternalServerError) @@ -77,12 +80,13 @@ func handleLibrary(w http.ResponseWriter, r *http.Request) { for i := range files { data.Files = append(data.Files, FileDisplay{ - ID: files[i].ID, - Path: files[i].Path, - Size: files[i].Size, - Status: files[i].Status.String(), - Health: files[i].Health.String(), - MD5: fmt.Sprintf("%x", files[i].MD5), + ID: files[i].ID, + Path: files[i].Path, + Size: files[i].Size, + Status: files[i].Status.String(), + Health: files[i].Health.String(), + MD5: fmt.Sprintf("%x", files[i].MD5), + UpdatedAt: files[i].UpdatedAt.Format(time.DateTime), }) } diff --git a/server/task.go b/server/task.go index 23bf2a7..d5b9c79 100644 --- a/server/task.go +++ b/server/task.go @@ -7,6 +7,7 @@ import ( "fmt" "log/slog" "net/http" + "time" "git.lastassault.de/speatzle/morffix/constants" "git.lastassault.de/speatzle/morffix/types" @@ -32,21 +33,23 @@ type TaskStats struct { } type TaskDisplay struct { - ID int `db:"id"` - Library int `db:"library"` - Worker *string `db:"worker"` - Type int `db:"type"` - Status string `db:"status"` - File string `db:"file"` + ID int `db:"id"` + Library int `db:"library"` + Worker *string `db:"worker"` + Type int `db:"type"` + Status string `db:"status"` + File string `db:"file"` + UpdatedAt string `db:"updated_at"` } type TaskDB struct { - ID int `db:"id"` - Library int `db:"library"` - Worker *string `db:"worker"` - Type int `db:"type"` - Status constants.TaskStatus `db:"status"` - File string `db:"file"` + ID int `db:"id"` + Library int `db:"library"` + Worker *string `db:"worker"` + Type int `db:"type"` + Status constants.TaskStatus `db:"status"` + File string `db:"file"` + UpdatedAt time.Time `db:"updated_at"` } func handleTasks(w http.ResponseWriter, r *http.Request) { @@ -93,7 +96,7 @@ func handleTasks(w http.ResponseWriter, r *http.Request) { } data.Libraries = libraries - rows, err = db.Query(r.Context(), "SELECT t.id AS id, l.id AS library, t.worker_id AS worker, t.type AS type, t.status AS status, f.path AS file FROM tasks t INNER JOIN files f ON f.id = t.file_id INNER JOIN libraries l ON l.id = f.library_id ORDER BY CASE t.type WHEN 3 THEN -1 ELSE t.type END, t.id") + rows, err = db.Query(r.Context(), "SELECT t.id AS id, l.id AS library, t.worker_id AS worker, t.type AS type, t.status AS status, f.path AS file, t.updated_at AS updated_at FROM tasks t INNER JOIN files f ON f.id = t.file_id INNER JOIN libraries l ON l.id = f.library_id ORDER BY CASE t.type WHEN 3 THEN -1 ELSE t.type END, t.id") if err != nil { slog.ErrorContext(r.Context(), "Query Tasks", "err", err) http.Error(w, "Error Query Tasks: "+err.Error(), http.StatusInternalServerError) @@ -107,12 +110,13 @@ func handleTasks(w http.ResponseWriter, r *http.Request) { } for i := range tasks { data.Tasks = append(data.Tasks, TaskDisplay{ - ID: tasks[i].ID, - Library: tasks[i].Library, - Worker: tasks[i].Worker, - Type: tasks[i].Type, - File: tasks[i].File, - Status: tasks[i].Status.String(), + ID: tasks[i].ID, + Library: tasks[i].Library, + Worker: tasks[i].Worker, + Type: tasks[i].Type, + File: tasks[i].File, + Status: tasks[i].Status.String(), + UpdatedAt: tasks[i].UpdatedAt.Format(time.DateTime), }) } diff --git a/tmpl/library.tmpl b/tmpl/library.tmpl index 7b59ca8..0f39886 100644 --- a/tmpl/library.tmpl +++ b/tmpl/library.tmpl @@ -14,6 +14,7 @@