@@ -388,6 +388,38 @@ impl<Tbl: Table, Col: Index + Column<Table = Tbl>> UniqueColumn<Tbl, Col::ColTyp
388
388
let buf = IterBuf :: take ( ) ;
389
389
update :: < Tbl > ( Col :: index_id ( ) , new_row, buf)
390
390
}
391
+
392
+ /// Inserts `new_row` into the table, first checking for an existing
393
+ /// row with a matching value in the unique column and deleting it if present.
394
+ ///
395
+ /// Be careful: in case of a constraint violation, this method will return Err,
396
+ /// but the previous row will be deleted. If you propagate the error, SpacetimeDB will
397
+ /// rollback the transaction and the old row will be restored. If you ignore the error,
398
+ /// the old row will be lost.
399
+ #[ track_caller]
400
+ #[ doc( alias = "try_upsert" ) ]
401
+ #[ cfg( feature = "unstable" ) ]
402
+ pub fn try_insert_or_update ( & self , new_row : Tbl :: Row ) -> Result < Tbl :: Row , TryInsertError < Tbl > > {
403
+ let col_val = Col :: get_field ( & new_row) ;
404
+ // If the row doesn't exist, delete will return false, which we ignore.
405
+ let _ = self . delete ( col_val) ;
406
+
407
+ // Then, insert the new row.
408
+ let buf = IterBuf :: take ( ) ;
409
+ insert :: < Tbl > ( new_row, buf)
410
+ }
411
+
412
+ /// Inserts `new_row` into the table, first checking for an existing
413
+ /// row with a matching value in the unique column and deleting it if present.
414
+ ///
415
+ /// # Panics
416
+ /// Panics if either the delete or the insertion would violate a constraint.
417
+ #[ track_caller]
418
+ #[ doc( alias = "upsert" ) ]
419
+ #[ cfg( feature = "unstable" ) ]
420
+ pub fn insert_or_update ( & self , new_row : Tbl :: Row ) -> Tbl :: Row {
421
+ self . try_insert_or_update ( new_row) . unwrap_or_else ( |e| panic ! ( "{e}" ) )
422
+ }
391
423
}
392
424
393
425
pub trait Index {
0 commit comments