Skip to content

Commit

Permalink
[docs] Add intra documentation links #718 (#737)
Browse files Browse the repository at this point in the history
* add doc links

* Update lib.rs
  • Loading branch information
michaelvlach authored Sep 16, 2023
1 parent 64f2c74 commit 0f0bb50
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 28 deletions.
37 changes: 29 additions & 8 deletions agdb/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,20 @@ impl Serialize for DbStorageIndex {
///
/// These are the available variants of the database to choose from:
///
/// - `Db`: [default] File based and memory mapped database.
/// - `DbFile`: File based only (no memory mapping).
/// - `DbMemory`: In-memory database only.
/// - [`Db`]: \[default] File based and memory mapped database.
/// - [`DbFile`]: File based only (no memory mapping).
/// - [`DbMemory`]: In-memory database only.
///
/// For each of these there are convenient using declarations, e.g. `DbTransaction`,
/// `DbFileTransaction`, `DbMemoryTransactionMut` etc. in case you need to name
/// the related types of the main database type.
///
/// You can execute queries or transactions on the database object with
///
/// - exec() //immutable queries
/// - exec_mut() //mutable queries
/// - transaction() //immutable transactions
/// - transaction_mut() // mutable transaction
/// - [exec()](#method.exec) //immutable queries
/// - [exec_mut()](#method.exec_mut) //mutable queries
/// - [transaction()](#method.transaction) //immutable transactions
/// - [transaction_mut()](#method.transaction_mut) // mutable transaction
///
/// # Examples
///
Expand Down Expand Up @@ -173,7 +173,7 @@ impl Serialize for DbStorageIndex {
///
/// The `agdb` is using a single database file to store all of its data. Additionally
/// a single shadow file with a `.` prefix of the main database file name is used as
/// a write ahead log (WAL). On drop of the `Db` object the WAL is processed and removed
/// a write ahead log (WAL). On drop of the [`Db`] object the WAL is processed and removed
/// aborting any unfinished transactions. Furthermore the database data is defragmented.
///
/// On load, if the WAL file is present (e.g. due to a crash), it will be processed
Expand All @@ -189,16 +189,37 @@ pub struct DbImpl<Store: StorageData> {
undo_stack: Vec<Command>,
}

/// The default implementation of the database using memory mapped file (full ACID) with
/// write ahead log. If your data set exceeds available (or reasonable amount) of memory
/// consider using [`DbFile`] instead. You can load the file created with [`DbFile`] and
/// vice versa.
pub type Db = DbImpl<FileStorageMemoryMapped>;

/// A convenience alias for the [`Transaction`] type for the default [`Db`].
pub type DbTransaction<'a> = Transaction<'a, FileStorageMemoryMapped>;

/// A convenience alias for the [`TransactionMut`] type for the default [`Db`].
pub type DbTransactionMut<'a> = TransactionMut<'a, FileStorageMemoryMapped>;

/// The file based implementation of the database (full ACID) with write ahead logging and
/// but minimum memory footprint but slower than the default [`Db`]. You can load the file
/// created with [`Db`] and vice versa.
pub type DbFile = DbImpl<FileStorage>;

/// A convenience alias for the [`Transaction`] type for the default [`DbFile`].
pub type DbFileTransaction<'a> = Transaction<'a, FileStorage>;

/// A convenience alias for the [`TransactionMut`] type for the default [`DbFile`].
pub type DbFileTransactionMut<'a> = TransactionMut<'a, FileStorage>;

/// The purely in-memory implementation of the database. It has no persistence but offers
/// unmatched performance
pub type DbMemory = DbImpl<MemoryStorage>;

/// A convenience alias for the [`Transaction`] type for the default [`DbMemory`].
pub type DbMemoryTransaction<'a> = Transaction<'a, MemoryStorage>;

/// A convenience alias for the [`TransactionMut`] type for the default [`DbMemory`].
pub type DbMemoryTransactionMut<'a> = TransactionMut<'a, MemoryStorage>;

impl<Store: StorageData> std::fmt::Debug for DbImpl<Store> {
Expand Down
2 changes: 1 addition & 1 deletion agdb/src/db/db_element.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::DbId;
use crate::DbKeyValue;

/// Database element used in `QueryResult`
/// Database element used in [`QueryResult`]
/// that represents a node or an edge.
#[derive(Debug, PartialEq)]
pub struct DbElement {
Expand Down
2 changes: 1 addition & 1 deletion agdb/src/db/db_key.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::DbValue;

/// Alias to `DbValue`
/// Alias to [`DbValue`]
pub type DbKey = DbValue;

/// Ordering for search queries
Expand Down
2 changes: 1 addition & 1 deletion agdb/src/db/db_user_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::DbKeyValue;
/// of types that are convertible to/from database
/// primitive types.
///
/// The special type `db_id` of type `Option<DbId>`
/// The special type `db_id` of type [`Option<DbId>`](DbId)
/// can be used to allow direct insertion and select
/// of a user value tied with a particular database
/// element. The field `db_id` is skipped in the derive
Expand Down
2 changes: 1 addition & 1 deletion agdb/src/query/query_aliases.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// Wrapper around `Vec<String>` to provide
/// several convenient conversions for the
/// `QueryBuilder`.
/// [`QueryBuilder`].
pub struct QueryAliases(pub Vec<String>);

impl From<Vec<String>> for QueryAliases {
Expand Down
2 changes: 1 addition & 1 deletion agdb/src/query/query_condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub enum CountComparison {
NotEqual(u64),
}

/// Comparison of database values (`DbValue`) used
/// Comparison of database values ([`DbValue`]) used
/// by `key()` condition. Supports
/// the usual set of named comparisons: `==, !=, <, <=, >, =>`
/// plus `contains()`. The comparisons are type
Expand Down
4 changes: 2 additions & 2 deletions agdb/src/query/query_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use crate::DbId;
/// id or a string alias.
#[derive(Debug, Clone, PartialEq)]
pub enum QueryId {
/// Numerical id as `DbId`
/// Numerical id as [`DbId`]
Id(DbId),

/// Alias
/// String alias
Alias(String),
}

Expand Down
4 changes: 2 additions & 2 deletions agdb/src/query/query_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use crate::QueryResult;
use crate::SearchQuery;

/// List of database ids used in queries. It
/// can either represent a list of `QueryId`s
/// can either represent a list of [`QueryId`]s
/// or a search query. Search query allows query
/// nesting and sourcing the ids dynamically for
/// another query most commonly with the
/// select queries.
#[derive(Debug, Clone, PartialEq)]
pub enum QueryIds {
/// List of `QueryId`s
/// List of [`QueryId`]s
Ids(Vec<QueryId>),

/// Search query
Expand Down
6 changes: 3 additions & 3 deletions agdb/src/query/query_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ pub enum QueryValues {
Multi(Vec<Vec<DbKeyValue>>),
}

/// Convenient wrapper for the `QueryBuilder` to
/// Convenient wrapper for the [`QueryBuilder`] to
/// allow properties conversions. Represents `QueryValues::Single`.
pub struct SingleValues(pub Vec<DbKeyValue>);

/// Convenient wrapper for the `QueryBuilder` to
/// Convenient wrapper for the [`QueryBuilder`] to
/// allow properties conversions. Represents `QueryValues::Multi`.
pub struct MultiValues(pub Vec<Vec<DbKeyValue>>);

/// Convenient wrapper for the `QueryBuilder` to
/// Convenient wrapper for the [`QueryBuilder`] to
/// allow properties conversions. Represents list
/// of property keys.
pub struct QueryKeys(pub Vec<DbKey>);
Expand Down
28 changes: 28 additions & 0 deletions agdb/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,51 @@ impl Serialize for StorageIndex {

impl SerializeStatic for StorageIndex {}

/// Convenience alias for `Cow<'a, [u8]>`.
pub type StorageSlice<'a> = Cow<'a, [u8]>;

/// Minimum set of data operations required by the database
/// to store & retrieve data.
pub trait StorageData: Sized {
/// Copy the underlying data storage to a new `name`. The
/// default implementation does nothing. File implementations
/// might need to copy the underlying file(s).
fn backup(&mut self, _name: &str) -> Result<(), DbError> {
Ok(())
}

/// Flushes any buffers to the underlying storage (e.g. file). The
/// default implementation does nothing.
fn flush(&mut self) -> Result<(), DbError> {
Ok(())
}

/// Convenience method that returns `len() == 0`.
fn is_empty(&self) -> bool {
self.len() == 0
}

/// Returns the length of the underlying storage in bytes.
fn len(&self) -> u64;

/// Returns the name this storage was constructed with.
fn name(&self) -> &str;

/// Constructs or loads the storage `name`. The `name` might be
/// a file name or other identifier.
fn new(name: &str) -> Result<Self, DbError>;

/// Reads `value_len` bytes starting at `pos`. Returns [`StorageSlice`]
/// (COW).
fn read(&self, pos: u64, value_len: u64) -> Result<StorageSlice, DbError>;

/// Resizes the underlying storage to `new_len`. If the storage is enlarged as
/// a result the new bytes should be initialized to `0_u8`.
fn resize(&mut self, new_len: u64) -> Result<(), DbError>;

/// Writes the `bytes` to the underlying storage at `pos`. The implementation
/// must handle the case where the `pos + bytes.len()` exceeds the current
/// [`len()`](#method.len).
fn write(&mut self, pos: u64, bytes: &[u8]) -> Result<(), DbError>;
}

Expand Down
14 changes: 14 additions & 0 deletions agdb/src/storage/file_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ use std::io::SeekFrom;
use std::io::Write;
use std::sync::Mutex;

/// Single file based storage with write ahead log (WAL) for resiliency
/// implementing [`StorageData`]. It uses the storage name as the file
/// name (`.{name}` for WAL). It allows multiple readers from the file
/// by opening additional temporary file handles if the single member file
/// handle is being used (read). The [`StorageData::read()`] always returns
/// owning buffer.
///
/// The [`StorageData::backup()`] is implemented so that it copes the file
/// to the new name.
///
/// The [`StorageData::flush()`] merely clears the WAL. This implementation
/// relies on the OS to flush the content to the disk. It is specifically not
/// using manual calls to `File::sync_data()` / `File::sync_all()` because they
/// result in extreme slowdown.
pub struct FileStorage {
file: File,
filename: String,
Expand Down
12 changes: 11 additions & 1 deletion agdb/src/storage/file_storage_memory_mapped.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
use super::file_storage::FileStorage;
use super::memory_storage::MemoryStorage;
use super::{StorageData, StorageSlice};
use super::StorageData;
use super::StorageSlice;
use crate::DbError;

/// The default implementation of the database storage implementing
/// [`StorageData`]. It combines the [`FileStorage`] and [`MemoryStorage`]
/// leveraging the former for the persistence and the latter for performance.
/// The read operations are implemented in terms of the [`MemoryStorage`] only
/// and the write operations are implemented in terms of both [`FileStorage`]
/// and [`MemoryStorage`].
///
/// The file based storage is using write ahead logging (WAL) and single underlying
/// file. See [`FileStorage`] for more details on the persistent storage.
pub struct FileStorageMemoryMapped {
file: FileStorage,
memory: MemoryStorage,
Expand Down
6 changes: 6 additions & 0 deletions agdb/src/storage/memory_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ pub struct MemoryStorage {
name: String,
}

/// In memory buffer equivalent to `Vec<u8>` implementing [`StorageData`].
/// The [`StorageData::read()`] always returns non-owning the slice to the
/// underlying buffer. The [`StorageData::backup()`] and [`StorageData::flush()`]
/// rely on default implementations that do nothing.
///
/// This implementation offers unmatched performance but also **no persistence**.
impl MemoryStorage {
pub fn from_buffer(name: &str, buffer: Vec<u8>) -> Self {
Self {
Expand Down
6 changes: 3 additions & 3 deletions agdb/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::QueryResult;
use crate::StorageData;

/// The `Transaction` is a proxy struct that
/// encapsulates an immutably borrowed `Db`.
/// It allows running queries via `exec()`.
/// encapsulates an immutably borrowed [`DbImpl`].
/// It allows running queries via [`exec()`](#method.exec).
pub struct Transaction<'a, Store: StorageData> {
db: &'a DbImpl<Store>,
}

impl<'a, Store: StorageData> Transaction<'a, Store> {
/// Executes immutable query:
/// Executes immutable queries:
///
/// - Select elements
/// - Select values
Expand Down
8 changes: 4 additions & 4 deletions agdb/src/transaction_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ use crate::StorageData;
use crate::Transaction;

/// The `TransactionMut` is a proxy struct that
/// encapsulates a mutably borrowed `Db`.
/// It allows running queries via `exec()` and `exec_mut()`.
/// encapsulates a mutably borrowed [`DbImpl`].
/// It allows running queries via [`exec()`](#method.exec) and [`exec_mut()`](#method.exec_mut).
pub struct TransactionMut<'a, Store: StorageData> {
db: &'a mut DbImpl<Store>,
}

impl<'a, Store: StorageData> TransactionMut<'a, Store> {
/// Executes immutable query:
/// Executes immutable queries:
///
/// - Select elements
/// - Select values
Expand All @@ -27,7 +27,7 @@ impl<'a, Store: StorageData> TransactionMut<'a, Store> {
Transaction::new(self.db).exec(query)
}

/// Executes mutable query:
/// Executes mutable queries:
///
/// - Insert nodes
/// - Insert edges
Expand Down
19 changes: 19 additions & 0 deletions agdb_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,25 @@ use quote::quote;
use syn::parse_macro_input;
use syn::DeriveInput;

/// The derive macro to add `agdb` compatibility
/// to user defined types. It implements [`agdb::DbUserValue`]
/// for the type automatically to allow your type to be read and
/// stored from/to the database. If your type contains a field
/// `db_id: Option<agdb::DbId>` it will be treated specially
/// and will additionally allow shorthand inserts/updates
/// of the elements directly.
///
/// # Examples
///
/// ```ignore
/// #[derive(agdb_derive::UserValue)]
/// struct MyValue {
/// db_id: Option<agdb::DbId>, //this field is useful but not mandatory
/// num_value: i64,
/// string_value: String,
/// vec_value: Vec<u64>,
/// }
/// ```
#[proc_macro_derive(UserValue)]
pub fn db_user_value_derive(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
Expand Down

0 comments on commit 0f0bb50

Please sign in to comment.