-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
534 additions
and
245 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use super::dht::*; | ||
use super::posts::*; | ||
use super::users::*; | ||
use crate::fs::FS_PATH; | ||
use miette::IntoDiagnostic; | ||
use native_db::*; | ||
use std::{path::PathBuf, sync::LazyLock}; | ||
|
||
pub(crate) static DATABASE_PATH: LazyLock<PathBuf> = | ||
LazyLock::new(|| PathBuf::from(FS_PATH).join("OKU_FS_DATABASE")); | ||
/// An Oku node's database. | ||
pub static DATABASE: LazyLock<OkuDatabase> = LazyLock::new(|| OkuDatabase::new().unwrap()); | ||
pub(crate) static MODELS: LazyLock<Models> = LazyLock::new(|| { | ||
let mut models = Models::new(); | ||
models.define::<OkuUser>().unwrap(); | ||
models.define::<OkuPost>().unwrap(); | ||
models.define::<ReplicaAnnouncement>().unwrap(); | ||
models | ||
}); | ||
|
||
/// The database used by Oku's protocol. | ||
pub struct OkuDatabase { | ||
pub(crate) database: Database<'static>, | ||
} | ||
|
||
impl OkuDatabase { | ||
/// Open an existing Oku database, or create one if it does not exist. | ||
/// | ||
/// # Returns | ||
/// | ||
/// An Oku database. | ||
pub fn new() -> miette::Result<Self> { | ||
Ok(Self { | ||
database: native_db::Builder::new() | ||
.create(&MODELS, &*DATABASE_PATH) | ||
.into_diagnostic()?, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
use super::core::*; | ||
use miette::IntoDiagnostic; | ||
use native_db::*; | ||
use native_model::{native_model, Model}; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone)] | ||
#[native_model(id = 3, version = 1)] | ||
#[native_db( | ||
primary_key(primary_key -> (Vec<u8>, Vec<u8>)) | ||
)] | ||
/// A record of a replica announcement on the DHT. | ||
pub struct ReplicaAnnouncement { | ||
/// The public key of the announcement. | ||
#[primary_key] | ||
pub key: Vec<u8>, | ||
/// The signature of the announcement. | ||
pub signature: Vec<u8>, | ||
} | ||
|
||
impl OkuDatabase { | ||
/// Insert or update a replica announcement record. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `announcement` - A replica announcement record to upsert. | ||
/// | ||
/// # Returns | ||
/// | ||
/// The previous record of the announcement, if one existed. | ||
pub fn upsert_announcement( | ||
&self, | ||
announcement: ReplicaAnnouncement, | ||
) -> miette::Result<Option<ReplicaAnnouncement>> { | ||
let rw = self.database.rw_transaction().into_diagnostic()?; | ||
let old_value: Option<ReplicaAnnouncement> = rw.upsert(announcement).into_diagnostic()?; | ||
rw.commit().into_diagnostic()?; | ||
Ok(old_value) | ||
} | ||
|
||
/// Insert or update multiple replica announcement records. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `announcements` - A list of replica announcement records to upsert. | ||
/// | ||
/// # Returns | ||
/// | ||
/// A list containing the previous record of each announcement, if one existed. | ||
pub fn upsert_announcements( | ||
&self, | ||
announcements: Vec<ReplicaAnnouncement>, | ||
) -> miette::Result<Vec<Option<ReplicaAnnouncement>>> { | ||
let rw = self.database.rw_transaction().into_diagnostic()?; | ||
let old_announcements: Vec<_> = announcements | ||
.clone() | ||
.into_iter() | ||
.filter_map(|announcement| rw.upsert(announcement).ok()) | ||
.collect(); | ||
rw.commit().into_diagnostic()?; | ||
Ok(old_announcements) | ||
} | ||
|
||
/// Delete a replica announcement record. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `announcement` - A replica announcement record to delete. | ||
/// | ||
/// # Returns | ||
/// | ||
/// The deleted replica announcement record. | ||
pub fn delete_announcement( | ||
&self, | ||
announcement: ReplicaAnnouncement, | ||
) -> miette::Result<ReplicaAnnouncement> { | ||
let rw = self.database.rw_transaction().into_diagnostic()?; | ||
let removed_announcement = rw.remove(announcement).into_diagnostic()?; | ||
rw.commit().into_diagnostic()?; | ||
Ok(removed_announcement) | ||
} | ||
|
||
/// Delete multiple replica announcement records. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `announcements` - A list of replica announcement records to delete. | ||
/// | ||
/// # Returns | ||
/// | ||
/// A list containing the deleted replica announcement records. | ||
pub fn delete_announcements( | ||
&self, | ||
announcements: Vec<ReplicaAnnouncement>, | ||
) -> miette::Result<Vec<ReplicaAnnouncement>> { | ||
let rw = self.database.rw_transaction().into_diagnostic()?; | ||
let removed_announcements = announcements | ||
.into_iter() | ||
.filter_map(|announcement| rw.remove(announcement).ok()) | ||
.collect(); | ||
rw.commit().into_diagnostic()?; | ||
Ok(removed_announcements) | ||
} | ||
|
||
/// Gets the replica announcements recorded by this node. | ||
/// | ||
/// # Returns | ||
/// | ||
/// The replica announcements recorded by this node. | ||
pub fn get_announcements(&self) -> miette::Result<Vec<ReplicaAnnouncement>> { | ||
let r = self.database.r_transaction().into_diagnostic()?; | ||
r.scan() | ||
.primary() | ||
.into_diagnostic()? | ||
.all() | ||
.into_diagnostic()? | ||
.collect::<Result<Vec<_>, _>>() | ||
.into_diagnostic() | ||
} | ||
|
||
/// Gets a replica announcement record by its public key. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `key` - The public key of the DHT announcement. | ||
/// | ||
/// # Returns | ||
/// | ||
/// A replica announcement record. | ||
pub fn get_announcement(&self, key: Vec<u8>) -> miette::Result<Option<ReplicaAnnouncement>> { | ||
let r = self.database.r_transaction().into_diagnostic()?; | ||
r.get().primary(key).into_diagnostic() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/// Core functionality of an OkuNet node's database. | ||
pub mod core; | ||
/// Database functionality relating to the DHT. | ||
pub mod dht; | ||
/// Database functionality relating to OkuNet posts. | ||
pub mod posts; | ||
/// Database functionality relating to OkuNet users. | ||
pub mod users; |
Oops, something went wrong.