upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/storage
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-11-19 11:55:32 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-11-19 15:43:29 +0000
commitfa065ad128882755f2a988d6203b59a2ab5e38ff (patch)
treee8326de70a6e6ea56b5bf4250e0a00a3cda4afed /src/storage
parent98c6fa4bfa897ff0b8f9c95ea698d4d065b5e9f3 (diff)
add landing page and nostr-relay-builder relay on same port
Diffstat (limited to 'src/storage')
-rw-r--r--src/storage/mod.rs132
1 files changed, 0 insertions, 132 deletions
diff --git a/src/storage/mod.rs b/src/storage/mod.rs
deleted file mode 100644
index eab8211..0000000
--- a/src/storage/mod.rs
+++ /dev/null
@@ -1,132 +0,0 @@
1use anyhow::Result;
2use nostr_sdk::Event;
3use std::collections::HashMap;
4use std::sync::Arc;
5use tokio::sync::RwLock;
6
7use crate::config::Config;
8
9/// Simple in-memory storage for events
10/// TODO: Persist to disk for production use
11#[derive(Clone)]
12pub struct Storage {
13 events: Arc<RwLock<HashMap<String, Event>>>,
14 data_path: String,
15 domain: String,
16}
17
18impl Storage {
19 pub fn new(config: &Config) -> Result<Self> {
20 // Create data directory if it doesn't exist
21 std::fs::create_dir_all(&config.relay_data_path)?;
22
23 Ok(Storage {
24 events: Arc::new(RwLock::new(HashMap::new())),
25 data_path: config.relay_data_path.clone(),
26 domain: config.domain.clone(),
27 })
28 }
29
30 pub fn get_domain(&self) -> String {
31 self.domain.clone()
32 }
33
34 pub async fn store_event(&self, event: Event) -> Result<()> {
35 let mut events = self.events.write().await;
36 events.insert(event.id.to_hex(), event);
37 Ok(())
38 }
39
40 pub async fn get_event(&self, event_id: &str) -> Option<Event> {
41 let events = self.events.read().await;
42 events.get(event_id).cloned()
43 }
44
45 pub async fn query_events<F>(&self, filter: F) -> Vec<Event>
46 where
47 F: Fn(&Event) -> bool,
48 {
49 let events = self.events.read().await;
50 events.values().filter(|e| filter(e)).cloned().collect()
51 }
52
53 pub async fn count_events(&self) -> usize {
54 let events = self.events.read().await;
55 events.len()
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use nostr_sdk::{EventBuilder, Keys, Kind};
63
64 #[tokio::test]
65 async fn test_store_and_retrieve() {
66 let config = Config {
67 domain: "test".to_string(),
68 owner_npub: "npub1test".to_string(),
69 relay_name: "test".to_string(),
70 relay_description: "test".to_string(),
71 git_data_path: "./test_data/git".to_string(),
72 relay_data_path: "./test_data/relay".to_string(),
73 bind_address: "127.0.0.1:8080".to_string(),
74 };
75
76 let storage = Storage::new(&config).unwrap();
77
78 // Create a test event
79 let keys = Keys::generate();
80 let event = EventBuilder::text_note("test content")
81 .sign_with_keys(&keys)
82 .unwrap();
83
84 // Store it
85 storage.store_event(event.clone()).await.unwrap();
86
87 // Retrieve it
88 let retrieved = storage.get_event(&event.id.to_hex()).await;
89 assert!(retrieved.is_some());
90 assert_eq!(retrieved.unwrap().id, event.id);
91
92 // Count events
93 assert_eq!(storage.count_events().await, 1);
94 }
95
96 #[tokio::test]
97 async fn test_query_events() {
98 let config = Config {
99 domain: "test".to_string(),
100 owner_npub: "npub1test".to_string(),
101 relay_name: "test".to_string(),
102 relay_description: "test".to_string(),
103 git_data_path: "./test_data/git".to_string(),
104 relay_data_path: "./test_data/relay".to_string(),
105 bind_address: "127.0.0.1:8080".to_string(),
106 };
107
108 let storage = Storage::new(&config).unwrap();
109
110 // Create multiple events
111 let keys = Keys::generate();
112 let event1 = EventBuilder::text_note("message 1")
113 .sign_with_keys(&keys)
114 .unwrap();
115 let event2 = EventBuilder::text_note("message 2")
116 .sign_with_keys(&keys)
117 .unwrap();
118
119 storage.store_event(event1.clone()).await.unwrap();
120 storage.store_event(event2.clone()).await.unwrap();
121
122 // Query all events
123 let all_events = storage.query_events(|_| true).await;
124 assert_eq!(all_events.len(), 2);
125
126 // Query by kind
127 let text_notes = storage
128 .query_events(|e| e.kind == Kind::TextNote)
129 .await;
130 assert_eq!(text_notes.len(), 2);
131 }
132}