Struct alexandria::Library[][src]

pub struct Library { /* fields omitted */ }

In-memory representation of an alexandria database

Refer to Builder to configure and initialise an alexandria instance.

Implementations

impl Library[src]

pub fn load<'tmp, P, S>(_: P, _: S) -> Result<Self> where
    P: Into<&'tmp Path>,
    S: Into<String>, 
[src]

Load and re-initialise a previous database session from disk

pub fn sessions<'lib>(&'lib self) -> SessionsApi<'lib>[src]

Load the database sessions API scope

pub async fn batch<T, D>(
    &self,
    id: Session,
    path: Path,
    tags: T,
    data: Vec<D>
) -> Result<Id> where
    T: Into<TagSet>,
    D: Into<Diff>, 
[src]

Similar to insert, but instead operating on a batch of Diffs

pub async fn insert<T, D>(
    &self,
    id: Session,
    path: Path,
    tags: T,
    data: D
) -> Result<Id> where
    T: Into<TagSet>,
    D: Into<Diff>, 
[src]

Insert a new record into the library and return it’s ID

You need to have a valid and active user session to do so, and the path must be unique.

pub async fn delete(&self, id: Session, path: Path) -> Result<()>[src]

pub async fn update<D>(&self, id: Session, path: Path, diff: D) -> Result<()> where
    D: Into<Diff>, 
[src]

Update a record in-place

pub async fn query<S>(&self, id: S, q: Query) -> Result<QueryResult> where
    S: Into<Session> + Debug
[src]

Query the database with a specific query object

Request data from alexandria via a Query object. A query can only touch a single parameter, such as the Record Id, the path or a set query via tags. The data returned are snapshots or records that are immutable. If you want to make changes to them, use update() with a Diff instead.

Also: future writes will not propagate to the copy of the Record returned from this function, because alexandria is Copy-on-Write. You will need to query the database again in the future.

Examples

This code makes a direct query via the path of a record. This will only return a single record if successful.

let path = Path::from("/msg:alice");
lib.query(GLOBAL, Query::Path(path)).await;

Search tags

In alexandria you can tag records with extra metadata (which is also encrypted), to make queries easier and even build relationships between records in your application. These tags are String-keyed, with an arbitrary (or no) payload and can be used to make more precise (and fast!) search queries into the database.

The constraints imposed by tag queries are modelled on set theory and can be created via the TagQuery helper type.

Following are a few examples for tag queries.

let tags = TagSet::from(vec![tag1, tag2]);
lib.query(GLOBAL, Query::tags().subset(tags)).await;

pub async fn query_iter<S>(
    self: &Arc<Self>,
    id: S,
    q: Query
) -> Result<QueryIterator> where
    S: Into<Session> + Debug
[src]

Create an iterator from a database query

The primary difference between this function and query() is that no records are returned or loaded immediately from the database. Instead a query is stored, sized and estimated at the time of querying and can then be stepped through. This allows for fetching only a range of objects, limiting memory usage.

Paths that are inserted after the QueryIterator was constructed aren’t automatically added to it, because it’s internal state is atomic for the time it was created. If you want to get updates to the database as they happen, consider a Subscription instead.

Following is an example for an iterator query, mirroring most of the query() usage quite closely.

let tags = TagSet::from(vec![tag1, tag2]);
let iter = lib
    .query_iter(GLOBAL, Query::tags().equals(tags))
    .await?;
iter.skip(5);
let rec = iter.next().await;

Garbage collection

By default, garbage collection isn’t locked for paths that are included in an iterator. What this means is that any delete call can remove records that will at some point be accessed by the returned iterator, resulting in an Err(_) return. To avoid this race condition, you can call lock() on the iterator, which blocks alexandria from cleaning the iternal record representation for items that are supposed to be accessed by the iterator.

Note: query may still return “No such path” for these items, since they were already deleted from the tag cache. And a caveat worth mentioning: if the program aborts before the Iterator drop was able to run, the items will not be cleaned from disk and reloaded into cache on restart.

pub async fn subscribe<S>(&self, id: S, q: Query) -> Result<Subscription> where
    S: Into<Session> + Debug
[src]

Subscribe to future database updates via a query filter

When querying repeatedly isn’t an option, or would lead to decreased performance, it’s also possible to register a subscription. They use the same mechanism as Queries to filter through tags and paths, but return a type that can be async-polled for updates.

This doesn’t give immediate access to the data, only the path that was changed, but can then be used to make a real query into the database to get an updated set of data.

let tags = TagSet::from(vec![my_tag]);
let sub = lib.subscribe(GLOBAL, Query::tags().subset(tags)).await?;

let path = sub.next().await;
let new_data = lib.query(GLOBAL, Query::Path(path)).await?;

pub async fn path_exists<S>(&self, id: S, p: Path) -> Result<bool> where
    S: Into<Session> + Debug
[src]

Check if a path exists for a particular session

When inserting data, sometimes it’s useful to check the path that was just inserted, or was inserted by a previous operation. Because this is such a common operation, this utility function aims to make this workflow easier.

If you want the actual type of a path node, use query() instead!

Auto Trait Implementations

impl !RefUnwindSafe for Library

impl Send for Library

impl Sync for Library

impl Unpin for Library

impl !UnwindSafe for Library

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

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