130 lines
3.0 KiB
Rust
130 lines
3.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use sqlx::{prelude::FromRow, PgPool};
|
|
|
|
use self::defaults::DefaultArtifactsDB;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct AddCommitArtifact {
|
|
pub app: String,
|
|
pub branch: String,
|
|
pub artifact_id: uuid::Uuid,
|
|
}
|
|
|
|
#[derive(Clone, Debug, FromRow)]
|
|
pub struct Artifact {
|
|
pub app: String,
|
|
pub branch: String,
|
|
pub artifact_id: uuid::Uuid,
|
|
pub created_at: chrono::NaiveDateTime,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct GetLatestArtifact {
|
|
pub app: String,
|
|
pub branch: String,
|
|
}
|
|
|
|
pub mod traits {
|
|
use super::{AddCommitArtifact, Artifact, GetLatestArtifact};
|
|
|
|
#[async_trait::async_trait]
|
|
pub trait ArtifactsDB {
|
|
async fn commit_artifact(&self, commit_artifact: AddCommitArtifact) -> anyhow::Result<()>;
|
|
async fn get_latest_artifact(
|
|
&self,
|
|
get_latest_artifact: GetLatestArtifact,
|
|
) -> anyhow::Result<Artifact>;
|
|
}
|
|
}
|
|
|
|
pub mod defaults {
|
|
use sqlx::PgPool;
|
|
|
|
use super::{traits, AddCommitArtifact, Artifact, GetLatestArtifact};
|
|
|
|
pub struct DefaultArtifactsDB {
|
|
db: PgPool,
|
|
}
|
|
|
|
impl DefaultArtifactsDB {
|
|
pub fn new(db: PgPool) -> Self {
|
|
Self { db }
|
|
}
|
|
}
|
|
|
|
#[async_trait::async_trait]
|
|
impl traits::ArtifactsDB for DefaultArtifactsDB {
|
|
async fn commit_artifact(&self, commit_artifact: AddCommitArtifact) -> anyhow::Result<()> {
|
|
sqlx::query("INSERT INTO artifacts (app, branch, artifact_id) VALUES ($1, $2, $3)")
|
|
.bind(commit_artifact.app)
|
|
.bind(commit_artifact.branch)
|
|
.bind(commit_artifact.artifact_id)
|
|
.execute(&self.db)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn get_latest_artifact(
|
|
&self,
|
|
get_latest_artifact: GetLatestArtifact,
|
|
) -> anyhow::Result<Artifact> {
|
|
let artifact = sqlx::query_as::<_, Artifact>(
|
|
"SELECT
|
|
*
|
|
FROM
|
|
artifacts
|
|
WHERE
|
|
app = $1 AND
|
|
branch = $2
|
|
ORDER BY created_at DESC
|
|
LIMIT 1",
|
|
)
|
|
.bind(get_latest_artifact.app)
|
|
.bind(get_latest_artifact.branch)
|
|
.fetch_one(&self.db)
|
|
.await?;
|
|
|
|
Ok(artifact)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct ArtifactsDB {
|
|
inner: Arc<dyn traits::ArtifactsDB + Send + Sync>,
|
|
}
|
|
|
|
impl ArtifactsDB {
|
|
pub fn new(db: PgPool) -> Self {
|
|
Self {
|
|
inner: Arc::new(DefaultArtifactsDB::new(db)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::ops::Deref for ArtifactsDB {
|
|
type Target = Arc<dyn traits::ArtifactsDB + Send + Sync>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.inner
|
|
}
|
|
}
|
|
|
|
pub mod extensions {
|
|
use crate::app::App;
|
|
|
|
use super::ArtifactsDB;
|
|
|
|
pub trait ArtifactsDBExt {
|
|
fn artifacts_db(&self) -> ArtifactsDB;
|
|
}
|
|
|
|
impl ArtifactsDBExt for App {
|
|
fn artifacts_db(&self) -> ArtifactsDB {
|
|
ArtifactsDB::new(self.database.clone())
|
|
}
|
|
}
|
|
}
|