/ backend / src / services / get_upload_session_service.rs
get_upload_session_service.rs
 1  use sqlx::Pool;
 2  
 3  use crate::{
 4      db::{self, upload_session_repository, DB},
 5      models::upload_session::UploadSession,
 6      registry_error::{RegistryError, RegistryResult},
 7      types::session_id::SessionId,
 8  };
 9  
10  pub async fn retrieve_last_upload_session(
11      db_pool: &Pool<DB>,
12      namespace: &str,
13      session_id: SessionId,
14  ) -> RegistryResult<UploadSession> {
15      let mut transaction = db::new_transaction(db_pool).await?;
16  
17      let previous = upload_session_repository::find_by_repository_and_id(
18          &mut transaction,
19          namespace,
20          session_id.clone().into(),
21      )
22      .await?;
23  
24      let Some(mut previous) = previous else {
25          warn!("Tried to retrieve non-existant upload session ({session_id})");
26          return Err(RegistryError::SessionNotFound);
27      };
28  
29      while let Some(next) =
30          upload_session_repository::try_find_by_previous_id(&mut transaction, namespace, previous.id)
31              .await?
32      {
33          previous = next;
34      }
35  
36      if previous.is_finished {
37          warn!("Session has already been finished ({session_id})");
38          return Err(RegistryError::SessionNotFound);
39      }
40  
41      if previous.digest.is_some() {
42          error!(
43              "Invalid state: last session in unfinished upload has been uploaded! ({session_id})"
44          );
45          return Err(RegistryError::InvalidState);
46      }
47  
48      transaction.commit().await?;
49  
50      Ok(previous)
51  }