Struct alexandria::Library [−][src]
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]
P: Into<&'tmp Path>,
S: Into<String>,
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]
&self,
id: Session,
path: Path,
tags: T,
data: Vec<D>
) -> Result<Id> where
T: Into<TagSet>,
D: Into<Diff>,
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]
&self,
id: Session,
path: Path,
tags: T,
data: D
) -> Result<Id> where
T: Into<TagSet>,
D: Into<Diff>,
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]
D: Into<Diff>,
Update a record in-place
pub async fn query<S>(&self, id: S, q: Query) -> Result<QueryResult> where
S: Into<Session> + Debug,
[src]
S: Into<Session> + Debug,
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]
self: &Arc<Self>,
id: S,
q: Query
) -> Result<QueryIterator> where
S: Into<Session> + Debug,
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]
S: Into<Session> + Debug,
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]
S: Into<Session> + Debug,
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]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T> Instrument for T
[src]
pub fn instrument(self, span: Span) -> Instrumented<Self>
[src]
pub fn in_current_span(self) -> Instrumented<Self>
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
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]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,