rec23-rs 0.2.82

A library for REC23 CRM.
Documentation
use std::error::Error;
use bb8_postgres::bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use bb8_postgres::tokio_postgres::{GenericClient, NoTls, Row};

const GET_MESSAGE_TASK_LINK: &str = "SELECT message_task_link.task_id, message_task_link.message_id, message_task_link.link_type FROM rec23.message_task_link message_task_link WHERE message_task_link.message_id = $1 AND message_task_link.link_type = $2";
const INSERT_MESSAGE_TASK_LINK: &str = "INSERT INTO rec23.message_task_link VALUES(DEFAULT, $1, $2, $3) RETURNING ID";

pub struct MessageTaskLink {
    pub message_id: i32,
    pub task_id: i32,
    pub link_type: i32,
}

impl MessageTaskLink {
    /// Constructs a new `MessageTaskLink` object.
    ///
    /// This static method returns a new instance of the `MessageTaskLink`
    /// struct with the following parameters as its fields:
    ///
    /// # Arguments
    ///
    /// * `message_id` - A 32-bit integer representing the message ID.
    /// * `task_id` - A 32-bit integer representing the task ID.
    /// * `link_type` - A 32-bit integer representing the type of the link, where each type corresponds to a different meaning.
    ///
    /// # Returns
    ///
    /// Returns the `MessageTaskLink` structure populated with `message_id`, `task_id`, and `link_type`.
    pub fn new(message_id: i32, task_id: i32, link_type: i32) -> Self {
        Self {
            message_id,
            task_id,
            link_type,
        }
    }

    /// Saves a `MessageTaskLink` object to the database.
    ///
    /// This asynchronous method executes a SQL insert command to persist the `MessageTaskLink` object
    /// to the database. It first retrieves a connection from the provided connection pool, then prepares
    /// the SQL command for execution. The SQL command is parameterized to prevent SQL injection attacks.
    ///
    /// # Arguments
    ///
    /// * `self` - The instance of `MessageTaskLink` that will be persisted to the database.
    /// * `pool` - A database connection pool, used to ensure that database connections
    ///             are efficiently reused.
    ///
    /// # Returns
    ///
    /// This method returns a Result that is:
    ///
    /// * `Ok(())` - If the insert operation was successful.
    /// * `Err(e)` - If the insert operation failed, where `e` is the error that was encountered.
    ///
    /// # Errors
    ///
    /// This function will return an error if the database operation fails for any reason,
    /// such as if the connection pool is exhausted or if the execution of the SQL command fails.
    pub async fn save(&self, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<(), Box<dyn Error + Sync + Send>> {
        let connection = pool.get().await?;
        let client = connection.client();
        client.execute(INSERT_MESSAGE_TASK_LINK, &[&self.message_id, &self.task_id, &self.link_type]).await?;
        Ok(())
    }

    /// Converts a `Row` reference to a `MessageTaskLink` instance.
    ///
    /// This function takes a single argument, `row`, which is a reference to a `Row` instance, generally
    /// extracted from a database query result. It retrieves the `"task_id"`, `"message_id"`, and `"link_type"`
    /// fields from the `Row` reference, and uses them to construct a new `MessageTaskLink` instance.
    ///
    /// # Arguments
    ///
    /// * `row` - A `Row` reference representing a single row in a database query result.
    ///
    /// # Returns
    ///
    /// This function returns a `MessageTaskLink` instance with its fields populated based
    /// on the data in the `Row` reference.
    pub fn convert_from_row(row: &Row) -> Self {
        Self {
            task_id: row.get("task_id"),
            message_id: row.get("message_id"),
            link_type: row.get("link_type"),
        }
    }

    /// Fetches a `MessageTaskLink` object with a specific message id and link type from the database.
    ///
    /// This asynchronous method constructs and executes a SQL query to retrieve the `MessageTaskLink` object
    /// with the specified message id and link type from the database. It first retrieves a connection from the
    /// provided connection pool, then prepares the SQL query for execution. The query is parameterized for
    /// safety to prevent SQL injection attacks.
    ///
    /// The result is then matched: If a `row` exists, it is passed to the `convert_from_row` function and the
    /// resulting `MessageTaskLink` is wrapped in `Some()`. If `row` does not exists i.e., if the query did not
    /// retrieve a result, it returns `None`.
    ///
    /// # Arguments
    ///
    /// * `message_id` - A 32-bit integer of the message id to query for.
    /// * `link_type` - A 32-bit integer of the link type to query for.
    /// * `pool` - A database connection pool. This is used to ensure efficient reuse of database connections.
    ///
    /// # Returns
    ///
    /// This method returns a `Result` with the `Option` of `MessageTaskLink`:
    ///
    /// * `Ok(Some(MessageTaskLink))` - If the query operation was successful and a `MessageTaskLink` is found.
    /// * `Ok(None)` - If the query operation was successful but no `MessageTaskLink` is found.
    /// * `Err(e)` - If the query operation failed, where `e` is the error that was encountered.
    ///
    /// # Errors
    ///
    /// This function will return an error if operation fails for any reason,
    /// such as if the connection pool is exhausted or if the execution of the SQL command fails.
    pub async fn get_by_message_id_and_link_type(message_id: i32, link_type: i32, pool: &Pool<PostgresConnectionManager<NoTls>>) -> Result<Option<MessageTaskLink>, Box<dyn Error + Sync + Send>> {
        let connection = pool.get().await?;
        let client = connection.client();
        let row = client.query_opt(GET_MESSAGE_TASK_LINK, &[&message_id, &link_type]).await?;
        let message_link = match row {
            Some(row) => Some(Self::convert_from_row(&row)),
            None => None
        };
        Ok(message_link)
    }
}