pub trait Connection: Send + Sync {
Show 20 methods fn get<'life0, 'async_trait, C>(
        &'life0 self,
        id: u64
    ) -> Pin<Box<dyn Future<Output = Result<Option<OwnedDocument>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        C: Collection + 'async_trait,
        Self: 'async_trait
;
fn get_multiple<'life0, 'life1, 'async_trait, C>(
        &'life0 self,
        ids: &'life1 [u64]
    ) -> Pin<Box<dyn Future<Output = Result<Vec<OwnedDocument, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        C: Collection + 'async_trait,
        Self: 'async_trait
;
fn list<'life0, 'async_trait, C, R>(
        &'life0 self,
        ids: R,
        order: Sort,
        limit: Option<usize>
    ) -> Pin<Box<dyn Future<Output = Result<Vec<OwnedDocument, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        C: Collection + 'async_trait,
        R: Into<Range<u64>> + Send + 'async_trait,
        Self: 'async_trait
;
fn query<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        order: Sort,
        limit: Option<usize>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Map<<V as View>::Key, <V as View>::Value>, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait
;
fn query_with_docs<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        order: Sort,
        limit: Option<usize>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<MappedDocuments<OwnedDocument, V>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait
;
fn reduce<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<<V as View>::Value, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait
;
fn reduce_grouped<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<Vec<MappedValue<<V as View>::Key, <V as View>::Value>, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait
;
fn delete_docs<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait
;
fn apply_transaction<'life0, 'async_trait>(
        &'life0 self,
        transaction: Transaction
    ) -> Pin<Box<dyn Future<Output = Result<Vec<OperationResult, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        Self: 'async_trait
;
fn list_executed_transactions<'life0, 'async_trait>(
        &'life0 self,
        starting_id: Option<u64>,
        result_limit: Option<usize>
    ) -> Pin<Box<dyn Future<Output = Result<Vec<Executed, Global>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        Self: 'async_trait
;
fn last_transaction_id<'life0, 'async_trait>(
        &'life0 self
    ) -> Pin<Box<dyn Future<Output = Result<Option<u64>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        Self: 'async_trait
;
fn compact<'life0, 'async_trait>(
        &'life0 self
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        Self: 'async_trait
;
fn compact_collection<'life0, 'async_trait, C>(
        &'life0 self
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        C: Collection + 'async_trait,
        Self: 'async_trait
;
fn compact_key_value_store<'life0, 'async_trait>(
        &'life0 self
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        Self: 'async_trait
; fn collection<C>(&self) -> Collection<'_, Self, C>
    where
        C: Collection
, { ... }
fn insert<'life0, 'async_trait, C, B>(
        &'life0 self,
        id: Option<u64>,
        contents: B
    ) -> Pin<Box<dyn Future<Output = Result<Header, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        C: Collection + 'async_trait,
        B: Into<Bytes> + Send + 'async_trait,
        Self: 'async_trait
, { ... }
fn update<'a, 'life0, 'life1, 'async_trait, C, D>(
        &'life0 self,
        doc: &'life1 mut D
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>>
    where
        'a: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        C: Collection + 'async_trait,
        D: Document<'a> + Send + Sync + 'async_trait,
        Self: 'async_trait
, { ... }
fn delete<'life0, 'life1, 'async_trait, C, H>(
        &'life0 self,
        doc: &'life1 H
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        C: Collection + 'async_trait,
        H: AsRef<Header> + Send + Sync + 'async_trait,
        Self: 'async_trait
, { ... }
fn view<V>(&self) -> View<'_, Self, V>
    where
        V: SerializedView
, { ... }
fn query_with_collection_docs<'life0, 'async_trait, V>(
        &'life0 self,
        key: Option<QueryKey<<V as View>::Key>>,
        order: Sort,
        limit: Option<usize>,
        access_policy: AccessPolicy
    ) -> Pin<Box<dyn Future<Output = Result<MappedDocuments<CollectionDocument<<V as View>::Collection>, V>, Error>> + Send + 'async_trait, Global>>
    where
        'life0: 'async_trait,
        V: SerializedView + 'async_trait,
        Self: 'async_trait,
        <V as View>::Collection: SerializedCollection,
        <<V as View>::Collection as SerializedCollection>::Contents: Debug
, { ... }
}
Expand description

Defines all interactions with a schema::Schema, regardless of whether it is local or remote.

Interacting with Collections

At its core, each document is just a unique ID and an array of bytes. The low-level interface works with OwnedDocument, which leaves you in charge of deserializing data.

For most standard use cases, you will be happy to leverage Serde / Transmog and CollectionDocument<T>/SerializedCollection.

These examples all use this basic collection type definition:

use bonsaidb_core::{
    schema::{Collection, CollectionName, DefaultSerialization, Schematic},
    Error,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Default)]
pub struct MyCollection {
    pub rank: u32,
    pub score: f32,
}

impl Collection for MyCollection {
    fn collection_name() -> CollectionName {
        CollectionName::new("MyAuthority", "MyCollection")
    }

    fn define_views(schema: &mut Schematic) -> Result<(), Error> {
        // ...
        Ok(())
    }
}

impl DefaultSerialization for MyCollection {}

Using Connection with OwnedDocument

Inserting a document with an automatically assigned ID
let inserted_header = db.collection::<MyCollection>().push_bytes(vec![]).await?;
println!(
    "Inserted id {} with revision {}",
    inserted_header.id, inserted_header.revision
);
Inserting a document with a specific ID
let inserted_header = db
    .collection::<MyCollection>()
    .insert_bytes(42, vec![])
    .await?;
println!(
    "Inserted id {} with revision {}",
    inserted_header.id, inserted_header.revision
);
Retrieving a document by ID
if let Some(doc) = db.collection::<MyCollection>().get(42).await? {
    println!(
        "Retrieved bytes {:?} with revision {}",
        doc.contents, doc.header.revision
    );
    let deserialized = doc.contents::<MyCollection>()?;
    println!("Deserialized contents: {:?}", deserialized);
}
Retreiving multiple documents by IDs
for doc in db
    .collection::<MyCollection>()
    .get_multiple(&[42, 43])
    .await?
{
    println!("Retrieved #{} with bytes {:?}", doc.header.id, doc.contents);
    let deserialized = doc.contents::<MyCollection>()?;
    println!("Deserialized contents: {:?}", deserialized);
}
Retreiving all documents
for doc in db.collection::<MyCollection>().list(..).await? {
    println!("Retrieved #{} with bytes {:?}", doc.header.id, doc.contents);
    let deserialized = doc.contents::<MyCollection>()?;
    println!("Deserialized contents: {:?}", deserialized);
}
Listing a limited amount of documents in reverse order
for doc in db
    .collection::<MyCollection>()
    .list(..)
    .descending()
    .limit(20)
    .await?
{
    println!("Retrieved #{} with bytes {:?}", doc.header.id, doc.contents);
    let deserialized = doc.contents::<MyCollection>()?;
    println!("Deserialized contents: {:?}", deserialized);
}

Using Connection with CollectionDocument<T>

Inserting a document with an automatically assigned ID
let document = MyCollection::default().push_into(&db).await?;
println!(
    "Inserted {:?} with id {} with revision {}",
    document.contents, document.header.id, document.header.revision
);
Inserting a document with a specific ID
let document = MyCollection::default().insert_into(42, &db).await?;
println!(
    "Inserted {:?} with id {} with revision {}",
    document.contents, document.header.id, document.header.revision
);
Retrieving a document by ID
if let Some(doc) = MyCollection::get(42, &db).await? {
    println!(
        "Retrieved revision {} with deserialized contents: {:?}",
        doc.header.revision, doc.contents
    );
}
Retreiving multiple documents by IDs
for doc in MyCollection::get_multiple(&[42, 43], &db).await? {
    println!(
        "Retrieved #{} with deserialized contents: {:?}",
        doc.header.id, doc.contents
    );
}
Retreiving all documents
for doc in MyCollection::list(.., &db).await? {
    println!(
        "Retrieved #{} with deserialized contents: {:?}",
        doc.header.id, doc.contents
    );
}
Listing a limited amount of documents in reverse order
for doc in MyCollection::list(.., &db).descending().limit(20).await? {
    println!(
        "Retrieved #{} with deserialized contents: {:?}",
        doc.header.id, doc.contents
    );
}

Querying Views

The examples use this view definition:

use bonsaidb_core::{
    define_basic_unique_mapped_view,
    document::CollectionDocument,
    schema::{
        CollectionViewSchema, DefaultViewSerialization, Name, ReduceResult, View,
        ViewMapResult, ViewMappedValue,
    },
};

#[derive(Debug)]
pub struct ScoresByRank;

impl View for ScoresByRank {
    type Collection = MyCollection;
    type Key = u32;
    type Value = f32;

    fn name(&self) -> Name {
        Name::new("scores-by-rank")
    }
}

impl CollectionViewSchema for ScoresByRank {
    type View = Self;
    fn map(
        &self,
        document: CollectionDocument<<Self::View as View>::Collection>,
    ) -> ViewMapResult<Self::View> {
        Ok(document
            .header
            .emit_key_and_value(document.contents.rank, document.contents.score))
    }

    fn reduce(
        &self,
        mappings: &[ViewMappedValue<Self::View>],
        rereduce: bool,
    ) -> ReduceResult<Self::View> {
        if mappings.is_empty() {
            Ok(0.)
        } else {
            Ok(mappings.iter().map(|map| map.value).sum::<f32>() / mappings.len() as f32)
        }
    }
}

impl DefaultViewSerialization for ScoresByRank {}

Retrieving all view entries

for mapping in db.view::<ScoresByRank>().query().await? {
    println!(
        "Mapping from #{} with rank: {} and score: {}",
        mapping.source.id, mapping.key, mapping.value
    );
}

Retrieving all mappings with the same key

for mapping in db.view::<ScoresByRank>().with_key(42).query().await? {
    println!(
        "Mapping from #{} with rank: {} and score: {}",
        mapping.source.id, mapping.key, mapping.value
    );
}

Retrieving all mappings with a range of keys

for mapping in db
    .view::<ScoresByRank>()
    .with_key_range(42..=44)
    .query()
    .await?
{
    println!(
        "Mapping from #{} with rank: {} and score: {}",
        mapping.source.id, mapping.key, mapping.value
    );
}

Retrieving the associated documents with a view query

With OwnedDocument:

for mapping in &db
    .view::<ScoresByRank>()
    .with_key_range(42..=44)
    .query_with_docs()
    .await?
{
    println!(
        "Mapping from #{} with rank: {} and score: {}. Document bytes: {:?}",
        mapping.document.header.id, mapping.key, mapping.value, mapping.document.contents
    );
}

With CollectionDocument<T>:

for mapping in &db
    .view::<ScoresByRank>()
    .with_key_range(42..=44)
    .query_with_collection_docs()
    .await?
{
    println!(
        "Mapping from #{} with rank: {} and score: {}. Deserialized Contents: {:?}",
        mapping.document.header.id, mapping.key, mapping.value, mapping.document.contents
    );
}

Customizing view query parameters

for mapping in db
    .view::<ScoresByRank>()
    .with_key_range(42..=44)
    .descending()
    .limit(10)
    .query()
    .await?
{
    println!(
        "Mapping from #{} with rank: {} and score: {}",
        mapping.source.id, mapping.key, mapping.value
    );
}

Reducing a view to its value type

All of the ways of filtering a view can be used in conjunction with reduce().

// score is an f32 in this example
let score = db.view::<ScoresByRank>().reduce().await?;
println!("Average score: {:3}", score);

Reducing a view to its value type, grouping by key

All of the ways of filtering a view can be used in conjunction with reduce().

// score is an f32 in this example
for mapping in db.view::<ScoresByRank>().reduce_grouped().await? {
    println!(
        "Rank {} has an average score of {:3}",
        mapping.key, mapping.value
    );
}

Required methods

Retrieves a stored document from Collection C identified by id.

Retrieves all documents matching ids. Documents that are not found are not returned, but no error will be generated.

Retrieves all documents within the range of ids. Documents that are not found are not returned, but no error will be generated. To retrieve all documents, pass in .. for ids.

Queries for view entries matching View.

Queries for view entries matching View with their source documents.

Reduces the view entries matching View.

Reduces the view entries matching View, reducing the values by each unique key.

Deletes all of the documents associated with this view.

Applies a Transaction to the schema::Schema. If any operation in the Transaction fails, none of the operations will be applied to the schema::Schema.

Lists executed Transactions from this schema::Schema. By default, a maximum of 1000 entries will be returned, but that limit can be overridden by setting result_limit. A hard limit of 100,000 results will be returned. To begin listing after another known transaction_id, pass transaction_id + 1 into starting_id.

Fetches the last transaction id that has been committed, if any.

Compacts the entire database to reclaim unused disk space.

This process is done by writing data to a new file and swapping the file once the process completes. This ensures that if a hardware failure, power outage, or crash occurs that the original collection data is left untouched.

Errors
  • Error::Io: an error occurred while compacting the database.

Compacts the collection to reclaim unused disk space.

This process is done by writing data to a new file and swapping the file once the process completes. This ensures that if a hardware failure, power outage, or crash occurs that the original collection data is left untouched.

Errors

Compacts the key value store to reclaim unused disk space.

This process is done by writing data to a new file and swapping the file once the process completes. This ensures that if a hardware failure, power outage, or crash occurs that the original collection data is left untouched.

Errors
  • Error::Io: an error occurred while compacting the database.

Provided methods

Accesses a collection for the connected schema::Schema.

Inserts a newly created document into the connected schema::Schema for the Collection C. If id is None a unique id will be generated. If an id is provided and a document already exists with that id, a conflict error will be returned.

Updates an existing document in the connected schema::Schema for the Collection C. Upon success, doc.revision will be updated with the new revision.

Removes a Document from the database.

Initializes View for schema::View V.

Queries for view entries matching View with their source documents, deserialized.

Implementors

Pass-through implementation