Merge pull request #158 from zhaofengli/upsert-object-on-conflict

server: Upsert object row on conflict
This commit is contained in:
Zhaofeng Li 2024-08-13 10:21:27 -04:00 committed by GitHub
commit 26b9417bde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 19 deletions

View file

@ -46,7 +46,7 @@ use crate::database::entity::cache;
use crate::database::entity::chunk::{self, ChunkState, Entity as Chunk};
use crate::database::entity::chunkref::{self, Entity as ChunkRef};
use crate::database::entity::nar::{self, Entity as Nar, NarState};
use crate::database::entity::object::{self, Entity as Object};
use crate::database::entity::object::{self, Entity as Object, InsertExt};
use crate::database::entity::Json as DbJson;
use crate::database::{AtticDatabase, ChunkGuard, NarGuard};
@ -257,12 +257,6 @@ async fn upload_path_dedup(
.map_err(ServerError::database_error)?;
// Create a mapping granting the local cache access to the NAR
Object::delete_many()
.filter(object::Column::CacheId.eq(cache.id))
.filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string()))
.exec(&txn)
.await
.map_err(ServerError::database_error)?;
Object::insert({
let mut new_object = upload_info.to_active_model();
new_object.cache_id = Set(cache.id);
@ -271,6 +265,7 @@ async fn upload_path_dedup(
new_object.created_by = Set(username);
new_object
})
.on_conflict_do_update()
.exec(&txn)
.await
.map_err(ServerError::database_error)?;
@ -487,12 +482,6 @@ async fn upload_path_new_chunked(
.map_err(ServerError::database_error)?;
// Create a mapping granting the local cache access to the NAR
Object::delete_many()
.filter(object::Column::CacheId.eq(cache.id))
.filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string()))
.exec(&txn)
.await
.map_err(ServerError::database_error)?;
Object::insert({
let mut new_object = upload_info.to_active_model();
new_object.cache_id = Set(cache.id);
@ -501,6 +490,7 @@ async fn upload_path_new_chunked(
new_object.created_by = Set(username);
new_object
})
.on_conflict_do_update()
.exec(&txn)
.await
.map_err(ServerError::database_error)?;
@ -594,12 +584,6 @@ async fn upload_path_new_unchunked(
.map_err(ServerError::database_error)?;
// Create a mapping granting the local cache access to the NAR
Object::delete_many()
.filter(object::Column::CacheId.eq(cache.id))
.filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string()))
.exec(&txn)
.await
.map_err(ServerError::database_error)?;
Object::insert({
let mut new_object = upload_info.to_active_model();
new_object.cache_id = Set(cache.id);
@ -608,6 +592,7 @@ async fn upload_path_new_unchunked(
new_object.created_by = Set(username);
new_object
})
.on_conflict_do_update()
.exec(&txn)
.await
.map_err(ServerError::database_error)?;

View file

@ -6,6 +6,8 @@ use std::path::PathBuf;
use std::str::FromStr;
use sea_orm::entity::prelude::*;
use sea_orm::sea_query::OnConflict;
use sea_orm::Insert;
use super::nar::NarModel;
use super::Json;
@ -15,6 +17,10 @@ use attic::hash::Hash;
pub type ObjectModel = Model;
pub trait InsertExt {
fn on_conflict_do_update(self) -> Self;
}
/// An object in a binary cache.
#[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "object")]
@ -87,6 +93,27 @@ pub enum Relation {
Nar,
}
impl InsertExt for Insert<ActiveModel> {
fn on_conflict_do_update(self) -> Self {
self.on_conflict(
OnConflict::columns([Column::CacheId, Column::StorePathHash])
.update_columns([
Column::NarId,
Column::StorePath,
Column::References,
Column::System,
Column::Deriver,
Column::Sigs,
Column::Ca,
Column::CreatedAt,
Column::LastAccessedAt,
Column::CreatedBy,
])
.to_owned(),
)
}
}
impl Model {
/// Converts this object to a NarInfo.
pub fn to_nar_info(&self, nar: &NarModel) -> ServerResult<NarInfo> {