diff options
-rw-r--r-- | src/commands/db.rs | 8 | ||||
-rw-r--r-- | src/commands/release.rs | 45 | ||||
-rw-r--r-- | src/db/models/artifact.rs | 10 | ||||
-rw-r--r-- | src/db/models/mod.rs | 3 | ||||
-rw-r--r-- | src/db/models/releases.rs | 44 | ||||
-rw-r--r-- | src/endpoint/scheduler.rs | 2 |
6 files changed, 84 insertions, 28 deletions
diff --git a/src/commands/db.rs b/src/commands/db.rs index 38e1de5..5ae4b90 100644 --- a/src/commands/db.rs +++ b/src/commands/db.rs @@ -149,18 +149,20 @@ fn artifacts(conn_cfg: DbConnectionConfig, matches: &ArgMatches) -> Result<()> { .map(|job_uuid| -> Result<_> { dsl::artifacts .inner_join(schema::jobs::table) + .left_join(schema::releases::table) .filter(schema::jobs::dsl::uuid.eq(job_uuid)) - .load::<(models::Artifact, models::Job)>(&conn) + .load::<(models::Artifact, models::Job, Option<models::Release>)>(&conn) .map_err(Error::from) }) .unwrap_or_else(|| { dsl::artifacts .inner_join(schema::jobs::table) - .load::<(models::Artifact, models::Job)>(&conn) + .left_join(schema::releases::table) + .load::<(models::Artifact, models::Job, Option<models::Release>)>(&conn) .map_err(Error::from) })? .into_iter() - .map(|(artifact, job)| vec![format!("{}", artifact.id), artifact.path, artifact.released.to_string(), job.uuid.to_string()]) + .map(|(artifact, job, rel)| vec![format!("{}", artifact.id), artifact.path, rel.is_some().to_string(), job.uuid.to_string()]) .collect::<Vec<_>>(); if data.is_empty() { diff --git a/src/commands/release.rs b/src/commands/release.rs index 723a779..b443ec1 100644 --- a/src/commands/release.rs +++ b/src/commands/release.rs @@ -55,35 +55,40 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .inner_join(crate::schema::packages::table) }) .filter(crate::schema::jobs::submit_id.eq(submit.id)) - .filter(crate::schema::artifacts::released.eq(false)); + .left_outer_join(crate::schema::releases::table) // not released + .select(crate::schema::artifacts::all_columns) + ; match (pname, pvers) { (Some(name), Some(vers)) => { - let query = sel.filter(crate::schema::packages::name.eq(name)) + let query = sel + .filter(crate::schema::packages::name.eq(name)) .filter(crate::schema::packages::version.like(vers)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (Some(name), None) => { - let query = sel.filter(crate::schema::packages::name.eq(name)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + let query = sel + .filter(crate::schema::packages::name.eq(name)); + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (None, Some(vers)) => { - let query = sel.filter(crate::schema::packages::version.like(vers)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + let query = sel + .filter(crate::schema::packages::version.like(vers)); + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (None, None) => { - debug!("Query: {}", diesel::debug_query(&sel).to_string()); - sel.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&sel)); + sel.load::<dbmodels::Artifact>(&conn)? }, } }; debug!("Artifacts = {:?}", arts); arts.iter() - .filter_map(|(art, _)| art.path_buf().parent().map(|p| config.releases_directory().join(p))) + .filter_map(|art| art.path_buf().parent().map(|p| config.releases_directory().join(p))) .map(|p| async { debug!("mkdir {:?}", p); tokio::fs::create_dir_all(p).await.map_err(Error::from) @@ -93,8 +98,10 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .await?; let staging_base: &PathBuf = &config.staging_directory().join(submit.uuid.to_string()); + + let now = chrono::offset::Local::now().naive_local(); arts.into_iter() - .map(|(art, _)| async move { + .map(|art| async move { let art_path = staging_base.join(&art.path); let dest_path = config.releases_directory().join(&art.path); debug!("Trying to release {} to {}", art_path.display(), dest_path.display()); @@ -118,12 +125,10 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .await? .into_iter() .map(|art| { - debug!("Updating {:?} to set released = true", art); - diesel::update(&art) - .set(crate::schema::artifacts::released.eq(true)) - .execute(&conn) - .map(|_| ()) - .map_err(Error::from) + debug!("Creating Release object in database for {:?}", art); + let rel = crate::db::models::Release::create(&conn, &art, &now)?; + debug!("Release object = {:?}", rel); + Ok(()) }) .collect() } diff --git a/src/db/models/artifact.rs b/src/db/models/artifact.rs index 01de301..01ac4c7 100644 --- a/src/db/models/artifact.rs +++ b/src/db/models/artifact.rs @@ -15,6 +15,7 @@ use anyhow::anyhow; use anyhow::Error; use anyhow::Context; use anyhow::Result; +use chrono::NaiveDateTime; use diesel::PgConnection; use diesel::prelude::*; @@ -27,7 +28,6 @@ use crate::schema::artifacts; pub struct Artifact { pub id: i32, pub path: String, - pub released: bool, pub job_id: i32, } @@ -35,7 +35,6 @@ pub struct Artifact { #[table_name="artifacts"] struct NewArtifact<'a> { pub path: &'a str, - pub released: bool, pub job_id: i32, } @@ -44,13 +43,16 @@ impl Artifact { PathBuf::from(&self.path) } - pub fn create(database_connection: &PgConnection, art_path: &ArtifactPath, art_released: bool, job: &Job) -> Result<Artifact> { + pub fn released(self, database_connection: &PgConnection, release_date: &NaiveDateTime) -> Result<crate::db::models::Release> { + crate::db::models::Release::create(database_connection, &self, release_date) + } + + pub fn create(database_connection: &PgConnection, art_path: &ArtifactPath, job: &Job) -> Result<Artifact> { let path_str = art_path.to_str() .ok_or_else(|| anyhow!("Path is not valid UTF-8: {}", art_path.display())) .context("Writing artifact to database")?; let new_art = NewArtifact { path: path_str, - released: art_released, job_id: job.id, }; diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index cd7aa72..77ebc51 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -32,6 +32,9 @@ pub use githash::*; mod package; pub use package::*; +mod releases; +pub use releases::*; + mod submit; pub use submit::*; diff --git a/src/db/models/releases.rs b/src/db/models/releases.rs new file mode 100644 index 0000000..1975d2c --- /dev/null +++ b/src/db/models/releases.rs @@ -0,0 +1,44 @@ +use anyhow::Error; +use anyhow::Result; +use chrono::NaiveDateTime; +use diesel::PgConnection; +use diesel::prelude::*; + +use crate::db::models::Artifact; +use crate::schema::releases::*; +use crate::schema::releases; + +#[derive(Debug, Identifiable, Queryable, Associations)] +#[belongs_to(Artifact)] +pub struct Release { + pub id: i32, + pub artifact_id: i32, + pub release_date: NaiveDateTime, +} + +#[derive(Insertable)] +#[table_name="releases"] +struct NewRelease<'a> { + pub artifact_id: i32, + pub release_date: &'a NaiveDateTime, +} + +impl Release { + pub fn create<'a>(database_connection: &PgConnection, art: &Artifact, date: &'a NaiveDateTime) -> Result<Release> { + let new_rel = NewRelease { + artifact_id: art.id, + release_date: date, + }; + + diesel::insert_into(releases::table) + .values(&new_rel) + .execute(database_connection)?; + + dsl::releases + .filter(artifact_id.eq(art.id).and(release_date.eq(date))) + .first::<Release>(database_connection) + .map_err(Error::from) + } +} + + diff --git a/src/endpoint/scheduler.rs b/src/endpoint/scheduler.rs index 1286ca9..0ed13cb 100644 --- a/src/endpoint/scheduler.rs +++ b/src/endpoint/scheduler.rs @@ -190,7 +190,7 @@ impl JobHandle { let mut r = vec![]; for p in paths.iter() { trace!("DB: Creating artifact entry for path: {}", p.display()); - r.push(dbmodels::Artifact::create(&self.db, p, false, &job)?); + r.push(dbmodels::Artifact::create(&self.db, p, &job)?); } Ok(r) } |