Does native_db support nested structures? #207
-
in this example code: use serde::{Deserialize, Serialize};
use native_db::*;
use native_model::{native_model, Model};
use once_cell::sync::Lazy;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
#[primary_key]
id: u32,
#[secondary_key]
name: Name,
}
struct Name {
first: String,
last: String,
}
// Define the models
// The lifetime of the models needs to be longer or equal to the lifetime of the database.
// In many cases, it is simpler to use a static variable but it is not mandatory.
static MODELS: Lazy<Models> = Lazy::new(|| {
let mut models = Models::new();
models.define::<Item>().unwrap();
models
});
fn main() -> Result<(), db_type::Error> {
// Create a database in memory
let mut db = Builder::new().create_in_memory(&MODELS)?;
// Insert data (open a read-write transaction)
let rw = db.rw_transaction().unwrap();
rw.insert(Item { id: 1, name: Name{first: "John".to_string(), last: "Doe".to_string()})?;
rw.commit()?;
// Open a read-only transaction
let r = db.r_transaction()?;
// Retrieve data with id=3
let retrieve_data: Item = r.get().primary(1_u32)?.unwrap();
println!("data id='3': {:?}", retrieve_data);
for item in r.scan().secondary::<Item>(ItemKey::name)?.start_with("John") {
println!("data name=\"red\": {:?}", item);
}
// Remove data (open a read-write transaction)
let rw = db.rw_transaction()?;
rw.remove(retrieve_data)?;
rw.commit()?;
Ok(())
} In this example code not too sure if its possible to query just the first name using a nested structure if so may I be provided with an example on how I would achieve this? |
Beta Was this translation helpful? Give feedback.
Answered by
vincent-herlemont
Aug 3, 2024
Replies: 1 comment
-
Here is an example using ToKey (read the documentation carefully). use native_db::*;
use native_model::{native_model, Model};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_db]
struct Item {
#[primary_key]
id: u32,
#[secondary_key]
name: Name,
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
struct Name {
first: String,
last: String,
}
impl ToKey for &Name {
fn to_key(&self) -> Key {
// Concatenate the first and last name
let mut key = self.first.clone();
key.push_str(&self.last);
Key::new(key.as_bytes().to_vec())
}
}
// Define the models
// The lifetime of the models needs to be longer or equal to the lifetime of the database.
// In many cases, it is simpler to use a static variable but it is not mandatory.
static MODELS: Lazy<Models> = Lazy::new(|| {
let mut models = Models::new();
models.define::<Item>().unwrap();
models
});
fn main() -> Result<(), db_type::Error> {
// Create a database in memory
let db = Builder::new().create_in_memory(&MODELS)?;
// Insert data (open a read-write transaction)
let rw: transaction::RwTransaction = db.rw_transaction().unwrap();
rw.insert(Item { id: 1, name: Name{first: "John".to_string(), last: "Doe".to_string()}})?;
rw.commit()?;
// Open a read-only transaction
let r = db.r_transaction()?;
// Retrieve data with id=3
let retrieve_data: Item = r.get().primary(1_u32)?.unwrap();
println!("data id='3': {:?}", retrieve_data);
for item in r.scan().secondary::<Item>(ItemKey::name)?.start_with("John") {
println!("data name=\"red\": {:?}", item);
}
// Remove data (open a read-write transaction)
let rw = db.rw_transaction()?;
rw.remove(retrieve_data)?;
rw.commit()?;
Ok(())
} Here is an example using custom keys. Read this documentation carefully Models.define. use native_db::*;
use native_model::{native_model, Model};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_db(secondary_key(name))]
struct Item {
#[primary_key]
id: u32,
name: Name,
}
impl Item {
pub fn name(&self) -> String {
format!("{} {}", self.name.first, self.name.last)
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Name {
first: String,
last: String,
}
// Define the models
// The lifetime of the models needs to be longer or equal to the lifetime of the database.
// In many cases, it is simpler to use a static variable but it is not mandatory.
static MODELS: Lazy<Models> = Lazy::new(|| {
let mut models = Models::new();
models.define::<Item>().unwrap();
models
});
fn main() -> Result<(), db_type::Error> {
// Create a database in memory
let db = Builder::new().create_in_memory(&MODELS)?;
// Insert data (open a read-write transaction)
let rw: transaction::RwTransaction = db.rw_transaction().unwrap();
rw.insert(Item { id: 1, name: Name{first: "John".to_string(), last: "Doe".to_string()}})?;
rw.commit()?;
// Open a read-only transaction
let r = db.r_transaction()?;
// Retrieve data with id=3
let retrieve_data: Item = r.get().primary(1_u32)?.unwrap();
println!("data id='3': {:?}", retrieve_data);
for item in r.scan().secondary::<Item>(ItemKey::name)?.start_with("John") {
println!("data name=\"red\": {:?}", item);
}
// Remove data (open a read-write transaction)
let rw = db.rw_transaction()?;
rw.remove(retrieve_data)?;
rw.commit()?;
Ok(())
} @Raj2032 If there are any problems with the explanations, feel free to let me know and make a merge request; I would be delighted. |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
Raj2032
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is an example using ToKey (read the documentation carefully).