pub struct Bucket<'b, 'tx: 'b> { /* private fields */ }
Expand description
A collection of data
Buckets contain a collection of data, sorted by key.
The data can either be key / value pairs, or nested buckets.
You can use buckets to get
and put
data,
as well as get
and create
nested buckets.
You can use a Cursor
to iterate over all the data in a bucket.
Buckets have an inner auto-incremented counter that keeps track
of how many unique keys have been inserted into the bucket.
You can access that using the next_int()
function.
Examples
use jammdb::{DB, Data};
let db = DB::open("my.db")?;
let mut tx = db.tx(true)?;
// create a root-level bucket
let bucket = tx.create_bucket("my-bucket")?;
// create nested bucket
bucket.create_bucket("nested-bucket")?;
// insert a key / value pair (using &str)
bucket.put("key", "value");
// insert a key / value pair (using [u8])
bucket.put([1,2,3], [4,5,6]);
for data in bucket.cursor() {
match data {
Data::Bucket(b) => println!("found a bucket with the name {:?}", b.name()),
Data::KeyValue(kv) => println!("found a kv pair {:?} {:?}", kv.key(), kv.value()),
}
}
println!("Bucket next_int {:?}", bucket.next_int());
In order to keep the database flexible, it is possible to obtain references to multiple sub-buckets from a single parent.
That means it is possible to obtain a reference to a bucket, then delete that bucket from the parent. Do not do this.
If you try to use a bucket that has been deleted it will panic, and nobody wants that 🙃.
The same is true for any iterator over a bucket as well, like a Cursor
, [Buckets
], or [KVPairs
].
Implementations§
source§impl<'b, 'tx> Bucket<'b, 'tx>
impl<'b, 'tx> Bucket<'b, 'tx>
sourcepub fn put<'a, T: ToBytes<'tx>, S: ToBytes<'tx>>(
&'a self,
key: T,
value: S
) -> Result<Option<KVPair<'b, 'tx>>, Error>
pub fn put<'a, T: ToBytes<'tx>, S: ToBytes<'tx>>( &'a self, key: T, value: S ) -> Result<Option<KVPair<'b, 'tx>>, Error>
Adds to or replaces key / value data in the bucket. Returns an error if the key currently exists but is a bucket instead of a key / value pair.
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(true)?;
// create a root-level bucket
let bucket = tx.create_bucket("my-bucket")?;
// insert data
bucket.put("123", "456")?;
// update data
bucket.put("123", "789")?;
bucket.create_bucket("nested-bucket")?;
assert!(bucket.put("nested-bucket", "data").is_err());
pub fn get<'a, T: AsRef<[u8]>>(&'a self, key: T) -> Option<Data<'b, 'tx>>
pub fn get_kv<'a, T: AsRef<[u8]>>(&'a self, key: T) -> Option<KVPair<'b, 'tx>>
sourcepub fn delete<T: AsRef<[u8]>>(&self, key: T) -> Result<KVPair<'_, '_>, Error>
pub fn delete<T: AsRef<[u8]>>(&self, key: T) -> Result<KVPair<'_, '_>, Error>
Deletes a key / value pair from the bucket
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(false)?;
let bucket = tx.get_bucket("my-bucket")?;
// check if data is there
assert!(bucket.get_kv("some-key").is_some());
// delete the key / value pair
bucket.delete("some-key")?;
// data should no longer exist
assert!(bucket.get_kv("some-key").is_none());
sourcepub fn get_bucket<'a, T: ToBytes<'tx>>(
&'a self,
name: T
) -> Result<Bucket<'b, 'tx>, Error>
pub fn get_bucket<'a, T: ToBytes<'tx>>( &'a self, name: T ) -> Result<Bucket<'b, 'tx>, Error>
Gets an already created bucket.
Returns an error if
- the given key does not exist
- the key is for key / value data, not a bucket
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(false)?;
// get a root-level bucket
let bucket = tx.get_bucket("my-bucket")?;
// get nested bucket
let mut sub_bucket = bucket.get_bucket("nested-bucket")?;
// get nested bucket
let sub_sub_bucket = sub_bucket.get_bucket("double-nested-bucket")?;
sourcepub fn create_bucket<'a, T: ToBytes<'tx>>(
&'a self,
name: T
) -> Result<Bucket<'b, 'tx>, Error>
pub fn create_bucket<'a, T: ToBytes<'tx>>( &'a self, name: T ) -> Result<Bucket<'b, 'tx>, Error>
Creates a new bucket.
Returns an error if
- the given key already exists
- It is in a read-only transaction
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(true)?;
// create a root-level bucket
let bucket = tx.create_bucket("my-bucket")?;
// create nested bucket
let mut sub_bucket = bucket.create_bucket("nested-bucket")?;
// create nested bucket
let mut sub_sub_bucket = sub_bucket.create_bucket("double-nested-bucket")?;
sourcepub fn get_or_create_bucket<'a, T: ToBytes<'tx>>(
&'a self,
name: T
) -> Result<Bucket<'b, 'tx>, Error>
pub fn get_or_create_bucket<'a, T: ToBytes<'tx>>( &'a self, name: T ) -> Result<Bucket<'b, 'tx>, Error>
Creates a new bucket if it doesn’t exist
Returns an error if
- It is in a read-only transaction
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
{
let mut tx = db.tx(true)?;
// create a root-level bucket
let bucket = tx.get_or_create_bucket("my-bucket")?;
tx.commit()?;
}
{
let mut tx = db.tx(true)?;
// get the existing a root-level bucket
let bucket = tx.get_or_create_bucket("my-bucket")?;
}
sourcepub fn delete_bucket<T: ToBytes<'tx>>(&self, key: T) -> Result<(), Error>
pub fn delete_bucket<T: ToBytes<'tx>>(&self, key: T) -> Result<(), Error>
Deletes an bucket.
Returns an error if
- the given key does not exist
- the key is for key / value data, not a bucket
- It is in a read-only transaction
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(true)?;
// get a root-level bucket
let bucket = tx.get_bucket("my-bucket")?;
// delete nested bucket
bucket.delete_bucket("nested-bucket")?;
sourcepub fn cursor<'a>(&'a self) -> Cursor<'b, 'tx> ⓘ
pub fn cursor<'a>(&'a self) -> Cursor<'b, 'tx> ⓘ
Get a cursor to iterate over the bucket.
Examples
use jammdb::{DB, Data};
let db = DB::open("my.db")?;
let mut tx = db.tx(false)?;
let bucket = tx.get_bucket("my-bucket")?;
for data in bucket.cursor() {
match data {
Data::Bucket(b) => println!("found a bucket with the name {:?}", b.name()),
Data::KeyValue(kv) => println!("found a kv pair {:?} {:?}", kv.key(), kv.value()),
}
}
sourcepub fn next_int(&self) -> u64
pub fn next_int(&self) -> u64
Returns the next integer for the bucket.
The integer is automatically incremented each time a new key is added to the bucket.
You can it as a unique key for the bucket, since it will increment each time you add something new.
It will not increment if you put
a key that already exists
Examples
use jammdb::{DB};
let db = DB::open("my.db")?;
let mut tx = db.tx(true)?;
// create a root-level bucket
let bucket = tx.create_bucket("my-bucket")?;
// starts at 0
assert_eq!(bucket.next_int(), 0);
let next_int = bucket.next_int();
bucket.put(next_int.to_be_bytes(), [0]);
// auto-incremented after inserting a key / value pair
assert_eq!(bucket.next_int(), 1);
bucket.put(0_u64.to_be_bytes(), [0, 0]);
// not incremented after updating a key / value pair
assert_eq!(bucket.next_int(), 1);
bucket.create_bucket("nested-bucket")?;
// auto-incremented after creating a nested bucket
assert_eq!(bucket.next_int(), 2);
sourcepub fn buckets<'a>(
&'a self
) -> impl Iterator<Item = (BucketName<'b, 'tx>, Bucket<'b, 'tx>)>
pub fn buckets<'a>( &'a self ) -> impl Iterator<Item = (BucketName<'b, 'tx>, Bucket<'b, 'tx>)>
Iterator over the sub-buckets in this bucket.
sourcepub fn kv_pairs<'a>(&'a self) -> impl Iterator<Item = KVPair<'b, 'tx>>
pub fn kv_pairs<'a>(&'a self) -> impl Iterator<Item = KVPair<'b, 'tx>>
Iterator over the key / value pairs in this bucket.