@@ -506,6 +506,7 @@ impl Keyring {
506506 #[ cfg_attr( feature = "tracing" , tracing:: instrument( skip( self , items) , fields( item_count = items. len( ) ) ) ) ]
507507 pub ( crate ) async fn create_items ( & self , items : Vec < ItemDefinition > ) -> Result < ( ) , Error > {
508508 let key = self . derive_key ( ) . await ?;
509+ let mut mtime = self . mtime . lock ( ) . await ;
509510 let mut keyring = self . keyring . write ( ) . await ;
510511
511512 #[ cfg( feature = "tracing" ) ]
@@ -523,7 +524,11 @@ impl Keyring {
523524 #[ cfg( feature = "tracing" ) ]
524525 tracing:: debug!( "Writing keyring back to the file" ) ;
525526 if let Some ( ref path) = self . path {
526- keyring. dump ( path, * self . mtime . lock ( ) . await ) . await ?;
527+ keyring. dump ( path, * mtime) . await ?;
528+ // Update mtime after successful write
529+ if let Ok ( modified) = fs:: metadata ( path) . await ?. modified ( ) {
530+ * mtime = Some ( modified) ;
531+ }
527532 }
528533 Ok ( ( ) )
529534 }
@@ -1492,4 +1497,70 @@ mod tests {
14921497
14931498 Ok ( ( ) )
14941499 }
1500+
1501+ #[ tokio:: test]
1502+ async fn bulk_create_items ( ) -> Result < ( ) , Error > {
1503+ let temp_dir = tempdir ( ) . unwrap ( ) ;
1504+ let keyring_path = temp_dir. path ( ) . join ( "bulk_create_test.keyring" ) ;
1505+ let keyring = Keyring :: load ( & keyring_path, strong_key ( ) ) . await ?;
1506+
1507+ // Prepare multiple items to create at once
1508+ let items_to_create = vec ! [
1509+ (
1510+ "Bulk Item 1" . to_string( ) ,
1511+ HashMap :: from( [
1512+ ( "app" . to_string( ) , "bulk-app" . to_string( ) ) ,
1513+ ( "user" . to_string( ) , "user1" . to_string( ) ) ,
1514+ ] ) ,
1515+ Secret :: text( "secret1" ) ,
1516+ false ,
1517+ ) ,
1518+ (
1519+ "Bulk Item 2" . to_string( ) ,
1520+ HashMap :: from( [
1521+ ( "app" . to_string( ) , "bulk-app" . to_string( ) ) ,
1522+ ( "user" . to_string( ) , "user2" . to_string( ) ) ,
1523+ ] ) ,
1524+ Secret :: text( "secret2" ) ,
1525+ false ,
1526+ ) ,
1527+ (
1528+ "Bulk Item 3" . to_string( ) ,
1529+ HashMap :: from( [
1530+ ( "app" . to_string( ) , "bulk-app" . to_string( ) ) ,
1531+ ( "user" . to_string( ) , "user3" . to_string( ) ) ,
1532+ ] ) ,
1533+ Secret :: text( "secret3" ) ,
1534+ false ,
1535+ ) ,
1536+ ] ;
1537+
1538+ // Create all items in bulk
1539+ keyring. create_items ( items_to_create) . await ?;
1540+ // Verify all items were created
1541+ let all_items = keyring
1542+ . search_items ( & HashMap :: from ( [ ( "app" , "bulk-app" ) ] ) )
1543+ . await ?;
1544+ assert_eq ! ( all_items. len( ) , 3 ) ;
1545+
1546+ // Test replace=true in bulk create
1547+ let replace_items = vec ! [ (
1548+ "Replaced Item" . to_string( ) ,
1549+ HashMap :: from( [
1550+ ( "app" . to_string( ) , "bulk-app" . to_string( ) ) ,
1551+ ( "user" . to_string( ) , "user1" . to_string( ) ) ,
1552+ ] ) ,
1553+ Secret :: text( "new_secret1" ) ,
1554+ true , // replace=true should remove existing item with same attributes
1555+ ) ] ;
1556+
1557+ keyring. create_items ( replace_items) . await ?;
1558+
1559+ // Verify the item was replaced - should still have 3 items total
1560+ let all_items_after = keyring
1561+ . search_items ( & HashMap :: from ( [ ( "app" , "bulk-app" ) ] ) )
1562+ . await ?;
1563+ assert_eq ! ( all_items_after. len( ) , 3 ) ;
1564+ Ok ( ( ) )
1565+ }
14951566}
0 commit comments