buffdb 0.2.0

Embedded storage at the speed of light.
# buffDB

This is an early implementation of a persistence layer for gRPC written in Rust and based on RocksDB.
The goal is to abstract a lot of the complexity associated with using protobufs and flattbuffers so
that mobile users can go fast.

## How to run

To run the server, you need to [have Rust installed](https://rustup.rs/). Then, with the repository
cloned, you can run

```bash
cargo run -- run
```

This will start the server on `[::1]:50051`, storing the key-value pairs in `kv_store.db` and
the blob data in `blob_store.db`. All three can be configured with command line flags:
`--addr`, `--kv-store`, and `--blob-store` respectively.

To build with optimizations enabled, run `cargo build --release`. The resulting binary will be
located at `target/release/buffdb`. It is statically linked, so it can be moved anywhere on your
file system without issue.

Prefer to handle the gRPC server yourself? `buffdb` can be used as a library as well!

## Example library usage in Rust

Run `cargo add buffdb tonic tokio` to add the necessary dependencies. Then you can execute the
following code:

```rust
use buffdb::kv::{Key, KeyValue, KeyValueRpc, KvStore};
use tonic::{Request, IntoRequest};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let store = KvStore::new_in_memory();

    store
        .set(
            KeyValue {
                key: "key".to_owned(),
                value: "value".to_owned(),
            }
            .into_request()
        )
        .await?;

    let response = store
        .delete(Key { key: "key".to_owned() } .into_request() )
        .await?;
    assert_eq!(response.get_ref().value, "value");

    let response = store
        .get(Key { key: "key".to_owned() }.into_request())
        .await;
    assert!(response.is_err());

    Ok(())
}
```

This project is inspired by conversations with Michael Cahill, Professor of Practice, School of Computer Science, University of Sydney

## Command line interface

You can use `buffdb help` to see the commands and flags permitted. The following operations are
currently supported:

- `buffdb run [ADDR]`, starting the server. The default address is `[::1]:50051`.
- `buffdb kv get <KEY>`, printing the value to stdout.
- `buffdb kv set <KEY> <VALUE>`, setting the value.
- `buffdb kv delete <KEY>`, deleting the value.
- `buffdb kv eq [KEYS]...`, exiting successfully if the values for all provided keys are equal.
  Exits with an error code if any two values are not equal.
- `buffdb kv not-eq [KEYS]...`, exiting successfully if the values for all provided keys are
  unique. Exits with an error code if any two values are equal.
- `buffdb blob get <ID>`, printing the data to stdout. Note that this is arbitrary bytes!
- `buffdb blob store <FILE> [METADATA]`, storing the file (use `-` for stdin) and printing the ID
  to stdout. Metadata is optional.
- `buffdb blob update <ID> data <FILE>`, updating the data of the blob. Use `-` for stdin. Metadata
  is unchanged.
- `buffdb blob update <ID> metadata [METADATA]`, updating the metadata of the blob. Data is
  unchanged. Omitting `[METADATA]` will set the metadata to null.
- `buffdb blob update <ID> all <FILE> [METADATA]`, updating both the data and metadata of the blob.
  For `<FILE>`, use `-` for stdin. Omitting `[METADATA]` will set the metadata to null.
- `buffdb blob delete <ID>`, deleting the blob.
- `buffdb blob eq-data [IDS]...`, exiting successfully if the blobs for all provided IDs are equal.
  Exits with an error code if any two blobs are not equal.
- `buffdb blob not-eq-data [IDS]...`, exiting successfully if the blobs for all provided IDs are
    unique. Exits with an error code if any two blobs are equal.

Commands altering a store will exit with an error code if the key/id does not exist. An exception
to this is updating the metadata of a blob to be null, as it is not required to exist beforehand.

All commands for `kv` and `blob` can use `-s`/`--store` to specify which store to use. The defaults
are `kv_store.db` and `blob_store.db` respectively.