A fork of attic a self-hostable Nix Binary Cache server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

server: Upsert object row on conflict

authored by

Zhaofeng Li and committed by
GitHub
26b9417b e127acbf

+31 -19
+4 -19
server/src/api/v1/upload_path.rs
··· 46 46 use crate::database::entity::chunk::{self, ChunkState, Entity as Chunk}; 47 47 use crate::database::entity::chunkref::{self, Entity as ChunkRef}; 48 48 use crate::database::entity::nar::{self, Entity as Nar, NarState}; 49 - use crate::database::entity::object::{self, Entity as Object}; 49 + use crate::database::entity::object::{self, Entity as Object, InsertExt}; 50 50 use crate::database::entity::Json as DbJson; 51 51 use crate::database::{AtticDatabase, ChunkGuard, NarGuard}; 52 52 ··· 257 257 .map_err(ServerError::database_error)?; 258 258 259 259 // Create a mapping granting the local cache access to the NAR 260 - Object::delete_many() 261 - .filter(object::Column::CacheId.eq(cache.id)) 262 - .filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string())) 263 - .exec(&txn) 264 - .await 265 - .map_err(ServerError::database_error)?; 266 260 Object::insert({ 267 261 let mut new_object = upload_info.to_active_model(); 268 262 new_object.cache_id = Set(cache.id); ··· 271 265 new_object.created_by = Set(username); 272 266 new_object 273 267 }) 268 + .on_conflict_do_update() 274 269 .exec(&txn) 275 270 .await 276 271 .map_err(ServerError::database_error)?; ··· 487 482 .map_err(ServerError::database_error)?; 488 483 489 484 // Create a mapping granting the local cache access to the NAR 490 - Object::delete_many() 491 - .filter(object::Column::CacheId.eq(cache.id)) 492 - .filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string())) 493 - .exec(&txn) 494 - .await 495 - .map_err(ServerError::database_error)?; 496 485 Object::insert({ 497 486 let mut new_object = upload_info.to_active_model(); 498 487 new_object.cache_id = Set(cache.id); ··· 501 490 new_object.created_by = Set(username); 502 491 new_object 503 492 }) 493 + .on_conflict_do_update() 504 494 .exec(&txn) 505 495 .await 506 496 .map_err(ServerError::database_error)?; ··· 594 584 .map_err(ServerError::database_error)?; 595 585 596 586 // Create a mapping granting the local cache access to the NAR 597 - Object::delete_many() 598 - .filter(object::Column::CacheId.eq(cache.id)) 599 - .filter(object::Column::StorePathHash.eq(upload_info.store_path_hash.to_string())) 600 - .exec(&txn) 601 - .await 602 - .map_err(ServerError::database_error)?; 603 587 Object::insert({ 604 588 let mut new_object = upload_info.to_active_model(); 605 589 new_object.cache_id = Set(cache.id); ··· 608 592 new_object.created_by = Set(username); 609 593 new_object 610 594 }) 595 + .on_conflict_do_update() 611 596 .exec(&txn) 612 597 .await 613 598 .map_err(ServerError::database_error)?;
+27
server/src/database/entity/object.rs
··· 6 6 use std::str::FromStr; 7 7 8 8 use sea_orm::entity::prelude::*; 9 + use sea_orm::sea_query::OnConflict; 10 + use sea_orm::Insert; 9 11 10 12 use super::nar::NarModel; 11 13 use super::Json; ··· 14 16 use attic::hash::Hash; 15 17 16 18 pub type ObjectModel = Model; 19 + 20 + pub trait InsertExt { 21 + fn on_conflict_do_update(self) -> Self; 22 + } 17 23 18 24 /// An object in a binary cache. 19 25 #[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel)] ··· 85 91 to = "super::nar::Column::Id" 86 92 )] 87 93 Nar, 94 + } 95 + 96 + impl InsertExt for Insert<ActiveModel> { 97 + fn on_conflict_do_update(self) -> Self { 98 + self.on_conflict( 99 + OnConflict::columns([Column::CacheId, Column::StorePathHash]) 100 + .update_columns([ 101 + Column::NarId, 102 + Column::StorePath, 103 + Column::References, 104 + Column::System, 105 + Column::Deriver, 106 + Column::Sigs, 107 + Column::Ca, 108 + Column::CreatedAt, 109 + Column::LastAccessedAt, 110 + Column::CreatedBy, 111 + ]) 112 + .to_owned(), 113 + ) 114 + } 88 115 } 89 116 90 117 impl Model {