Lines
21.6 %
Functions
7.02 %
Branches
100 %
use bonsaidb_client::{Client, RemoteDatabase};
#[cfg(feature = "password-hashing")]
use bonsaidb_core::connection::{Authenticated, Authentication};
use bonsaidb_core::{
async_trait::async_trait,
connection::{self, AccessPolicy, Connection, QueryKey, Range, Sort, StorageConnection},
document::{AnyDocumentId, OwnedDocument},
schema::{
view::map::MappedDocuments, Collection, Map, MappedValue, Nameable, Schema, SchemaName,
SerializedView,
},
transaction::{Executed, OperationResult, Transaction},
};
use bonsaidb_server::{Backend, CustomServer, NoBackend, ServerDatabase};
/// A local server or a server over a network connection.
pub enum AnyServerConnection<B: Backend> {
/// A local server.
Local(CustomServer<B>),
/// A server accessed with a [`Client`].
Networked(Client<B::CustomApi>),
}
#[async_trait]
impl<B: Backend> StorageConnection for AnyServerConnection<B> {
type Database = AnyDatabase<B>;
async fn database<DB: Schema>(
&self,
name: &str,
) -> Result<Self::Database, bonsaidb_core::Error> {
match self {
Self::Local(server) => server.database::<DB>(name).await.map(AnyDatabase::Local),
Self::Networked(client) => client
.database::<DB>(name)
.await
.map(AnyDatabase::Networked),
async fn create_database_with_schema(
schema: SchemaName,
only_if_needed: bool,
) -> Result<(), bonsaidb_core::Error> {
Self::Local(server) => {
server
.create_database_with_schema(name, schema, only_if_needed)
Self::Networked(client) => {
client
async fn delete_database(&self, name: &str) -> Result<(), bonsaidb_core::Error> {
Self::Local(server) => server.delete_database(name).await,
Self::Networked(client) => client.delete_database(name).await,
async fn list_databases(&self) -> Result<Vec<connection::Database>, bonsaidb_core::Error> {
Self::Local(server) => server.list_databases().await,
Self::Networked(client) => client.list_databases().await,
async fn list_available_schemas(&self) -> Result<Vec<SchemaName>, bonsaidb_core::Error> {
Self::Local(server) => server.list_available_schemas().await,
Self::Networked(client) => client.list_available_schemas().await,
async fn create_user(&self, username: &str) -> Result<u64, bonsaidb_core::Error> {
Self::Local(server) => server.create_user(username).await,
Self::Networked(client) => client.create_user(username).await,
async fn set_user_password<'user, U: Nameable<'user, u64> + Send + Sync>(
user: U,
password: bonsaidb_core::connection::SensitiveString,
Self::Local(server) => server.set_user_password(user, password).await,
Self::Networked(client) => client.set_user_password(user, password).await,
async fn authenticate<'user, U: Nameable<'user, u64> + Send + Sync>(
authentication: Authentication,
) -> Result<Authenticated, bonsaidb_core::Error> {
Self::Local(server) => server.authenticate(user, authentication).await,
Self::Networked(client) => client.authenticate(user, authentication).await,
async fn add_permission_group_to_user<
'user,
'group,
U: Nameable<'user, u64> + Send + Sync,
G: Nameable<'group, u64> + Send + Sync,
>(
permission_group: G,
.add_permission_group_to_user(user, permission_group)
async fn remove_permission_group_from_user<
.remove_permission_group_from_user(user, permission_group)
async fn add_role_to_user<
'role,
R: Nameable<'role, u64> + Send + Sync,
role: R,
Self::Local(server) => server.add_role_to_user(user, role).await,
Self::Networked(client) => client.add_role_to_user(user, role).await,
async fn remove_role_from_user<
Self::Local(server) => server.remove_role_from_user(user, role).await,
Self::Networked(client) => client.remove_role_from_user(user, role).await,
/// A database connection that can be either from a local server or a server
/// over a network connection.
pub enum AnyDatabase<B: Backend = NoBackend> {
/// A local database.
Local(ServerDatabase<B>),
/// A networked database accessed with a [`Client`].
Networked(RemoteDatabase<B::CustomApi>),
impl<B: Backend> Connection for AnyDatabase<B> {
async fn get<C, PrimaryKey>(
id: PrimaryKey,
) -> Result<Option<OwnedDocument>, bonsaidb_core::Error>
where
C: Collection,
PrimaryKey: Into<AnyDocumentId<C::PrimaryKey>> + Send,
{
Self::Local(server) => server.get::<C, _>(id).await,
Self::Networked(client) => client.get::<C, _>(id).await,
async fn get_multiple<C, PrimaryKey, DocumentIds, I>(
ids: DocumentIds,
) -> Result<Vec<OwnedDocument>, bonsaidb_core::Error>
DocumentIds: IntoIterator<Item = PrimaryKey, IntoIter = I> + Send + Sync,
I: Iterator<Item = PrimaryKey> + Send + Sync,
PrimaryKey: Into<AnyDocumentId<C::PrimaryKey>> + Send + Sync,
Self::Local(server) => server.get_multiple::<C, _, _, _>(ids).await,
Self::Networked(client) => client.get_multiple::<C, _, _, _>(ids).await,
async fn list<C, R, PrimaryKey>(
ids: R,
order: Sort,
limit: Option<usize>,
R: Into<Range<PrimaryKey>> + Send,
Self::Local(server) => server.list::<C, _, _>(ids, order, limit).await,
Self::Networked(client) => client.list::<C, _, _>(ids, order, limit).await,
async fn query<V: SerializedView>(
key: Option<QueryKey<V::Key>>,
access_policy: AccessPolicy,
) -> Result<Vec<Map<V::Key, V::Value>>, bonsaidb_core::Error>
Self: Sized,
Self::Local(server) => server.query::<V>(key, order, limit, access_policy).await,
Self::Networked(client) => client.query::<V>(key, order, limit, access_policy).await,
async fn query_with_docs<V: SerializedView>(
) -> Result<MappedDocuments<OwnedDocument, V>, bonsaidb_core::Error>
.query_with_docs::<V>(key, order, limit, access_policy)
async fn reduce<V: SerializedView>(
) -> Result<V::Value, bonsaidb_core::Error>
Self::Local(server) => server.reduce::<V>(key, access_policy).await,
Self::Networked(client) => client.reduce::<V>(key, access_policy).await,
async fn reduce_grouped<V: SerializedView>(
) -> Result<Vec<MappedValue<V::Key, V::Value>>, bonsaidb_core::Error>
Self::Local(server) => server.reduce_grouped::<V>(key, access_policy).await,
Self::Networked(client) => client.reduce_grouped::<V>(key, access_policy).await,
async fn delete_docs<V: SerializedView>(
) -> Result<u64, bonsaidb_core::Error>
Self::Local(server) => server.delete_docs::<V>(key, access_policy).await,
Self::Networked(client) => client.delete_docs::<V>(key, access_policy).await,
async fn apply_transaction(
transaction: Transaction,
) -> Result<Vec<OperationResult>, bonsaidb_core::Error> {
Self::Local(server) => server.apply_transaction(transaction).await,
Self::Networked(client) => client.apply_transaction(transaction).await,
async fn list_executed_transactions(
starting_id: Option<u64>,
result_limit: Option<usize>,
) -> Result<Vec<Executed>, bonsaidb_core::Error> {
.list_executed_transactions(starting_id, result_limit)
async fn last_transaction_id(&self) -> Result<Option<u64>, bonsaidb_core::Error> {
Self::Local(server) => server.last_transaction_id().await,
Self::Networked(client) => client.last_transaction_id().await,
async fn compact_collection<C: Collection>(&self) -> Result<(), bonsaidb_core::Error> {
Self::Local(server) => server.compact_collection::<C>().await,
Self::Networked(client) => client.compact_collection::<C>().await,
async fn compact(&self) -> Result<(), bonsaidb_core::Error> {
Self::Local(server) => server.compact().await,
Self::Networked(client) => client.compact().await,
async fn compact_key_value_store(&self) -> Result<(), bonsaidb_core::Error> {
Self::Local(server) => server.compact_key_value_store().await,
Self::Networked(client) => client.compact_key_value_store().await,