pub trait ToKey: Debug {
// Required methods
fn to_key(&self) -> Key;
fn key_names() -> Vec<String>;
}Expand description
Allow to use a type as a key in the database.
In the below example, we define a struct City and implement the ToKey trait for it.
It can be use for primary or/and secondary key, and any other type that require City as a key.
§Example
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
struct City(String);
impl ToKey for City {
fn to_key(&self) -> Key {
Key::new(self.0.as_bytes().to_vec())
}
fn key_names() -> Vec<String> {
vec!["City".to_string()]
}
}
#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db]
struct Contry {
#[primary_key]
capital: City,
#[secondary_key(unique)]
bigest_city: City,
}
fn main() -> Result<(), db_type::Error> {
let mut models = Models::new();
models.define::<Contry>()?;
let db = Builder::new().create_in_memory(&models)?;
// Open a read transaction
let r = db.r_transaction()?;
// Get contry by the capital city (primary key)
let _us: Option<Contry> = r.get().primary(City("Washington, D.C.".to_string()))?;
// Get contry by the bigest city (secondary key)
let _us: Option<Contry> = r.get().secondary(ContryKey::bigest_city, City("New York".to_string()))?;
Ok(())
}§Example with Uuid
You can use uuid crate to generate a Uuid key.
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone, Hash)]
struct Uuid(uuid::Uuid);
impl ToKey for Uuid {
fn to_key(&self) -> Key {
Key::new(self.0.as_bytes().to_vec())
}
fn key_names() -> Vec<String> {
vec!["Uuid".to_string()]
}
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
#[primary_key]
uuid: Uuid,
}
fn main() -> Result<(), db_type::Error> {
let mut models = Models::new();
models.define::<Item>()?;
let db = Builder::new().create_in_memory(&models)?;
let rw = db.rw_transaction()?;
let item = Item { uuid: Uuid(uuid::Uuid::new_v4()) };
rw.insert(item.clone())?;
rw.commit()?;
let r = db.r_transaction()?;
let result_item: Item = r.get().primary(item.uuid.clone())?.unwrap();
assert_eq!(result_item.uuid, item.uuid);
Ok(())
}§Example with chrono
You can use chrono crate to generate a chrono::DateTime key.
use native_db::*;
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};
use itertools::Itertools;
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone, Hash)]
struct DateTime(chrono::DateTime<chrono::Utc>);
impl ToKey for DateTime {
fn to_key(&self) -> Key {
Key::new(self.0.timestamp_millis().to_be_bytes().to_vec())
}
fn key_names() -> Vec<String> {
vec!["DateTime".to_string()]
}
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
#[primary_key]
id: u32,
#[secondary_key]
created_at: DateTime,
}
fn main() -> Result<(), db_type::Error> {
let mut models = Models::new();
models.define::<Item>()?;
let db = Builder::new().create_in_memory(&models)?;
let rw = db.rw_transaction()?;
let item1 = Item { id: 2, created_at: DateTime(chrono::Utc::now()) };
rw.insert(item1.clone())?;
std::thread::sleep(std::time::Duration::from_millis(2));
let item2 = Item { id: 1, created_at: DateTime(chrono::Utc::now()) };
rw.insert(item2.clone())?;
rw.commit()?;
let r = db.r_transaction()?;
let result_items: Vec<Item> = r.scan().secondary(ItemKey::created_at)?.all()?.try_collect()?;
assert_eq!(result_items.len(), 2);
assert_eq!(result_items[0].id, 2);
assert_eq!(result_items[1].id, 1);
Ok(())
}
Required Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.