1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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)
}
}