pub struct Database<T, S = FileSource> where
    T: IntoJson + FromJson + 'static,
    S: Source
{ /* private fields */ }
Expand description

Represents a JasonDB database.

The type of values in the database is specified by the T generic parameter. This must implement Humphrey JSON’s IntoJson and FromJson traits, which can be done with its json_map macro. These traits are automatically implemented for basic types like strings and numbers.

Example

use jasondb::Database;
use jasondb::error::JasonError;
use humphrey_json::prelude::*;

struct Person {
    name: String,
    age: u8,
}

json_map! {
    Person,
    name => "name",
    age => "age"
}

fn main() -> Result<(), JasonError> {
    let mut db: Database<Person> = Database::new("database.jdb")?;

    db.set("alice", Person {
        name: "Alice".to_string(),
        age: 20,
    })?;

    db.set("bob", Person {
        name: "Bob".to_string(),
        age: 24,
    })?;

    let alice = db.get("alice")?;
    assert_eq!(alice.age, 20);

    Ok(())
}

Implementations

Opens the database from the given path, or creates an empty one if it doesn’t exist.

To create an empty database and throw an error if it already exists, use create. To open an existing database and throw an error if it doesn’t exist, use open.

Creates a new empty database at the given path.

If the file already exists, an error will be thrown.

Opens an existing database at the given path.

If the file doesn’t exist, an error will be thrown.

Converts the file-based database into an in-memory database by copying the contents of the file into memory.

Warning: changes made to the new in-memory database will not be reflected in the original file-based database.

Creates a new empty in-memory database.

Writes the in-memory database to a new file at the given path.

Creates a new database backed by the given source.

Compacts the database on load.

For smaller databases and for frequently-updated databases, it is good practice to do this on load. For more read-oriented databases, it can offer a minor performance boost but it does take longer to load.

Configures the database to use the given secondary index. This is intended for use in a builder pattern as the example below shows.

The field can be given as a dot-separated string or using the field macro, and it specifies how to find the field to index in the JSON representation of the type.

Example
let mut db = Database::new(source)?
    .with_index(field!(my_field.my_subfield))?
    .with_index("my_field.my_other_subfield")?;

Adds a synchronous replica to the database.

This is useful to add persistence to an in-memory database. By having an in-memory database with a synchronous file-based replica, you get the speed of the in-memory database for reads and the persistence of the file-based replica for writes. This is a good idea for databases that get many reads and less writes.

All writes to the database will be replicated to the all configured replicas synchronously, so having many replicas or having slow ones can slow down writes.

Any implementor of the Replica trait can be used. Currently, this is just Database, but the API has been designed in such a way that in the future, other types of replica could be used, for example distributed replicas or even other database systems completely.

Example
// Creating a new in-memory database with synchronous replication to disk.
let mut db = Database::new_in_memory()
    .with_replica(Database::create("sync_file_replica.jdb")?);

// Opening a disk-based database, copying it into memory, and synchronously replicating it back to disk.
let mut db = Database::open("database.jdb")?
    .into_memory()?
    .with_replica(Database::open("database.jdb")?);

Adds an asynchronous replica to the database, and starts a background thread to replicate writes to it.

All writes to the database will be replicated to the all configured replicas asynchronously, so data loss is possible in the event of a panic. The database will attempt to continue replicating writes to the replica if an error causes the database to be dropped, but if drop is not called, all pending writes will be lost.

Any implementor of the Replica trait can be used. Currently, this is just Database, but the API has been designed in such a way that in the future, other types of replica could be used, for example distributed replicas or even other database systems completely.

Example
let mut db = Database::new_in_memory()
    .with_async_replica(Database::create("async_file_replica.jdb")?);

Gets the value with the given key.

Returns Err(JasonError::InvalidKey) if the index is not found, or another error if the source fails.

Sets the value with the given key to the given value.

Updates all indexes with the new value.

Deletes the value with the given key.

This appends a null value to the end of the database, and updates all indexes.

Executes the given query on the database.

Queries are typically constructed with the query! macro.

Creates an iterator over the database.

This only reads from the database when it is used, so is very cheap to create. It does, however, sort the keys so it can iterate over the database in the order in which it is stored on disk. To avoid this behaviour, use the iter_unordered method instead.

Creates an iterator over the database, but does not sort the keys.

This is quicker to create, but will be slower to iterate over since the disk will not be read sequentially.

Performs compaction on the database.

Migrates the database to a new type according to the function.

Trait Implementations

Returns the “default value” for a type. Read more

Replicate the change to the replica. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.