OXYGENHUB
# 73beb84b202a oxygenhub / crates / hub / src / db / repos.rs
3.7 KiB · Rust · last changed Milestone 0.1: browse 1 month ago source blame history raw
1
//! The `repositories` and `pushes` tables.
2
3
use super::{now_ms, Pool};
4
use hub_api::Visibility;
5
use sqlx::FromRow;
6
7
#[derive(Clone, Debug, FromRow)]
8
pub struct RepoRow {
9
    pub id: i64,
10
    pub owner: String,
11
    pub name: String,
12
    pub description: String,
13
    pub default_bookmark: String,
14
    pub visibility: String,
15
    pub created_ms: i64,
16
    pub updated_ms: i64,
17
}
18
19
impl RepoRow {
20
    pub fn visibility(&self) -> Visibility {
21
        Visibility::parse(&self.visibility).unwrap_or(Visibility::Private)
22
    }
23
24
    pub fn slug(&self) -> String {
25
        format!("{}/{}", self.owner, self.name)
26
    }
27
}
28
29
#[derive(Clone, Debug, FromRow)]
30
pub struct PushRow {
31
    pub id: i64,
32
    pub at_ms: i64,
33
    pub reference: String,
34
    pub ok: bool,
35
    pub reason: String,
36
}
37
38
pub async fn list(pool: &Pool) -> sqlx::Result<Vec<RepoRow>> {
39
    sqlx::query_as("SELECT * FROM repositories ORDER BY updated_ms DESC, owner, name").fetch_all(pool).await
40
}
41
42
pub async fn list_by_owner(pool: &Pool, owner: &str) -> sqlx::Result<Vec<RepoRow>> {
43
    sqlx::query_as("SELECT * FROM repositories WHERE owner = ? ORDER BY updated_ms DESC, name").bind(owner).fetch_all(pool).await
44
}
45
46
pub async fn get(pool: &Pool, owner: &str, name: &str) -> sqlx::Result<Option<RepoRow>> {
47
    sqlx::query_as("SELECT * FROM repositories WHERE owner = ? AND name = ?").bind(owner).bind(name).fetch_optional(pool).await
48
}
49
50
pub async fn create(pool: &Pool, owner: &str, name: &str, description: &str, visibility: Visibility) -> sqlx::Result<RepoRow> {
51
    let now = now_ms();
52
    sqlx::query_as(
53
        "INSERT INTO repositories (owner, name, description, visibility, created_ms, updated_ms) VALUES (?, ?, ?, ?, ?, ?) RETURNING *",
54
    )
55
    .bind(owner)
56
    .bind(name)
57
    .bind(description)
58
    .bind(visibility.as_str())
59
    .bind(now)
60
    .bind(now)
61
    .fetch_one(pool)
62
    .await
63
}
64
65
pub async fn delete(pool: &Pool, id: i64) -> sqlx::Result<()> {
66
    sqlx::query("DELETE FROM repositories WHERE id = ?").bind(id).execute(pool).await?;
67
    Ok(())
68
}
69
70
pub async fn set_description(pool: &Pool, id: i64, description: &str) -> sqlx::Result<()> {
71
    sqlx::query("UPDATE repositories SET description = ? WHERE id = ?").bind(description).bind(id).execute(pool).await?;
72
    Ok(())
73
}
74
75
pub async fn set_default_bookmark(pool: &Pool, id: i64, bookmark: &str) -> sqlx::Result<()> {
76
    sqlx::query("UPDATE repositories SET default_bookmark = ? WHERE id = ?").bind(bookmark).bind(id).execute(pool).await?;
77
    Ok(())
78
}
79
80
pub async fn set_visibility(pool: &Pool, id: i64, visibility: Visibility) -> sqlx::Result<()> {
81
    sqlx::query("UPDATE repositories SET visibility = ? WHERE id = ?").bind(visibility.as_str()).bind(id).execute(pool).await?;
82
    Ok(())
83
}
84
85
/// Record a push's per-reference results and bump the repository's activity.
86
pub async fn record_push(pool: &Pool, id: i64, results: &[(String, bool, String)]) -> sqlx::Result<()> {
87
    let now = now_ms();
88
    let mut tx = pool.begin().await?;
89
    for (reference, ok, reason) in results {
90
        sqlx::query("INSERT INTO pushes (repo_id, at_ms, reference, ok, reason) VALUES (?, ?, ?, ?, ?)")
91
            .bind(id)
92
            .bind(now)
93
            .bind(reference)
94
            .bind(ok)
95
            .bind(reason)
96
            .execute(&mut *tx)
97
            .await?;
98
    }
99
    if results.iter().any(|(_, ok, _)| *ok) {
100
        sqlx::query("UPDATE repositories SET updated_ms = ? WHERE id = ?").bind(now).bind(id).execute(&mut *tx).await?;
101
    }
102
    tx.commit().await
103
}
104
105
pub async fn pushes(pool: &Pool, id: i64, limit: i64) -> sqlx::Result<Vec<PushRow>> {
106
    sqlx::query_as("SELECT id, at_ms, reference, ok, reason FROM pushes WHERE repo_id = ? ORDER BY at_ms DESC, id DESC LIMIT ?")
107
        .bind(id)
108
        .bind(limit)
109
        .fetch_all(pool)
110
        .await
111
}