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::chunk::{self, ChunkState, Entity as Chunk};
|
||||||
use crate::database::entity::chunkref::{self, Entity as ChunkRef};
|
use crate::database::entity::chunkref::{self, Entity as ChunkRef};
|
||||||
use crate::database::entity::nar::{self, Entity as Nar, NarState};
|
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::entity::Json as DbJson;
|
||||||
use crate::database::{AtticDatabase, ChunkGuard, NarGuard};
|
use crate::database::{AtticDatabase, ChunkGuard, NarGuard};
|
||||||
|
|
||||||
|
@ -257,12 +257,6 @@ async fn upload_path_dedup(
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
|
||||||
// Create a mapping granting the local cache access to the NAR
|
// 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({
|
Object::insert({
|
||||||
let mut new_object = upload_info.to_active_model();
|
let mut new_object = upload_info.to_active_model();
|
||||||
new_object.cache_id = Set(cache.id);
|
new_object.cache_id = Set(cache.id);
|
||||||
|
@ -271,6 +265,7 @@ async fn upload_path_dedup(
|
||||||
new_object.created_by = Set(username);
|
new_object.created_by = Set(username);
|
||||||
new_object
|
new_object
|
||||||
})
|
})
|
||||||
|
.on_conflict_do_update()
|
||||||
.exec(&txn)
|
.exec(&txn)
|
||||||
.await
|
.await
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
@ -487,12 +482,6 @@ async fn upload_path_new_chunked(
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
|
||||||
// Create a mapping granting the local cache access to the NAR
|
// 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({
|
Object::insert({
|
||||||
let mut new_object = upload_info.to_active_model();
|
let mut new_object = upload_info.to_active_model();
|
||||||
new_object.cache_id = Set(cache.id);
|
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.created_by = Set(username);
|
||||||
new_object
|
new_object
|
||||||
})
|
})
|
||||||
|
.on_conflict_do_update()
|
||||||
.exec(&txn)
|
.exec(&txn)
|
||||||
.await
|
.await
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
@ -594,12 +584,6 @@ async fn upload_path_new_unchunked(
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
|
||||||
// Create a mapping granting the local cache access to the NAR
|
// 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({
|
Object::insert({
|
||||||
let mut new_object = upload_info.to_active_model();
|
let mut new_object = upload_info.to_active_model();
|
||||||
new_object.cache_id = Set(cache.id);
|
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.created_by = Set(username);
|
||||||
new_object
|
new_object
|
||||||
})
|
})
|
||||||
|
.on_conflict_do_update()
|
||||||
.exec(&txn)
|
.exec(&txn)
|
||||||
.await
|
.await
|
||||||
.map_err(ServerError::database_error)?;
|
.map_err(ServerError::database_error)?;
|
||||||
|
|
|
@ -6,6 +6,8 @@ use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
use sea_orm::sea_query::OnConflict;
|
||||||
|
use sea_orm::Insert;
|
||||||
|
|
||||||
use super::nar::NarModel;
|
use super::nar::NarModel;
|
||||||
use super::Json;
|
use super::Json;
|
||||||
|
@ -15,6 +17,10 @@ use attic::hash::Hash;
|
||||||
|
|
||||||
pub type ObjectModel = Model;
|
pub type ObjectModel = Model;
|
||||||
|
|
||||||
|
pub trait InsertExt {
|
||||||
|
fn on_conflict_do_update(self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
/// An object in a binary cache.
|
/// An object in a binary cache.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel)]
|
#[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel)]
|
||||||
#[sea_orm(table_name = "object")]
|
#[sea_orm(table_name = "object")]
|
||||||
|
@ -87,6 +93,27 @@ pub enum Relation {
|
||||||
Nar,
|
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 {
|
impl Model {
|
||||||
/// Converts this object to a NarInfo.
|
/// Converts this object to a NarInfo.
|
||||||
pub fn to_nar_info(&self, nar: &NarModel) -> ServerResult<NarInfo> {
|
pub fn to_nar_info(&self, nar: &NarModel) -> ServerResult<NarInfo> {
|
||||||
|
|
Loading…
Reference in a new issue