db: supply table as Type not as fn param (#32)

This commit is contained in:
Georgios Konstantopoulos
2022-10-10 12:52:42 -07:00
committed by GitHub
parent 60d3c64410
commit c41c6b99a6
4 changed files with 18 additions and 29 deletions

View File

@ -175,12 +175,12 @@ mod tests {
// PUT // PUT
let tx = env.begin_mut_tx().expect(ERROR_INIT_TX); let tx = env.begin_mut_tx().expect(ERROR_INIT_TX);
tx.put(PlainState, key, value.clone()).expect(ERROR_PUT); tx.put::<PlainState>(key, value.clone()).expect(ERROR_PUT);
tx.commit().expect(ERROR_COMMIT); tx.commit().expect(ERROR_COMMIT);
// GET // GET
let tx = env.begin_tx().expect(ERROR_INIT_TX); let tx = env.begin_tx().expect(ERROR_INIT_TX);
let result = tx.get(PlainState, key).expect(ERROR_GET); let result = tx.get::<PlainState>(key).expect(ERROR_GET);
assert!(result.expect(ERROR_RETURN_VALUE) == value); assert!(result.expect(ERROR_RETURN_VALUE) == value);
tx.commit().expect(ERROR_COMMIT); tx.commit().expect(ERROR_COMMIT);
} }
@ -199,7 +199,7 @@ mod tests {
// PUT // PUT
let result = env.update(|tx| { let result = env.update(|tx| {
tx.put(PlainState, key, value.clone()).expect(ERROR_PUT); tx.put::<PlainState>(key, value.clone()).expect(ERROR_PUT);
200 200
}); });
assert!(result.expect(ERROR_RETURN_VALUE) == 200); assert!(result.expect(ERROR_RETURN_VALUE) == 200);
@ -208,7 +208,7 @@ mod tests {
let env = Env::<WriteMap>::open(&path, EnvKind::RO).expect(ERROR_DB_CREATION); let env = Env::<WriteMap>::open(&path, EnvKind::RO).expect(ERROR_DB_CREATION);
// GET // GET
let result = env.view(|tx| tx.get(PlainState, key).expect(ERROR_GET)).expect(ERROR_GET); let result = env.view(|tx| tx.get::<PlainState>(key).expect(ERROR_GET)).expect(ERROR_GET);
assert!(result == Some(value)) assert!(result == Some(value))
} }

View File

@ -27,15 +27,14 @@ impl<T> Object for T where T: Encode + Decode {}
/// Generic trait that a database table should follow. /// Generic trait that a database table should follow.
pub trait Table: Send + Sync + Debug + 'static { pub trait Table: Send + Sync + Debug + 'static {
/// Return table name as it is present inside the MDBX.
const NAME: &'static str;
/// Key element of `Table`. /// Key element of `Table`.
type Key: Encode; type Key: Encode;
/// Value element of `Table`. /// Value element of `Table`.
type Value: Object; type Value: Object;
/// Seek Key element of `Table`. /// Seek Key element of `Table`.
type SeekKey: Encode; type SeekKey: Encode;
/// Return name as it is present inside the MDBX.
fn name(&self) -> &'static str;
} }
/// DupSort allows for keys not to be repeated in the database, /// DupSort allows for keys not to be repeated in the database,

View File

@ -33,14 +33,11 @@ macro_rules! table {
pub struct $name; pub struct $name;
impl $crate::kv::table::Table for $name { impl $crate::kv::table::Table for $name {
const NAME: &'static str = $name::const_name();
type Key = $key; type Key = $key;
type Value = $value; type Value = $value;
type SeekKey = $seek; type SeekKey = $seek;
/// Return $name as it is present inside the database.
fn name(&self) -> &'static str {
$name::const_name()
}
} }
impl $name { impl $name {

View File

@ -33,25 +33,23 @@ impl<'env, K: TransactionKind, E: EnvironmentKind> Tx<'env, K, E> {
} }
/// Open cursor on `table`. /// Open cursor on `table`.
pub fn cursor<'a, T: Table>(&'a self, table: T) -> Result<Cursor<'a, K, T>, KVError> pub fn cursor<'a, T: Table>(&'a self) -> Result<Cursor<'a, K, T>, KVError>
where where
'env: 'a, 'env: 'a,
T: Table, T: Table,
{ {
let table_name = table.name();
Ok(Cursor { Ok(Cursor {
inner: self.inner.cursor(&self.inner.open_db(Some(table_name))?)?, inner: self.inner.cursor(&self.inner.open_db(Some(T::NAME))?)?,
table: table_name, table: T::NAME,
_dbi: PhantomData, _dbi: PhantomData,
}) })
} }
/// Gets value associated with `key` on `table`. If it's a DUPSORT table, then returns the first /// Gets value associated with `key` on `table`. If it's a DUPSORT table, then returns the first
/// entry. /// entry.
pub fn get<T: Table>(&self, table: T, key: T::Key) -> ValueOnlyResult<T> { pub fn get<T: Table>(&self, key: T::Key) -> ValueOnlyResult<T> {
self.inner self.inner
.get(&self.inner.open_db(Some(table.name()))?, key.encode().as_ref())? .get(&self.inner.open_db(Some(T::NAME))?, key.encode().as_ref())?
.map(decode_one::<T>) .map(decode_one::<T>)
.transpose() .transpose()
} }
@ -65,23 +63,18 @@ impl<'env, K: TransactionKind, E: EnvironmentKind> Tx<'env, K, E> {
impl<'a, E: EnvironmentKind> Tx<'a, RW, E> { impl<'a, E: EnvironmentKind> Tx<'a, RW, E> {
/// Opens `table` and inserts `(key, value)` pair. If the `key` already exists, it replaces the /// Opens `table` and inserts `(key, value)` pair. If the `key` already exists, it replaces the
/// value it if the table doesn't support DUPSORT. /// value it if the table doesn't support DUPSORT.
pub fn put<T>(&self, table: T, k: T::Key, v: T::Value) -> Result<(), KVError> pub fn put<T>(&self, k: T::Key, v: T::Value) -> Result<(), KVError>
where where
T: Table, T: Table,
{ {
self.inner self.inner
.put( .put(&self.inner.open_db(Some(T::NAME))?, &k.encode(), &v.encode(), WriteFlags::UPSERT)
&self.inner.open_db(Some(table.name()))?,
&k.encode(),
&v.encode(),
WriteFlags::UPSERT,
)
.map_err(KVError::Put) .map_err(KVError::Put)
} }
/// Deletes the `(key, value)` entry on `table`. When `value` is `None`, all entries with `key` /// Deletes the `(key, value)` entry on `table`. When `value` is `None`, all entries with `key`
/// are to be deleted. Otherwise, only the item matching that data shall be. /// are to be deleted. Otherwise, only the item matching that data shall be.
pub fn delete<T>(&self, table: T, key: T::Key, value: Option<T::Value>) -> Result<bool, KVError> pub fn delete<T>(&self, key: T::Key, value: Option<T::Value>) -> Result<bool, KVError>
where where
T: Table, T: Table,
{ {
@ -93,16 +86,16 @@ impl<'a, E: EnvironmentKind> Tx<'a, RW, E> {
}; };
self.inner self.inner
.del(&self.inner.open_db(Some(table.name()))?, key.encode(), data) .del(&self.inner.open_db(Some(T::NAME))?, key.encode(), data)
.map_err(KVError::Delete) .map_err(KVError::Delete)
} }
/// Empties `table`. /// Empties `table`.
pub fn clear<T>(&self, table: T) -> Result<(), KVError> pub fn clear<T>(&self) -> Result<(), KVError>
where where
T: Table, T: Table,
{ {
self.inner.clear_db(&self.inner.open_db(Some(table.name()))?)?; self.inner.clear_db(&self.inner.open_db(Some(T::NAME))?)?;
Ok(()) Ok(())
} }