|
2 | 2 |
|
3 | 3 | use std::collections::BTreeSet;
|
4 | 4 |
|
5 |
| -use nostr::PublicKey; |
| 5 | +use nostr::{PublicKey, RelayUrl}; |
6 | 6 | use nostr_mls_storage::groups::error::GroupError;
|
7 | 7 | use nostr_mls_storage::groups::types::{Group, GroupExporterSecret, GroupRelay};
|
8 | 8 | use nostr_mls_storage::groups::GroupStorage;
|
@@ -192,29 +192,42 @@ impl GroupStorage for NostrMlsSqliteStorage {
|
192 | 192 | Ok(relays)
|
193 | 193 | }
|
194 | 194 |
|
195 |
| - fn save_group_relay(&self, group_relay: GroupRelay) -> Result<(), GroupError> { |
| 195 | + fn replace_group_relays( |
| 196 | + &self, |
| 197 | + group_id: &GroupId, |
| 198 | + relays: BTreeSet<RelayUrl>, |
| 199 | + ) -> Result<(), GroupError> { |
196 | 200 | // First verify the group exists
|
197 |
| - if self |
198 |
| - .find_group_by_mls_group_id(&group_relay.mls_group_id)? |
199 |
| - .is_none() |
200 |
| - { |
| 201 | + if self.find_group_by_mls_group_id(group_id)?.is_none() { |
201 | 202 | return Err(GroupError::InvalidParameters(format!(
|
202 | 203 | "Group with MLS ID {:?} not found",
|
203 |
| - group_relay.mls_group_id |
| 204 | + group_id |
204 | 205 | )));
|
205 | 206 | }
|
206 | 207 |
|
207 | 208 | let conn_guard = self.db_connection.lock().map_err(into_group_err)?;
|
208 | 209 |
|
209 |
| - conn_guard |
210 |
| - .execute( |
211 |
| - "INSERT OR REPLACE INTO group_relays (mls_group_id, relay_url) VALUES (?, ?)", |
212 |
| - params![ |
213 |
| - group_relay.mls_group_id.as_slice(), |
214 |
| - group_relay.relay_url.as_str() |
215 |
| - ], |
| 210 | + // Use a transaction for atomicity |
| 211 | + let tx = conn_guard.unchecked_transaction().map_err(into_group_err)?; |
| 212 | + |
| 213 | + // Clear existing relays for this group |
| 214 | + tx.execute( |
| 215 | + "DELETE FROM group_relays WHERE mls_group_id = ?", |
| 216 | + params![group_id.as_slice()], |
| 217 | + ) |
| 218 | + .map_err(into_group_err)?; |
| 219 | + |
| 220 | + // Insert new relays |
| 221 | + for relay_url in relays { |
| 222 | + tx.execute( |
| 223 | + "INSERT INTO group_relays (mls_group_id, relay_url) VALUES (?, ?)", |
| 224 | + params![group_id.as_slice(), relay_url.as_str()], |
216 | 225 | )
|
217 | 226 | .map_err(into_group_err)?;
|
| 227 | + } |
| 228 | + |
| 229 | + // Commit the transaction |
| 230 | + tx.commit().map_err(into_group_err)?; |
218 | 231 |
|
219 | 232 | Ok(())
|
220 | 233 | }
|
@@ -276,7 +289,6 @@ impl GroupStorage for NostrMlsSqliteStorage {
|
276 | 289 | mod tests {
|
277 | 290 | use aes_gcm::aead::OsRng;
|
278 | 291 | use aes_gcm::{Aes128Gcm, KeyInit};
|
279 |
| - use nostr::RelayUrl; |
280 | 292 | use nostr_mls_storage::groups::types::GroupState;
|
281 | 293 |
|
282 | 294 | use super::*;
|
@@ -335,51 +347,8 @@ mod tests {
|
335 | 347 | assert_eq!(all_groups.len(), 1);
|
336 | 348 | }
|
337 | 349 |
|
338 |
| - #[test] |
339 |
| - fn test_group_relay() { |
340 |
| - let storage = NostrMlsSqliteStorage::new_in_memory().unwrap(); |
341 |
| - |
342 |
| - // Create a test group |
343 |
| - let mls_group_id = GroupId::from_slice(&[1, 2, 3, 4]); |
344 |
| - let mut nostr_group_id = [0u8; 32]; |
345 |
| - nostr_group_id[0..13].copy_from_slice(b"test_group_12"); |
346 |
| - |
347 |
| - let group = Group { |
348 |
| - mls_group_id: mls_group_id.clone(), |
349 |
| - nostr_group_id, |
350 |
| - name: "Test Group".to_string(), |
351 |
| - description: "A test group".to_string(), |
352 |
| - admin_pubkeys: BTreeSet::new(), |
353 |
| - last_message_id: None, |
354 |
| - last_message_at: None, |
355 |
| - epoch: 0, |
356 |
| - state: GroupState::Active, |
357 |
| - image_url: None, |
358 |
| - image_key: None, |
359 |
| - image_nonce: None, |
360 |
| - }; |
361 |
| - |
362 |
| - // Save the group |
363 |
| - storage.save_group(group).unwrap(); |
364 |
| - |
365 |
| - // Create a group relay |
366 |
| - let relay_url = RelayUrl::parse("wss://relay.example.com").unwrap(); |
367 |
| - let group_relay = GroupRelay { |
368 |
| - mls_group_id: mls_group_id.clone(), |
369 |
| - relay_url, |
370 |
| - }; |
371 |
| - |
372 |
| - // Save the group relay |
373 |
| - storage.save_group_relay(group_relay).unwrap(); |
374 |
| - |
375 |
| - // Get group relays |
376 |
| - let relays = storage.group_relays(&mls_group_id).unwrap(); |
377 |
| - assert_eq!(relays.len(), 1); |
378 |
| - assert_eq!( |
379 |
| - relays.first().unwrap().relay_url.to_string(), |
380 |
| - "wss://relay.example.com" |
381 |
| - ); |
382 |
| - } |
| 350 | + // Note: Comprehensive storage functionality tests are now in nostr-mls-storage/tests/ |
| 351 | + // using shared test functions to ensure consistency between storage implementations |
383 | 352 |
|
384 | 353 | #[test]
|
385 | 354 | fn test_group_exporter_secret() {
|
|
0 commit comments