Skip to main content

Database

Struct Database 

Source
pub struct Database { /* private fields */ }

Implementations§

Source§

impl Database

Source§

impl Database

These impls control the keystore transaction lifecycle.

Source

pub async fn new_transaction( self: &Arc<Self>, ) -> CryptoKeystoreResult<UniqueArc<Transaction>>

Waits for the current transaction to be committed or rolled back, then starts a new one.

Source

pub async fn try_new_immediate_transaction( self: &Arc<Self>, ) -> CryptoKeystoreResult<UniqueArc<Transaction>>

Start a new transaction if no other transaction is currently in progress.

If a transaction is currently in progress, this will produce a TransactionInProgress error.

Source

pub async fn transactionally<R>( self: &Arc<Self>, operation: impl AsyncFnOnce(&Transaction) -> CryptoKeystoreResult<R>, ) -> CryptoKeystoreResult<R>

Do an operation on a new keystore transaction on this database.

This is a convenience method abstracting over the transaction lifecycle; it creates a new transaction (including waiting for any existing transaction to finish), then performs its operation.

If the operation succeeds, the transaction is committed. Otherwise, it is rolled back.

Source

pub async fn ensure_transaction<T, E>( self: &Arc<Self>, operation: impl AsyncFnOnce(&Transaction) -> Result<T, E>, map_err: impl Fn(CryptoKeystoreError) -> E, ) -> Result<T, E>

Ensure a transaction exists, passing it to the operation.

Ideally this method wouldn’t exist; in most cases, Self::transactionally or Self::with_transaction (crate-public) are the simpler picks. Every usage of this is a step away from the long-term goal of separating transactions from the database entirely. At present, this is designed for the FFI version of PkiEnvironment, which cannot natively know whether a CC transaction is currently in-progress or not.

If a transaction is already in progress, perform the operation and pass on its result without affecting the transaction lifecycle at all, whether or not the operation succeeded.

NOTE: if the transaction was already in progress, its owner’s .commit() will block until the operation here has completed.

If a transaction was not already in progress, create one and then perform the operation. If the operation succeeded, commit the transaction; otherwise, let it rollback by drop. Then return the result.

If the operation succeeded but the commit failed, the commit error masks the operation’s success.

Because the operation and therefore this overall function can return an arbitrary error type, and there is not necessarily a direct relation between CryptoKeystoreError and E, this function requires an explicit mapping function to be provided.

NOTE: Because of TOCTOU, there is an interval between when we check if an existing transaction exists, and when we create our own. If a separate process creates a transaction during that interval, then this function must wait for that external transaction to complete before it can acquire the semaphore. This might be surprising, but isn’t worth putting in the effort to change; it’s not strictly a bug.

Source§

impl Database

Source

pub async fn open( path: &str, database_key: &DatabaseKey, ) -> CryptoKeystoreResult<Arc<Self>>

Open an encrypted Database at the provided location.

When compiled with target_os = "unknown", this opens a database encrypted via sqlite3-multiple-ciphers using its default encryption mechanism, stored in IndexedDB via the relaxed-idb shim.

When compiled normally, this opens a database encrypted via sqlcipher at a path in the local filesystem.

Source

pub fn open_in_memory() -> CryptoKeystoreResult<Arc<Self>>

Open an in-memory Database.

In-memory databases are never encrypted.

Source

pub async fn update_key( &self, new_key: &DatabaseKey, ) -> CryptoKeystoreResult<()>

Change the encryption key for this database.

Source

pub async fn close(self) -> CryptoKeystoreResult<()>

Source

pub async fn wipe(self) -> CryptoKeystoreResult<()>

Close and remove this database.

This deletes the database, including its encryption key. Future opens will always succeed with any arbitrary encryption key; they will simply open an empty database.

Source

pub async fn location(&self) -> Option<String>

Get the location of the database.

Returns None if the database is in-memory.

Source

pub async fn export_copy( &self, destination_path: &str, ) -> CryptoKeystoreResult<()>

Export a copy of the database to the specified path using VACUUM INTO.

This creates a fully vacuumed and optimized copy of the database. The copy will be encrypted with the same key as the source database.

§Arguments
  • destination_path - The file path where the database copy should be created
Source§

impl Database

Source

pub async fn mls_fetch_key_packages<V: MlsEntity>( &self, count: u32, ) -> CryptoKeystoreResult<Vec<V>>

Fetches Keypackages

§Arguments
  • count - amount of entries to be returned
§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_group_exists(&self, group_id: impl AsRef<[u8]> + Send) -> bool

Checks if the given MLS group id exists in the keystore Note: in case of any error, this will return false

§Arguments
  • group_id - group/conversation id
Source

pub async fn mls_group_persist( &self, group_id: impl AsRef<[u8]> + Send, state: &[u8], sender_nonce: u32, parent_group_id: Option<&[u8]>, ) -> CryptoKeystoreResult<()>

Persists a MlsGroup

§Arguments
  • group_id - group/conversation id
  • state - the group state
§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_groups_restore( &self, ) -> CryptoKeystoreResult<HashMap<Vec<u8>, (Option<Vec<u8>>, Vec<u8>)>>

Loads MlsGroups from the database. It will be returned as a HashMap where the key is the group/conversation id and the value the group state

§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_group_delete( &self, group_id: impl AsRef<[u8]> + Send, ) -> CryptoKeystoreResult<()>

Deletes MlsGroups from the database.

§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_pending_groups_save( &self, group_id: impl AsRef<[u8]> + Send, mls_group: &[u8], custom_configuration: &[u8], parent_group_id: Option<&[u8]>, ) -> CryptoKeystoreResult<()>

Saves a MlsGroup in a temporary table (typically used in scenarios where the group cannot be committed until the backend acknowledges it, like external commits)

§Arguments
  • group_id - group/conversation id
  • mls_group - the group/conversation state
  • custom_configuration - local group configuration
§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_pending_groups_load( &self, group_id: impl AsRef<[u8]> + Send, ) -> CryptoKeystoreResult<Option<(Vec<u8>, Vec<u8>)>>

Loads a temporary MlsGroup and its configuration from the database

§Arguments
  • id - group/conversation id
§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source

pub async fn mls_pending_groups_delete( &self, group_id: impl AsRef<[u8]> + Send, ) -> CryptoKeystoreResult<()>

Deletes a temporary MlsGroup from the database

§Arguments
  • id - group/conversation id
§Errors

Any common error that can happen during a database connection. IoError being a common error for example.

Source§

impl Database

Source

pub async fn proteus_store_prekey( &self, id: u16, prekey: &[u8], ) -> CryptoKeystoreResult<()>

Trait Implementations§

Source§

impl Debug for Database

Source§

fn fmt(&self, __derive_more_f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl FetchFromDatabase for Database

Source§

fn get<'life0, 'life1, 'async_trait, E>( &'life0 self, id: &'life1 E::PrimaryKey, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<Option<E>>> + Send + 'async_trait>>
where E: 'static + Entity + Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get an instance of E from the database by its primary key.
Source§

fn get_borrowed<'life0, 'life1, 'async_trait, E>( &'life0 self, id: &'life1 <E as BorrowPrimaryKey>::BorrowedPrimaryKey, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<Option<E>>> + Send + 'async_trait>>
where E: 'static + EntityGetBorrowed + Clone + Send + Sync + 'async_trait, E::PrimaryKey: Borrow<E::BorrowedPrimaryKey>, for<'a> &'a E::BorrowedPrimaryKey: KeyType, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get an instance of E from the database by the borrowed form of its primary key.
Source§

fn count<'life0, 'async_trait, E>( &'life0 self, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<u32>> + Send + 'async_trait>>
where E: 'static + Entity + Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Count the number of Es in the database.
Source§

fn load_all<'life0, 'async_trait, E>( &'life0 self, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<Vec<E>>> + Send + 'async_trait>>
where E: 'static + Entity + Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Load all Es from the database.
Source§

fn search<'life0, 'life1, 'async_trait, E, SearchKey>( &'life0 self, search_key: &'life1 SearchKey, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<Vec<E>>> + Send + 'async_trait>>
where E: 'static + Entity + SearchableEntity<SearchKey> + Clone + Send + Sync + 'async_trait, SearchKey: KeyType + 'async_trait, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Search for relevant instances of E given a search key.
Source§

fn get_unique<'a, 'life0, 'async_trait, U>( &'life0 self, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<Option<U>>> + Send + 'async_trait>>
where U: 'static + UniqueEntityExt + Entity + Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'a: 'async_trait, 'life0: 'async_trait,

Get the requested unique entity from the database.
Source§

fn exists<'a, 'life0, 'async_trait, U>( &'life0 self, ) -> Pin<Box<dyn Future<Output = CryptoKeystoreResult<bool>> + Send + 'async_trait>>
where U: 'static + UniqueEntityExt + Entity + Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'a: 'async_trait, 'life0: 'async_trait,

Determine whether a unique entity is present in the database.
Source§

impl OpenMlsKeyStore for Database

Source§

type Error = CryptoKeystoreError

The error type returned by the [OpenMlsKeyStore].
Source§

fn store<'life0, 'life1, 'life2, 'async_trait, V>( &'life0 self, id: &'life1 [u8], value: &'life2 V, ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: Sized + 'async_trait, V: 'async_trait + MlsEntity + Sync, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Store a value v that implements the [MlsEntity] trait for serialization for ID k. Read more
Source§

fn read<'life0, 'life1, 'async_trait, V>( &'life0 self, id: &'life1 [u8], ) -> Pin<Box<dyn Future<Output = Option<V>> + Send + 'async_trait>>
where Self: Sized + 'async_trait, V: 'async_trait + MlsEntity, 'life0: 'async_trait, 'life1: 'async_trait,

Read and return a value stored for ID k that implements the [MlsEntity] trait for deserialization. Read more
Source§

fn delete<'life0, 'life1, 'async_trait, V>( &'life0 self, id: &'life1 [u8], ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where V: 'async_trait + MlsEntity, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete a value stored for ID k. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> MaybeSendSync for T