pub struct CovenBuilder { /* private fields */ }Expand description
The choices for creating or opening a store (E1).
Implementations§
Source§impl CovenBuilder
impl CovenBuilder
Sourcepub async fn open_read_only(
self,
store: StoreId,
) -> Result<CovenReadHandle, ReadOnlyOpenError>
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
impl CovenBuilder
Sourcepub fn synced_tables(self, tables: Vec<SyncedTable>) -> Self
pub fn synced_tables(self, tables: Vec<SyncedTable>) -> Self
The tables that sync (E2). Required.
Sourcepub fn namespaces(self, namespaces: Vec<Namespace>) -> Self
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.
Sourcepub fn migrations(self, migrations: Vec<Migration>) -> Self
pub fn migrations(self, migrations: Vec<Migration>) -> Self
The app’s schema migrations, numbered from 1 with no gaps (E13). Required.
Sourcepub fn clock(self, clock: ClockRef) -> Self
pub fn clock(self, clock: ClockRef) -> Self
The wall clock that timestamps use (§7.2). Defaults to the system clock.
Sourcepub fn id_source(self, ids: IdSourceRef) -> Self
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.
Sourcepub fn storage_connector(self, connector: Arc<dyn StorageConnector>) -> Self
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.
Sourcepub fn oauth_clients(self, clients: OAuthClients) -> Self
pub fn oauth_clients(self, clients: OAuthClients) -> Self
Configure this app’s own sign-in clients. Coven supplies no client ids.
Sourcepub fn oauth_presenter(self, presenter: Arc<dyn OAuthPresenter>) -> Self
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.
Sourcepub async fn authenticate(
&mut self,
access: OAuthAccess,
) -> Result<(), OAuthError>
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.
Sourcepub fn max_concurrent_uploads(self, n: NonZeroUsize) -> Self
pub fn max_concurrent_uploads(self, n: NonZeroUsize) -> Self
Limit file uploads running together; defaults to one.
Sourcepub fn max_concurrent_downloads(self, n: NonZeroUsize) -> Self
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.
Sourcepub fn key_custody(self, custody: CustodyChoice<StoreKeyring>) -> Self
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>.
Sourcepub fn identity_custody(self, custody: CustodyChoice<MemberIdentity>) -> Self
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.
Sourcepub fn sqlite_settings(self, settings: SqliteSettings) -> Self
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.
Sourcepub fn collation<F>(
self,
name: impl Into<String>,
version: u32,
compare: F,
) -> Self
pub fn collation<F>( self, name: impl Into<String>, version: u32, compare: F, ) -> Self
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.
Sourcepub fn function<F, T>(
self,
name: impl Into<String>,
arguments: u8,
determinism: Determinism,
compute: F,
) -> Self
pub fn function<F, T>( self, name: impl Into<String>, arguments: u8, determinism: Determinism, compute: F, ) -> Self
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.
Sourcepub async fn create_store(
self,
name: &str,
) -> Result<CovenHandle, StoreCreationError>
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.
Sourcepub async fn open(
self,
store: StoreId,
on_progress: impl Fn(Progress<OpenStep>),
) -> CovenResult<CovenHandle>
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).
Sourcepub async fn resume_deletion(
self,
store: StoreId,
) -> Result<(), StoreDeletionError>
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.
Sourcepub async fn reset_device(
self,
store: StoreId,
device_name: &str,
on_status: impl Fn(BootstrapStatus),
) -> Result<CovenHandle, BootstrapError>
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.
Sourcepub 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>
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.
Sourcepub async fn resume_replacement(
self,
store: StoreId,
on_status: impl Fn(BootstrapStatus),
cancel: &Receiver<bool>,
) -> Result<CovenHandle, BootstrapError>
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.
Sourcepub async fn unfinished_joins(&self) -> Result<Vec<InviteInfo>, BootstrapError>
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).
Sourcepub async fn resume_join(
self,
store: StoreId,
on_status: impl Fn(BootstrapStatus),
control: &JoinControl,
) -> Result<Option<CovenHandle>, BootstrapError>
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.
Sourcepub async fn unfinished_restores(
&self,
) -> Result<Vec<CodeMetadata>, BootstrapError>
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).
Sourcepub async fn resume_restore(
self,
store: StoreId,
on_status: impl Fn(BootstrapStatus),
cancel: &Receiver<bool>,
) -> Result<CovenHandle, BootstrapError>
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§
impl Freeze for CovenBuilder
impl !RefUnwindSafe for CovenBuilder
impl Send for CovenBuilder
impl Sync for CovenBuilder
impl Unpin for CovenBuilder
impl UnsafeUnpin for CovenBuilder
impl !UnwindSafe for CovenBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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