Skip to content

Commit

Permalink
wip: use id when storing files in S3
Browse files Browse the repository at this point in the history
  • Loading branch information
Frixxie committed Oct 17, 2024
1 parent 09823a3 commit 6ad2041
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions backend/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use sqlx::{prelude::FromRow, PgPool};

static BUCKET_NAME: &'static str = "files";

fn file_name(id: i32, hash: &str) -> String {
format!("{}-{}", id, hash)
}

fn get_s3_credentials() -> Result<(Credentials, Region)> {
Ok((Credentials::default()?, Region::from_default_env()?))
}
Expand All @@ -25,6 +29,7 @@ impl File {

pub async fn put_into_s3(
&self,
id: i32,
hash: &str,
credentials: Credentials,
region: Region,
Expand All @@ -42,21 +47,29 @@ impl File {
.await?;
}

bucket.put_object(hash, &self.content).await?;
bucket
.put_object(file_name(id, hash), &self.content)
.await?;

Ok(())
}

pub async fn get_from_s3(hash: &str, credentials: Credentials, region: Region) -> Result<Self> {
pub async fn get_from_s3(
id: i32,
hash: &str,
credentials: Credentials,
region: Region,
) -> Result<Self> {
let bucket = Bucket::new(BUCKET_NAME, region.clone(), credentials.clone())
.unwrap()
.with_path_style();

let result = bucket.get_object(hash).await?;
let result = bucket.get_object(file_name(id, hash)).await?;
Ok(Self::new(result.into()))
}

pub async fn delete_from_s3(
id: i32,
hash: &str,
credentials: Credentials,
region: Region,
Expand All @@ -65,7 +78,7 @@ impl File {
.unwrap()
.with_path_style();

bucket.delete_object(hash).await?;
bucket.delete_object(file_name(id, hash)).await?;

Ok(())
}
Expand Down Expand Up @@ -98,12 +111,16 @@ impl FileInfo {
let hash = digest(content);
let (credentials, region) = get_s3_credentials()?;
let file = File::new(content.to_vec());
file.put_into_s3(&hash, credentials, region).await?;
sqlx::query("INSERT INTO files (hash, object_storage_location) VALUES ($1, $2)")
.bind(hash.clone())
.bind(BUCKET_NAME)
.execute(pool)
.await?;
let id = sqlx::query_scalar("SELECT id FROM files WHERE hash = $1")
.bind(hash.clone())
.fetch_one(pool)
.await?;
file.put_into_s3(id, &hash, credentials, region).await?;
Ok(())
}

Expand All @@ -117,7 +134,7 @@ impl FileInfo {
pub async fn delete_from_db(pool: &PgPool, id: i32) -> Result<()> {
let file_info = Self::read_from_db_by_id(pool, id).await?;
let (credentials, region) = get_s3_credentials()?;
File::delete_from_s3(&file_info.hash, credentials, region).await?;
File::delete_from_s3(file_info.id, &file_info.hash, credentials, region).await?;
sqlx::query("DELETE FROM files WHERE id = $1")
.bind(id)
.execute(pool)
Expand All @@ -136,7 +153,7 @@ impl FileInfo {
pub async fn get_file_by_id(pool: &PgPool, id: i32) -> Result<Content> {
let file_info = Self::read_from_db_by_id(pool, id).await?;
let (credentials, region) = get_s3_credentials()?;
let file = File::get_from_s3(&file_info.hash, credentials, region).await?;
let file = File::get_from_s3(file_info.id, &file_info.hash, credentials, region).await?;
Ok(file.content)
}

Expand All @@ -148,8 +165,13 @@ impl FileInfo {

let mut result: Vec<(FileInfo, File)> = Vec::new();
for file_info in file_infos {
let file =
File::get_from_s3(&file_info.hash, credentials.clone(), region.clone()).await?;
let file = File::get_from_s3(
file_info.id,
&file_info.hash,
credentials.clone(),
region.clone(),
)
.await?;
result.push((file_info.clone(), file));
}
Ok(result)
Expand Down Expand Up @@ -187,7 +209,7 @@ mod tests {

let (credentials, region) = get_s3_credentials().unwrap();

File::delete_from_s3(&file_info.hash, credentials, region)
File::delete_from_s3(file_info.id, &file_info.hash, credentials, region)
.await
.unwrap();
}
Expand All @@ -204,11 +226,11 @@ mod tests {
let file = File::new([1, 2, 3, 4].to_vec());

let res = file
.put_into_s3("hei", credentials.clone(), region.clone())
.put_into_s3(2, "hei", credentials.clone(), region.clone())
.await;
assert!(res.is_ok());

let res = File::delete_from_s3("hei", credentials, region).await;
let res = File::delete_from_s3(2, "hei", credentials, region).await;
assert!(res.is_ok());
}

Expand All @@ -224,17 +246,17 @@ mod tests {
let file = File::new([1, 2, 3].to_vec());

let res = file
.put_into_s3("hei", credentials.clone(), region.clone())
.put_into_s3(3, "hei", credentials.clone(), region.clone())
.await;
assert!(res.is_ok());

let file = File::get_from_s3("hei", credentials.clone(), region.clone())
let file = File::get_from_s3(3, "hei", credentials.clone(), region.clone())
.await
.unwrap();

assert_eq!(file.content, &[1, 2, 3]);

let res = File::delete_from_s3("hei", credentials, region).await;
let res = File::delete_from_s3(3, "hei", credentials, region).await;
assert!(res.is_ok());
}
}

0 comments on commit 6ad2041

Please sign in to comment.