@@ -315,28 +315,28 @@ pub(crate) async fn persist_batch(
315315 } )
316316}
317317
318- /// Persists and recalculates every affected UID in one transaction.
318+ /// Persists and recalculates every submitted UID in one transaction.
319319///
320320/// A persistence or calculation failure rolls back every game represented by
321- /// the batch, which is required for multi-game UIGF imports.
321+ /// the batch, which is required for multi-game UIGF imports. Recalculation also
322+ /// runs when every pull already exists so reimporting refreshes stats after an
323+ /// administrator changes banner metadata.
322324pub ( crate ) async fn persist_batch_in_transaction (
323325 batch : & ImportBatch ,
324326 pool : & PgPool ,
325327) -> anyhow:: Result < PersistenceSummary > {
326328 let mut transaction = pool. begin ( ) . await ?;
327329 let summary = persist_batch ( batch, & mut transaction) . await ?;
328- if summary. changed_records > 0 {
329- for ( game, uid) in batch. affected_uids ( ) {
330- match game {
331- PullGame :: Hsr => {
332- crate :: gacha:: stats:: hsr:: recalculate_hsr_uid ( uid, & mut transaction) . await ?
333- }
334- PullGame :: Gi => {
335- crate :: gacha:: stats:: gi:: recalculate_gi_uid ( uid, & mut transaction) . await ?
336- }
337- PullGame :: Zzz => {
338- crate :: gacha:: stats:: zzz:: recalculate_zzz_uid ( uid, & mut transaction) . await ?
339- }
330+ for ( game, uid) in batch. affected_uids ( ) {
331+ match game {
332+ PullGame :: Hsr => {
333+ crate :: gacha:: stats:: hsr:: recalculate_hsr_uid ( uid, & mut transaction) . await ?
334+ }
335+ PullGame :: Gi => {
336+ crate :: gacha:: stats:: gi:: recalculate_gi_uid ( uid, & mut transaction) . await ?
337+ }
338+ PullGame :: Zzz => {
339+ crate :: gacha:: stats:: zzz:: recalculate_zzz_uid ( uid, & mut transaction) . await ?
340340 }
341341 }
342342 }
@@ -864,6 +864,41 @@ mod gacha_import_db {
864864 assert_eq ! ( count, 1 , "{table} is current before return" ) ;
865865 }
866866
867+ for table in [
868+ "warps_stats_standard" ,
869+ "gi_wishes_stats_standard" ,
870+ "zzz_signals_stats_standard" ,
871+ ] {
872+ sqlx:: query ( & format ! ( "DELETE FROM {table} WHERE uid = $1" ) )
873+ . bind ( uid)
874+ . execute ( & pool)
875+ . await
876+ . unwrap ( ) ;
877+ }
878+
879+ assert_eq ! (
880+ persist_batch_in_transaction( & valid, & pool)
881+ . await
882+ . unwrap( )
883+ . changed_records,
884+ 0 ,
885+ "an identical reimport should still recalculate stats"
886+ ) ;
887+
888+ for table in [
889+ "warps_stats_standard" ,
890+ "gi_wishes_stats_standard" ,
891+ "zzz_signals_stats_standard" ,
892+ ] {
893+ let count: i64 =
894+ sqlx:: query_scalar ( & format ! ( "SELECT COUNT(*) FROM {table} WHERE uid = $1" ) )
895+ . bind ( uid)
896+ . fetch_one ( & pool)
897+ . await
898+ . unwrap ( ) ;
899+ assert_eq ! ( count, 1 , "{table} is refreshed by an identical reimport" ) ;
900+ }
901+
867902 sqlx:: query ( "DELETE FROM mihomo WHERE uid = $1" )
868903 . bind ( uid)
869904 . execute ( & pool)
0 commit comments