Skip to content

database: add MultiStorageDatabase #716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
* database: add `Events::first_owned` and `Events::last_owned` ([Yuki Kishimoto])
* database: impl `FlatBufferDecodeBorrowed` for `EventBorrow` ([Yuki Kishimoto])
* database: add `NostrDatabaseWipe` trait ([Yuki Kishimoto])
* database: add `MultiStorageDatabase` ([Yuki Kishimoto])
* pool: add `Relay::try_connect` ([Yuki Kishimoto])
* pool: add `Relay::wait_for_connection` ([Yuki Kishimoto])
* pool: add `RelayPool::try_connect` ([Yuki Kishimoto])
Expand Down
3 changes: 2 additions & 1 deletion crates/nostr-database/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use nostr::prelude::*;

pub mod helper;

use crate::wipe::NostrDatabaseWipe;
use crate::{DatabaseError, Events, Profile};

/// Database event status
Expand Down Expand Up @@ -94,7 +95,7 @@ where
/// Store for the nostr events.
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait NostrEventsDatabase: fmt::Debug + Send + Sync {
pub trait NostrEventsDatabase: NostrDatabaseWipe + fmt::Debug + Send + Sync {
/// Save [`Event`] into store
///
/// **This method assumes that [`Event`] was already verified**
Expand Down
3 changes: 3 additions & 0 deletions crates/nostr-database/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod events;
#[cfg(feature = "flatbuf")]
pub mod flatbuffers;
pub mod memory;
pub mod multi;
pub mod prelude;
pub mod profile;
mod wipe;
Expand Down Expand Up @@ -50,6 +51,8 @@ pub enum Backend {
SQLite,
/// IndexedDB
IndexedDB,
/// Multiple backends
MultiBackend,
/// Custom
Custom(String),
}
Expand Down
106 changes: 106 additions & 0 deletions crates/nostr-database/src/multi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

//! Multi-storage

use std::collections::HashSet;
use std::sync::Arc;

use async_trait::async_trait;
use nostr::nips::nip01::Coordinate;
use nostr::{Event, EventId, Filter, RelayUrl, Timestamp};

use crate::events::NostrEventsDatabase;
use crate::{
Backend, DatabaseError, DatabaseEventStatus, Events, NostrDatabase, NostrDatabaseWipe,
SaveEventStatus,
};

/// Multi-storage database
///
/// This struct allows using different types of backends.
// TODO: should be this the `NostrDatabase`? If yes, remove the `NostrDatabase` trait
#[derive(Debug, Clone)]
pub struct MultiStorageDatabase {
/// Events storage
pub events: Arc<dyn NostrEventsDatabase>,
// TODO: add future traits here
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl NostrDatabase for MultiStorageDatabase {
fn backend(&self) -> Backend {
Backend::MultiBackend
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl NostrEventsDatabase for MultiStorageDatabase {
async fn save_event(&self, event: &Event) -> Result<SaveEventStatus, DatabaseError> {
self.events.save_event(event).await
}

async fn check_id(&self, event_id: &EventId) -> Result<DatabaseEventStatus, DatabaseError> {
self.events.check_id(event_id).await
}

async fn has_coordinate_been_deleted(
&self,
coordinate: &Coordinate,
timestamp: &Timestamp,
) -> Result<bool, DatabaseError> {
self.events
.has_coordinate_been_deleted(coordinate, timestamp)
.await
}

async fn event_id_seen(
&self,
event_id: EventId,
relay_url: RelayUrl,
) -> Result<(), DatabaseError> {
self.events.event_id_seen(event_id, relay_url).await
}

async fn event_seen_on_relays(
&self,
event_id: &EventId,
) -> Result<Option<HashSet<RelayUrl>>, DatabaseError> {
self.events.event_seen_on_relays(event_id).await
}

async fn event_by_id(&self, id: &EventId) -> Result<Option<Event>, DatabaseError> {
self.events.event_by_id(id).await
}

async fn count(&self, filters: Vec<Filter>) -> Result<usize, DatabaseError> {
self.events.count(filters).await
}

async fn query(&self, filters: Vec<Filter>) -> Result<Events, DatabaseError> {
self.events.query(filters).await
}

async fn negentropy_items(
&self,
filter: Filter,
) -> Result<Vec<(EventId, Timestamp)>, DatabaseError> {
self.events.negentropy_items(filter).await
}

async fn delete(&self, filter: Filter) -> Result<(), DatabaseError> {
self.events.delete(filter).await
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl NostrDatabaseWipe for MultiStorageDatabase {
async fn wipe(&self) -> Result<(), DatabaseError> {
self.events.wipe().await?;
Ok(())
}
}
1 change: 1 addition & 0 deletions crates/nostr-database/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ pub use nostr::prelude::*;

// Internal modules
pub use crate::memory::{self, *};
pub use crate::multi::{self, *};
pub use crate::*;
Loading