#pragma once // Read/write access to the `tasks` table, plus the projection onto the wire TaskSummary. // download.list does its filtering, sorting and paging here (M1 DoD: a 1000-row list under // 50 ms, never materialised client-side). #include #include #include #include #include "store/sqlite.hpp" #include "velox_proto.hpp" namespace velox::daemon::store { // One row of `tasks`, 1:1 with the schema. std::optional maps a NULL column. struct TaskRow { std::string task_id; std::string url; std::string save_dir; std::string filename; std::string state = "new"; std::string start_mode = "auto"; std::string created_at; std::optional effective_url; std::optional category_id; std::optional queue_id; std::optional description; std::optional pause_reason; std::optional etag; std::optional last_modified; std::optional content_type; std::optional last_try_at; std::optional completed_at; std::optional checksum_algo; std::optional checksum_value; std::optional size_bytes; std::int64_t downloaded_bytes = 0; bool resumable = false; std::optional req_segments; std::int64_t eff_segments = 0; std::optional req_buffer_bytes; std::optional eff_buffer_bytes; std::optional queue_position; std::optional error_code; std::optional error_message; std::optional error_http_status; std::optional error_retryable; std::optional error_attempt; std::optional error_next_retry_at; }; class Tasks { public: explicit Tasks(Db& db) : db_(db) {} DbResult insert(const TaskRow& row); DbResult> get(std::string_view task_id); struct Page { std::int64_t total = 0; // rows matching the filter, ignoring paging std::vector rows; }; DbResult list(const std::optional& filter, const std::optional& sort, std::int64_t offset, std::int64_t limit); // Move a task to `state`; `pause_reason` is written only when state == "paused" // (cleared otherwise). Returns false if there is no such task. DbResult set_state(std::string_view task_id, std::string_view state, const std::optional& pause_reason); DbResult remove(std::string_view task_id); DbResult count(); private: Db& db_; }; // Project a row onto the wire type. `state` and `error.code` strings are assumed valid // (the CHECK constraints and the state machine keep them so). velox::proto::TaskSummary to_summary(const TaskRow& row); } // namespace velox::daemon::store