fdb 0.2.1

FoundationDB Client API for Tokio
Documentation
use crate::error::{FdbError, FdbResult};
use crate::future::{
    FdbFutureCStringArray, FdbFutureI64, FdbFutureKey, FdbFutureMaybeValue, FdbFutureUnit,
    FdbStreamKeyValue,
};
use crate::range::{Range, RangeOptions};
use crate::transaction::TransactionOption;
use crate::{Key, KeySelector};

/// A read-only subset of a FDB [`Transaction`].
///
/// [`Transaction`]: crate::transaction::Transaction
//
// NOTE: Unlike Java API, `ReadTransaction` does not extend (i.e., is
//       a subtrait of) `ReadTransactionContext` (There is no
//       `ReadTransactionContext` in our case). This is to maintain
//       consistency with `Transaction`.
//
//       Also there is no `snapshot()` method on `ReadTransaction`
//       trait. Instead `snapshot()` is just a method on
//       `FdbTransaction` type. `onError` method is on
//       `ReadTransaction` trait, as its used to implement the retry
//       loop in `FdbDatabase::read`. We also don't have methods
//       `addReadConflictKeyIfNotSnapshot` and
//       `addReadConflictRangeIfNotSnapshot`.
pub trait ReadTransaction {
    /// Determines whether an error returned by a [`Transaction`]
    /// or [`ReadTransaction`] method is retryable. Waiting on the returned future will
    /// return the same error when fatal, or return `()` for retryable
    /// errors.
    ///
    /// Typical code will not use this method directly. It is used by
    /// [`run`] and [`read`] methods when they need to implement
    /// correct retry loop.
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async unsafe fn on_error(&self, e: FdbError) -> FdbResult<()>
    /// ```
    ///
    /// # Safety
    ///
    /// See [C API] for more details.
    ///
    /// [`Transaction`]: crate::transaction::Transaction
    /// [`run`]: crate::database::FdbDatabase::run
    /// [`read`]: crate::database::FdbDatabase::read
    /// [C API]: https://apple.github.io/foundationdb/api-c.html#c.fdb_transaction_on_error
    unsafe fn on_error(&self, e: FdbError) -> FdbFutureUnit;

    /// Gets a value from the database.    
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async fn get(&self, key: impl Into<Key>) -> FdbResult<Option<Value>>
    /// ```
    fn get(&self, key: impl Into<Key>) -> FdbFutureMaybeValue;

    /// Get a list of public network addresses as [`CString`], one for
    /// each of the storage servers responsible for storing [`Key`]
    /// and its associated value.
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async fn get_addresses_for_key(&self, key: impl Into<Key>) -> FdbResult<Vec<CString>>;
    /// ```
    ///
    /// [`CString`]: std::ffi::CString
    fn get_addresses_for_key(&self, key: impl Into<Key>) -> FdbFutureCStringArray;

    /// Gets an estimate for the number of bytes stored in the given
    /// range.
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async fn get_estimated_range_size_bytes(&self, range: Range) -> FdbResult<i64>
    /// ```
    ///
    /// # Note
    ///
    /// The estimated size is calculated based on the sampling done by
    /// FDB server. The sampling algorithm roughly works this way: The
    /// sampling algorithm works roughly in this way: the lager the
    /// key-value pair is, the more likely it would be sampled and the
    /// more accurate its sampled size would be. And due to that
    /// reason, it is recommended to use this API to query against
    /// large ranges for accuracy considerations. For a rough
    /// reference, if the returned size is larger than 3MB, one can
    /// consider the size to be accurate.
    fn get_estimated_range_size_bytes(&self, range: Range) -> FdbFutureI64;

    /// Returns the key referenced by the specificed [`KeySelector`].
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async fn get_key(&self, selector: KeySelector) -> FdbResult<Key>
    /// ```
    fn get_key(&self, selector: KeySelector) -> FdbFutureKey;

    /// Gets an ordered range of keys and values from the database.
    ///
    /// The returned [`FdbStreamKeyValue`] implements [`Stream`] trait
    /// that yields a [`KeyValue`] item.
    ///
    /// [`Stream`]: futures::Stream
    /// [`KeyValue`]: crate::KeyValue
    fn get_range(
        &self,
        begin: KeySelector,
        end: KeySelector,
        options: RangeOptions,
    ) -> FdbStreamKeyValue;

    /// Gets the version at which the reads for this [`Transaction`]
    /// or [`ReadTransaction`] will access the database.
    ///
    /// Equivalent to:
    ///
    /// ```ignore
    /// async unsafe fn get_read_version(&self) -> FdbResult<i64>
    /// ```
    ///
    /// # Safety
    ///
    /// The [`FdbFuture`] resolves to an [`i64`] instead of a [`u64`]
    /// because of [internal representation]. Even though it is an
    /// [`i64`], the future will always return a positive
    /// number. Negative GRV numbers are used internally within FDB.
    ///
    /// You only rely on GRV only for read-only transactions. For
    /// read-write transactions you should use commit version.
    ///
    /// [`Transaction`]: crate::transaction::Transaction
    /// [`FdbFuture`]: crate::future::FdbFuture
    /// [internal representation]: https://github.com/apple/foundationdb/blob/6.3.22/fdbclient/FDBTypes.h#L32
    unsafe fn get_read_version(&self) -> FdbFutureI64;

    /// Set options on a [`Transaction`] or [`ReadTransaction`]
    ///
    /// [`Transaction`]: crate::transaction::Transaction
    fn set_option(&self, option: TransactionOption) -> FdbResult<()>;

    /// Directly sets the version of the database at which to execute
    /// reads.
    ///
    /// # Safety
    ///
    /// See [C API] for more details.
    ///
    /// [C API]: https://apple.github.io/foundationdb/api-c.html#c.fdb_transaction_set_read_version
    unsafe fn set_read_version(&self, version: i64);
}