server: Upsert object row on conflict
Upsert instead of doing delete+insert or ignoring the specific error. Fixes #132.
This commit is contained in:
parent
e127acbf9a
commit
443ceac40f
|
@ -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)?;
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Reference in a new issue