Skip to main content

CovenBuilder

Struct CovenBuilder 

Source
pub struct CovenBuilder { /* private fields */ }
Expand description

The choices for creating or opening a store (E1).

Implementations§

Source§

impl CovenBuilder

Source

pub async fn open_read_only( self, store: StoreId, ) -> Result<CovenReadHandle, ReadOnlyOpenError>

Opens the store for reading only, alongside a handle that has it open. Its shared lock protects both read connections and local cache metadata. It runs no migration and refuses a database whose schema is newer, whose coven tables need migrating, or whose indexes were built with other versions of the app’s collations and functions. File reads connect using saved settings and custody credentials when present.

Source§

impl CovenBuilder

Source

pub fn synced_tables(self, tables: Vec<SyncedTable>) -> Self

The tables that sync (E2). Required.

Source

pub fn namespaces(self, namespaces: Vec<Namespace>) -> Self

The file namespaces, each with its kind and cache budget (E1). A file is staged into one of them.

Source

pub fn migrations(self, migrations: Vec<Migration>) -> Self

The app’s schema migrations, numbered from 1 with no gaps (E13). Required.

Source

pub fn clock(self, clock: ClockRef) -> Self

The wall clock that timestamps use (§7.2). Defaults to the system clock.

Source

pub fn id_source(self, ids: IdSourceRef) -> Self

The source of new ids: store, circle, member, key, invite and file ids, and this install’s device id (Appendix F.2). Defaults to UuidIds.

Source

pub fn storage_connector(self, connector: Arc<dyn StorageConnector>) -> Self

Replace provider construction in tests while exercising setup, credential custody, reconnect, restore and recovery through the production graph. coven_storage::test_utils::MemoryStorage implements this connector.

Source

pub fn oauth_clients(self, clients: OAuthClients) -> Self

Configure this app’s own sign-in clients. Coven supplies no client ids.

Source

pub fn oauth_presenter(self, presenter: Arc<dyn OAuthPresenter>) -> Self

Present sign-in through the app’s platform sheet. Desktop defaults to DesktopOAuthPresenter; iOS and Android require the app’s presenter.

Source

pub async fn authenticate( &mut self, access: OAuthAccess, ) -> Result<(), OAuthError>

Sign in and keep tokens in session custody for restore, join or opening. Replaces the prior sign-in only on success. Dropping the future cancels it.

Source

pub fn max_concurrent_uploads(self, n: NonZeroUsize) -> Self

Limit file uploads running together; defaults to one.

Source

pub fn max_concurrent_downloads(self, n: NonZeroUsize) -> Self

Limit file downloads running together; defaults to one. The sequence’s own reads don’t count against it.

Source

pub fn key_custody(self, custody: CustodyChoice<StoreKeyring>) -> Self

Where this device keeps the store keys: the OS keychain by default, a file sealed with a passphrase, memory for this session only, or the app’s own Custody<StoreKeyring>.

Source

pub fn identity_custody(self, custody: CustodyChoice<MemberIdentity>) -> Self

Where this device keeps its member’s keys, with the same four choices and the app’s own Custody<MemberIdentity> as the last.

Source

pub fn sqlite_settings(self, settings: SqliteSettings) -> Self

SQLite settings for every connection a handle opens to the store’s database (§4). Unset ones keep SQLite’s defaults, except that checkpoint_fullfsync is on for macOS and iOS; the page size and auto-vacuum mode apply only when the database is created.

Source

pub fn collation<F>( self, name: impl Into<String>, version: u32, compare: F, ) -> Self
where F: Fn(&str, &str) -> Ordering + Send + Sync + 'static,

A collation the app’s SQL names with COLLATE name (§4), ordering text by compare at version, on every connection a handle opens to the store’s database. The order is part of the store’s schema: compare must be deterministic, the same on every device and in every app version that registers this version, and a total order. Every change to the order takes a new version, and a writable open then rebuilds the indexes in it. A name that is SQLite’s own (BINARY, NOCASE, RTRIM) or given twice fails the open, and a panic in compare ends the process.

Source

pub fn function<F, T>( self, name: impl Into<String>, arguments: u8, determinism: Determinism, compute: F, ) -> Self
where F: Fn(&FunctionArguments<'_>) -> SqliteResult<T> + Send + Sync + 'static, T: Into<Value>,

A scalar function the app’s SQL calls as name(...) with exactly arguments arguments (§4), on every connection a handle opens to the store’s database. compute reads the arguments and returns the result, or an error that fails the statement calling it. A deterministic function can appear in indexes, CHECKs and generated columns, and is then part of the store’s schema: at its version it must give the same result for the same arguments on every device and in every app version, and takes at least one argument. Every change to its results takes a new version, and a writable open then rebuilds the indexes that call it. A name SQLite or coven already has, one with coven’s prefix coven_ or _coven_, or one given twice fails the open, and a panic in compute ends the process.

Source

pub async fn create_store( self, name: &str, ) -> Result<CovenHandle, StoreCreationError>

Create and open a store, initializing its member in the chosen custody before publication. Cancellation does not interrupt creation or rollback. Errors carry no handle; a published store is closed before returning.

Source

pub async fn open( self, store: StoreId, on_progress: impl Fn(Progress<OpenStep>), ) -> CovenResult<CovenHandle>

Opens the store for reading and writing, taking the store’s lock. Opening always migrates coven’s tables before the app’s schema, then unlocks both custody sessions before resuming unfinished operations and committed file work. Empty custody is allowed; an unlock failure prevents opening. No sync loop starts, and local database calls need no key material. on_progress is called on this task with each step the open runs and how much of it is done, at most a few times a second (§4).

Source

pub async fn resume_deletion( self, store: StoreId, ) -> Result<(), StoreDeletionError>

Finishes this device’s recorded deletion of store, which CovenHandle::delete_store began and couldn’t finish: it opens the store as open does, then goes on as the deletion would, with the choice for unsent work it recorded. Before the device’s removal is journaled, a refusal or failure removes the record and leaves the store as it was; from the journal on, a failure is StoreDeletionError::Unfinished and the deletion stays recorded (§11.6, E1). A store with no deletion recorded fails with StoreDeletionError::NoUnfinishedDeletion.

Source

pub async fn reset_device( self, store: StoreId, device_name: &str, on_status: impl Fn(BootstrapStatus), ) -> Result<CovenHandle, BootstrapError>

Replace this installation with a new device loaded from storage (§19.3), whenever the app chooses: after sync found another copy using this device’s id, a damaged database, or a device entry open found missing. Uses saved settings, credentials and member keys; nothing unsent is salvaged. The new device loads beside the old copy, which moves aside only once loading is complete; saved member keys that history has replaced fail with MemberKeysReplaced and change nothing. Just before the fresh device registers, the reset records itself and only goes forward: the store refuses opens with StoreLockError::ReplacementUnfinished until this call, or resume_replacement, finishes it. An interrupted call resumes with the same fresh id. A replacement restore_device began is refused with StoreLockError::ReplacementUnfinished, changing nothing. The returned handle’s device_reset() names the old and new ids. on_status hears how far the new device has come, as the other bootstrap calls report it.

Source

pub async fn restore_device( self, store: StoreId, code: &str, s3_credentials: Option<S3Credentials>, device_name: &str, prepare: impl FnOnce(BulkSqlContext<'_>) -> CovenResult<()> + Send + 'static, on_status: impl Fn(BootstrapStatus), cancel: &Receiver<bool>, ) -> Result<CovenHandle, BootstrapError>

Restore this device’s installation of store from the person’s current restore code, for a device whose member keys were replaced (§13.1). The code must name this store, and its pair must be current, checked against history before the store or keychain changes. The new device loads beside the old copy, which stays openable until the restore records itself, just before its fresh device registers; from then on the store refuses opens and the restore only goes forward, and once registered it swaps in and the old copy is removed. Cancelling past the record waits for the registration, then fails with RestoreRegistered. An interrupted call is finished by retrying it, or by resume_replacement; a replacement reset_device began is refused with StoreLockError::ReplacementUnfinished, changing nothing. A device whose custody and applied history already hold the code’s pair just opens. S3 requires the separately held key, as restore_from_code does. prepare is the app’s step on the new installation: one bulk write (CovenHandle::write_bulk) of its device-local tables, run after loading and before the record, so what it writes, such as preferences read from the old copy before the call, takes the old copy’s place with the new installation or not at all. A call that finds the replacement recorded, or the pair already installed, doesn’t run it.

Source

pub async fn resume_replacement( self, store: StoreId, on_status: impl Fn(BootstrapStatus), cancel: &Receiver<bool>, ) -> Result<CovenHandle, BootstrapError>

Finishes this device’s replacement of store past its record, as the call that began it would: reset_device or restore_device, from what the replacement kept on the device, with neither the code nor a new sign-in (§19.3). On Dropbox and OneDrive it connects through the kept sign-in, or a sign-in this builder holds once it grants the location’s access. A store with no replacement under way fails with BootstrapError::NoUnfinishedReplacement.

Source

pub async fn unfinished_joins(&self) -> Result<Vec<InviteInfo>, BootstrapError>

The joins under way on this device, ordered by store id (§13.2). A saved code coven can’t read fails the call; it is never skipped. An unfinished installation that keeps neither a saved code nor a restore’s record, and that no call holds, is deleted: a crash left it before its call wrote to storage (§13.4).

Source

pub async fn resume_join( self, store: StoreId, on_status: impl Fn(BootstrapStatus), control: &JoinControl, ) -> Result<Option<CovenHandle>, BootstrapError>

Continues an unfinished join from its saved code and device name, as join_with_invite does. On Dropbox and OneDrive it connects through the sign-in the join keeps on the device, or through a sign-in this builder holds, which replaces the kept one once it is shown to grant the location’s access. With neither, or with a kept sign-in the provider refuses even after its one refresh, it fails with OAuthError::Reauthorize and the join stays unfinished (§13.2). Returns None when the request was declined or the invite expired, after deleting the kept sign-in and the saved code. A store with no saved code fails with BootstrapError::NoUnfinishedJoin.

Source

pub async fn unfinished_restores( &self, ) -> Result<Vec<CodeMetadata>, BootstrapError>

The restores under way on this device, ordered by store id: each restore that recorded itself before registering the device and has not ended, as decode_code_info reads its code (§13.1). A record coven can’t read fails the call; it is never skipped. An unfinished installation that keeps neither a record nor a join’s saved code, and that no call holds, is deleted, as unfinished_joins does (§13.4).

Source

pub async fn resume_restore( self, store: StoreId, on_status: impl Fn(BootstrapStatus), cancel: &Receiver<bool>, ) -> Result<CovenHandle, BootstrapError>

Continues an unfinished restore from its record, as restore_from_code does: the code and device name it recorded, and the S3 key or sign-in it kept on the device. On Dropbox and OneDrive a sign-in this builder holds replaces the kept one once it is shown to grant the location’s access; with neither, or with a kept sign-in the provider refuses even after its one refresh, it fails with OAuthError::Reauthorize and the restore stays unfinished. Cancelling ends it as restore_from_code’s cancel does. A store with no record fails with BootstrapError::NoUnfinishedRestore.

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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
§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. 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> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

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

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,