zirv_queue/models/
processed_job.rs

1use diesel::prelude::*;
2use serde::{Deserialize, Serialize};
3use zirv_db::DB;
4
5use super::job::Job;
6
7/// Represents a successfully processed job record in the database.
8///
9/// This corresponds to the `processed_jobs` table, which stores details of jobs
10/// that have been completed. It can be used for auditing, logging, or debugging
11/// purposes after a job is removed from the active `jobs` table.
12///
13/// # Fields
14///
15/// - `id`: Primary key (database-generated).
16/// - `job_id`: The original `id` from the `jobs` table.
17/// - `return_value`: Data returned when the job was processed (e.g., a result string).
18/// - `payload`: The job's original payload (e.g., parameters).
19/// - `attempts`: The number of attempts made to run this job before it was completed.
20/// - `processed_at`: The timestamp indicating when the job was processed.
21#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
22#[diesel(table_name = crate::schema::processed_jobs)]
23pub struct ProcessedJob {
24    pub id: i32,
25    pub job_id: i32,
26    pub return_value: String,
27    pub payload: String,
28    pub attempts: i32,
29    pub processed_at: chrono::NaiveDateTime,
30}
31
32/// The data required to create a new record in the `processed_jobs` table.
33///
34/// This struct omits the `id` field from [`ProcessedJob`] because the database
35/// manages that automatically.
36///
37/// # Fields
38///
39/// - `job_id`: The ID of the job that was processed.
40/// - `return_value`: Data or message indicating the result of processing.
41/// - `payload`: The job's original payload.
42/// - `attempts`: The number of attempts that were made for the job.
43/// - `processed_at`: Timestamp of when the job finished processing.
44#[derive(Insertable, Debug, Serialize, Deserialize)]
45#[diesel(table_name = crate::schema::processed_jobs)]
46pub struct NewProcessedJob {
47    pub job_id: i32,
48    pub return_value: String,
49    pub payload: String,
50    pub attempts: i32,
51    pub processed_at: chrono::NaiveDateTime,
52}
53
54impl ProcessedJob {
55    /// Creates a new record in the `processed_jobs` table based on a completed [`Job`].
56    ///
57    /// This method:
58    /// 1. Constructs a [`NewProcessedJob`] from the provided [`Job`] data and a user-provided
59    ///    return value string.
60    /// 2. Acquires a database connection via [`DB::get_conn`].
61    /// 3. Inserts the `NewProcessedJob` into the `processed_jobs` table.
62    ///
63    /// # Parameters
64    ///
65    /// - `job`: The [`Job`] that has been successfully completed.
66    /// - `_return_value`: A string describing the outcome of the job (result data or message).
67    ///
68    /// # Returns
69    ///
70    /// - `Ok(())` if the record was inserted successfully.
71    /// - `Err(diesel::result::Error)` if there is a connection or insertion failure.
72    ///
73    /// # Example
74    ///
75    /// ```rust,no_run
76    /// # use zirv_queue::models::{job::Job, processed_job::ProcessedJob};
77    /// // Suppose `some_job` is an instance of a `Job` that has completed successfully.
78    /// let some_job = Job {
79    ///     id: 1,
80    ///     payload: "example payload".to_string(),
81    ///     status: "completed".to_string(),
82    ///     attempts: 1,
83    ///     available_at: chrono::Local::now().naive_local(),
84    ///     created_at: chrono::Local::now().naive_local(),
85    ///     updated_at: chrono::Local::now().naive_local(),
86    /// };
87    /// 
88    /// let return_msg = "Processed successfully".to_string();
89    ///
90    /// match ProcessedJob::create(some_job, return_msg) {
91    ///     Ok(_) => println!("Successfully inserted processed job record."),
92    ///     Err(e) => eprintln!("Failed to create processed job record: {:?}", e),
93    /// }
94    /// ```
95    pub fn create(
96        job: &Job,
97        _return_value: String,
98    ) -> Result<(), diesel::result::Error> {
99        use crate::schema::processed_jobs::dsl::*;
100
101        let new_processed_job = NewProcessedJob {
102            job_id: job.id,
103            return_value: _return_value,
104            payload: job.payload.to_owned(),
105            attempts: job.attempts,
106            processed_at: chrono::Local::now().naive_local(),
107        };
108
109        let mut conn = match DB::get_conn() {
110            Ok(conn) => conn,
111            Err(e) => {
112                eprintln!("Error getting DB connection: {:?}", e);
113                return Err(diesel::result::Error::NotFound);
114            }
115        };
116
117        match diesel::insert_into(processed_jobs)
118            .values(new_processed_job)
119            .execute(&mut conn)
120        {
121            Ok(_) => Ok(()),
122            Err(e) => {
123                eprintln!("Error inserting processed job: {:?}", e);
124                Err(e)
125            }
126        }
127    }
128}