Lines
98.63 %
Functions
9.34 %
Branches
100 %
use arc_bytes::serde::Bytes;
use serde::{Deserialize, Serialize};
use crate::api::{Api, ApiName};
use crate::connection::{
AccessPolicy, Database, IdentityReference, Range, SerializedQueryKey, Session, SessionId, Sort,
};
use crate::document::{DocumentId, Header, OwnedDocument};
use crate::keyvalue::{KeyOperation, Output};
use crate::schema::view::map::{self, MappedSerializedDocuments};
use crate::schema::{CollectionName, NamedReference, Qualified, SchemaSummary, ViewName};
use crate::transaction::{Executed, OperationResult, Transaction};
/// The current protocol version.
pub const CURRENT_PROTOCOL_VERSION: &str = "bonsai-pre-1";
/// A payload with an associated id.
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct Payload {
/// The authentication session id for this payload.
pub session_id: Option<SessionId>,
/// The unique id for this payload.
pub id: Option<u32>,
/// The unique name of the api
pub name: ApiName,
/// The payload
pub value: Result<Bytes, crate::Error>,
}
/// Creates a database.
pub struct CreateDatabase {
/// The database to create.
pub database: Database,
/// Only attempts to create the database if it doesn't already exist.
pub only_if_needed: bool,
impl Api for CreateDatabase {
type Error = crate::Error;
type Response = ();
fn name() -> ApiName {
ApiName::new("bonsaidb", "CreateDatabase")
/// Deletes the database named `name`
pub struct DeleteDatabase {
/// The name of the database to delete.
pub name: String,
impl Api for DeleteDatabase {
ApiName::new("bonsaidb", "DeleteDatabase")
/// Lists all databases.
pub struct ListDatabases;
impl Api for ListDatabases {
type Response = Vec<Database>;
ApiName::new("bonsaidb", "ListDatabases")
/// Lists available schemas.
pub struct ListAvailableSchemas;
impl Api for ListAvailableSchemas {
type Response = Vec<SchemaSummary>;
ApiName::new("bonsaidb", "ListAvailableSchemas")
/// Creates a user.
pub struct CreateUser {
/// The unique username of the user to create.
pub username: String,
impl Api for CreateUser {
type Response = u64;
ApiName::new("bonsaidb", "CreateUser")
/// Deletes a user.
pub struct DeleteUser {
/// The unique primary key of the user to be deleted.
pub user: NamedReference<'static, u64>,
impl Api for DeleteUser {
ApiName::new("bonsaidb", "DeleteUser")
/// Set's a user's password.
#[cfg(feature = "password-hashing")]
pub struct SetUserPassword {
/// The username or id of the user.
/// The user's new password.
pub password: crate::connection::SensitiveString,
impl Api for SetUserPassword {
ApiName::new("bonsaidb", "SetUserPassword")
/// Authenticate the current connection.
#[cfg(any(feature = "password-hashing", feature = "token-authentication"))]
pub struct Authenticate {
/// The method of authentication.
pub authentication: crate::connection::Authentication,
impl Api for Authenticate {
type Response = Session;
ApiName::new("bonsaidb", "Authenticate")
/// Assume an identity.
pub struct AssumeIdentity(pub IdentityReference<'static>);
impl Api for AssumeIdentity {
ApiName::new("bonsaidb", "AssumeIdentity")
/// Logs out from a session.
pub struct LogOutSession(pub SessionId);
impl Api for LogOutSession {
ApiName::new("bonsaidb", "LogOutSession")
/// Alter's a user's membership in a permission group.
pub struct AlterUserPermissionGroupMembership {
/// The name or id of the group.
pub group: NamedReference<'static, u64>,
/// Whether the user should be in the group.
pub should_be_member: bool,
impl Api for AlterUserPermissionGroupMembership {
ApiName::new("bonsaidb", "AlterUserPermissionGroupMembership")
/// Alter's a user's role
pub struct AlterUserRoleMembership {
/// The name or id of the role.
pub role: NamedReference<'static, u64>,
/// Whether the user should have the role.
impl Api for AlterUserRoleMembership {
ApiName::new("bonsaidb", "AlterUserRoleMembership")
/// Retrieve a single document.
pub struct Get {
/// The name of the database.
pub database: String,
/// The collection of the document.
pub collection: CollectionName,
/// The id of the document.
pub id: DocumentId,
impl Api for Get {
type Response = Option<OwnedDocument>;
ApiName::new("bonsaidb", "Get")
/// Retrieve multiple documents.
pub struct GetMultiple {
/// The collection of the documents.
/// The ids of the documents.
pub ids: Vec<DocumentId>,
impl Api for GetMultiple {
type Response = Vec<OwnedDocument>;
ApiName::new("bonsaidb", "GetMultiple")
pub struct List {
/// The range of ids to list.
pub ids: Range<DocumentId>,
/// The order for the query into the collection.
pub order: Sort,
/// The maximum number of results to return.
pub limit: Option<u32>,
impl Api for List {
ApiName::new("bonsaidb", "List")
/// Retrieve multiple document headers.
pub struct ListHeaders(pub List);
impl Api for ListHeaders {
type Response = Vec<Header>;
ApiName::new("bonsaidb", "ListHeaders")
/// Counts the number of documents in the specified range.
pub struct Count {
/// The range of ids to count.
impl Api for Count {
ApiName::new("bonsaidb", "Count")
/// Queries a view.
pub struct Query {
/// The name of the view.
pub view: ViewName,
/// The filter for the view.
pub key: Option<SerializedQueryKey>,
/// The order for the query into the view.
/// The access policy for the query.
pub access_policy: AccessPolicy,
impl Api for Query {
type Response = Vec<map::Serialized>;
ApiName::new("bonsaidb", "Query")
/// Queries a view with the associated documents.
pub struct QueryWithDocs(pub Query);
impl Api for QueryWithDocs {
type Response = MappedSerializedDocuments;
ApiName::new("bonsaidb", "QueryWithDocs")
/// Reduces a view.
pub struct Reduce {
impl Api for Reduce {
type Response = Bytes;
ApiName::new("bonsaidb", "Reduce")
/// Reduces a view, grouping the reduced values by key.
pub struct ReduceGrouped(pub Reduce);
impl Api for ReduceGrouped {
type Response = Vec<map::MappedSerializedValue>;
ApiName::new("bonsaidb", "ReduceGrouped")
/// Deletes the associated documents resulting from the view query.
pub struct DeleteDocs {
impl Api for DeleteDocs {
ApiName::new("bonsaidb", "DeleteDocs")
/// Applies a transaction.
pub struct ApplyTransaction {
/// The trasnaction to apply.
pub transaction: Transaction,
impl Api for ApplyTransaction {
type Response = Vec<OperationResult>;
ApiName::new("bonsaidb", "ApplyTransaction")
/// Lists executed transactions.
pub struct ListExecutedTransactions {
/// The starting transaction id.
pub starting_id: Option<u64>,
/// The maximum number of results.
pub result_limit: Option<u32>,
impl Api for ListExecutedTransactions {
type Response = Vec<Executed>;
ApiName::new("bonsaidb", "ListExecutedTransactions")
/// Queries the last transaction id.
pub struct LastTransactionId {
impl Api for LastTransactionId {
type Response = Option<u64>;
ApiName::new("bonsaidb", "LastTransactionId")
/// Creates a `PubSub` [`Subscriber`](crate::pubsub::Subscriber)
pub struct CreateSubscriber {
impl Api for CreateSubscriber {
ApiName::new("bonsaidb", "CreateSubscriber")
/// Publishes `payload` to all subscribers of `topic`.
pub struct Publish {
/// The topics to publish to.
pub topic: Bytes,
/// The payload to publish.
pub payload: Bytes,
impl Api for Publish {
ApiName::new("bonsaidb", "Publish")
/// Publishes `payload` to all subscribers of all `topics`.
pub struct PublishToAll {
pub topics: Vec<Bytes>,
impl Api for PublishToAll {
ApiName::new("bonsaidb", "PublishToAll")
/// Subscribes `subscriber_id` to messages for `topic`.
pub struct SubscribeTo {
/// The id of the [`Subscriber`](crate::pubsub::Subscriber).
pub subscriber_id: u64,
/// The topic to subscribe to.
impl Api for SubscribeTo {
ApiName::new("bonsaidb", "SubscribeTo")
/// A PubSub message was received.
pub struct MessageReceived {
/// The ID of the subscriber receiving the message.
/// The topic the payload was received on.
/// The message payload.
impl Api for MessageReceived {
type Response = Self;
ApiName::new("bonsaidb", "MessageReceived")
/// Unsubscribes `subscriber_id` from messages for `topic`.
pub struct UnsubscribeFrom {
/// The topic to unsubscribe from.
impl Api for UnsubscribeFrom {
ApiName::new("bonsaidb", "UnsubscribeFrom")
/// Unregisters the subscriber.
pub struct UnregisterSubscriber {
impl Api for UnregisterSubscriber {
ApiName::new("bonsaidb", "UnregisterSubscriber")
/// Excutes a key-value store operation.
pub struct ExecuteKeyOperation {
/// The operation to execute.
pub op: KeyOperation,
impl Api for ExecuteKeyOperation {
type Response = Output;
ApiName::new("bonsaidb", "ExecuteKeyOperation")
/// Compacts the collection.
pub struct CompactCollection {
/// The name of the collection to compact.
pub name: CollectionName,
impl Api for CompactCollection {
ApiName::new("bonsaidb", "CompactCollection")
/// Compacts the key-value store.
pub struct CompactKeyValueStore {
impl Api for CompactKeyValueStore {
ApiName::new("bonsaidb", "CompactKeyValueStore")
/// Compacts the entire database.
pub struct Compact {
impl Api for Compact {
ApiName::new("bonsaidb", "Compact")
/// A networking error.
#[derive(Clone, thiserror::Error, Debug, Serialize, Deserialize)]
pub enum Error {
/// The server responded with a message that wasn't expected for the request
/// sent.
#[error("unexpected response: {0}")]
UnexpectedResponse(String),
/// A timeout occurred while connecting to the server.
#[error("connection timeout")]
ConnectTimeout,
/// A timeout occurred waiting on a request to complete.
#[error("request timeout")]
RequestTimeout,
/// The connection was interrupted.
#[error("unexpected disconnection")]
Disconnected,