Skip to main content

chainlink/db/
relations.rs

1use anyhow::Result;
2use chrono::Utc;
3use rusqlite::params;
4
5use super::{issue_from_row, Database};
6use crate::models::Issue;
7
8impl Database {
9    pub fn add_relation(&self, issue_id_1: i64, issue_id_2: i64) -> Result<bool> {
10        if issue_id_1 == issue_id_2 {
11            anyhow::bail!("Cannot relate an issue to itself");
12        }
13        let (a, b) = if issue_id_1 < issue_id_2 {
14            (issue_id_1, issue_id_2)
15        } else {
16            (issue_id_2, issue_id_1)
17        };
18        let now = Utc::now().to_rfc3339();
19        let result = self.conn.execute(
20            "INSERT OR IGNORE INTO relations (issue_id_1, issue_id_2, created_at) VALUES (?1, ?2, ?3)",
21            params![a, b, now],
22        )?;
23        Ok(result > 0)
24    }
25
26    pub fn remove_relation(&self, issue_id_1: i64, issue_id_2: i64) -> Result<bool> {
27        let (a, b) = if issue_id_1 < issue_id_2 {
28            (issue_id_1, issue_id_2)
29        } else {
30            (issue_id_2, issue_id_1)
31        };
32        let rows = self.conn.execute(
33            "DELETE FROM relations WHERE issue_id_1 = ?1 AND issue_id_2 = ?2",
34            params![a, b],
35        )?;
36        Ok(rows > 0)
37    }
38
39    pub fn get_related_issues(&self, issue_id: i64) -> Result<Vec<Issue>> {
40        let mut stmt = self.conn.prepare(
41            r#"
42            SELECT i.id, i.title, i.description, i.status, i.priority, i.parent_id, i.created_at, i.updated_at, i.closed_at
43            FROM issues i
44            WHERE i.id IN (
45                SELECT issue_id_2 FROM relations WHERE issue_id_1 = ?1
46                UNION
47                SELECT issue_id_1 FROM relations WHERE issue_id_2 = ?1
48            )
49            ORDER BY i.id
50            "#,
51        )?;
52
53        let issues = stmt
54            .query_map([issue_id], issue_from_row)?
55            .collect::<std::result::Result<Vec<_>, _>>()?;
56
57        Ok(issues)
58    }
59}