/// Basic OSIRIS usage example /// /// This example demonstrates: /// - Creating objects with the derive macro /// - Storing objects in HeroDB /// - Querying by indexed fields /// - Retrieving objects /// /// Prerequisites: /// - HeroDB running on localhost:6379 /// /// Run with: /// ```bash /// cargo run --example basic_usage /// ``` use osiris::objects::{Event, Note}; use osiris::store::{BaseData, GenericStore, HeroDbClient}; use osiris::Object; use std::collections::BTreeMap; use time::OffsetDateTime; #[tokio::main] async fn main() -> Result<(), Box> { println!("๐Ÿš€ OSIRIS Basic Usage Example\n"); // Initialize HeroDB client println!("๐Ÿ“ก Connecting to HeroDB..."); let client = HeroDbClient::new("redis://localhost:6379", 1)?; let store = GenericStore::new(client); println!("โœ“ Connected to HeroDB (DB 1)\n"); // ======================================== // Part 1: Working with Notes // ======================================== println!("๐Ÿ“ Part 1: Working with Notes"); println!("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n"); // Create a note with tags let note1 = Note::new("notes".to_string()) .set_title("OSIRIS Architecture") .set_content("OSIRIS uses a trait-based architecture with automatic indexing based on #[index] attributes.") .add_tag("topic", "architecture") .add_tag("project", "osiris") .add_tag("priority", "high") .set_mime("text/plain"); println!("Creating note: {}", note1.title.as_ref().unwrap()); println!(" ID: {}", note1.base_data.id); println!(" Tags: {:?}", note1.tags); // Store the note store.put(¬e1).await?; println!("โœ“ Note stored\n"); // Create another note let note2 = Note::new("notes".to_string()) .set_title("HeroDB Integration") .set_content("HeroDB provides encrypted storage with Redis compatibility.") .add_tag("topic", "storage") .add_tag("project", "osiris") .add_tag("priority", "medium") .set_mime("text/plain"); println!("Creating note: {}", note2.title.as_ref().unwrap()); println!(" ID: {}", note2.base_data.id); store.put(¬e2).await?; println!("โœ“ Note stored\n"); // Retrieve a note by ID println!("Retrieving note by ID..."); let retrieved_note: Note = store.get("notes", ¬e1.base_data.id).await?; println!("โœ“ Retrieved: {}", retrieved_note.title.as_ref().unwrap()); println!(" Content: {}\n", retrieved_note.content.as_ref().unwrap_or(&"(none)".to_string())); // Query notes by tag println!("Querying notes by tag (project=osiris)..."); let ids = store.get_ids_by_index("notes", "tags:tag", "project=osiris").await?; println!("โœ“ Found {} notes with tag project=osiris", ids.len()); for id in &ids { let note: Note = store.get("notes", id).await?; println!(" - {}", note.title.as_ref().unwrap_or(&"(untitled)".to_string())); } println!(); // Query by different tag println!("Querying notes by tag (priority=high)..."); let high_priority_ids = store.get_ids_by_index("notes", "tags:tag", "priority=high").await?; println!("โœ“ Found {} high-priority notes\n", high_priority_ids.len()); // ======================================== // Part 2: Working with Events // ======================================== println!("๐Ÿ“… Part 2: Working with Events"); println!("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n"); use osiris::objects::event::EventStatus; // Create an event let now = OffsetDateTime::now_utc(); let event1 = Event::new("calendar".to_string(), "Team Standup") .set_description("Daily standup meeting") .set_start_time(now) .set_end_time(now + time::Duration::minutes(30)) .set_location("Room 101") .set_status(EventStatus::Published) .set_category("meetings") .set_all_day(false); println!("Creating event: {}", event1.title); println!(" ID: {}", event1.base_data.id); println!(" Location: {}", event1.location.as_ref().unwrap()); println!(" Status: {:?}", event1.status); store.put(&event1).await?; println!("โœ“ Event stored\n"); // Create another event let tomorrow = now + time::Duration::days(1); let event2 = Event::new("calendar".to_string(), "Project Review") .set_description("Review OSIRIS implementation progress") .set_start_time(tomorrow) .set_end_time(tomorrow + time::Duration::hours(1)) .set_location("Conference Room A") .set_status(EventStatus::Published) .set_category("reviews"); println!("Creating event: {}", event2.title); store.put(&event2).await?; println!("โœ“ Event stored\n"); // Query events by location println!("Querying events by location (Room 101)..."); let location_ids = store.get_ids_by_index("calendar", "location", "Room 101").await?; println!("โœ“ Found {} events in Room 101", location_ids.len()); for id in &location_ids { let event: Event = store.get("calendar", id).await?; println!(" - {}", event.title); } println!(); // Query events by status println!("Querying events by status (Published)..."); let status_ids = store.get_ids_by_index("calendar", "status", "Published").await?; println!("โœ“ Found {} published events", status_ids.len()); for id in &status_ids { let event: Event = store.get("calendar", id).await?; println!(" - {} ({})", event.title, event.category.as_ref().unwrap_or(&"uncategorized".to_string())); } println!(); // Query events by date let date_str = now.date().to_string(); println!("Querying events by date ({})...", date_str); let date_ids = store.get_ids_by_index("calendar", "start_time", &date_str).await?; println!("โœ“ Found {} events on {}", date_ids.len(), date_str); println!(); // ======================================== // Part 3: Demonstrating Auto-Generated Indexes // ======================================== println!("๐Ÿ” Part 3: Auto-Generated Indexes"); println!("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n"); println!("Note indexed fields: {:?}", Note::indexed_fields()); println!("Event indexed fields: {:?}", Event::indexed_fields()); println!(); println!("Note index keys for '{}': ", note1.title.as_ref().unwrap()); for key in note1.index_keys() { println!(" - {} = {}", key.name, key.value); } println!(); println!("Event index keys for '{}': ", event1.title); for key in event1.index_keys() { println!(" - {} = {}", key.name, key.value); } println!(); // ======================================== // Part 4: Cleanup // ======================================== println!("๐Ÿงน Part 4: Cleanup"); println!("โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n"); println!("Deleting notes..."); store.delete(¬e1).await?; store.delete(¬e2).await?; println!("โœ“ Notes deleted\n"); println!("Deleting events..."); store.delete(&event1).await?; store.delete(&event2).await?; println!("โœ“ Events deleted\n"); println!("โœ… Example completed successfully!"); Ok(()) }