doc: update readme with actual example code
This commit is contained in:
119
README.md
119
README.md
@@ -31,88 +31,83 @@ Learn more on EAV data model [here](https://en.wikipedia.org/wiki/Entity%E2%80%9
|
|||||||
Here is an example of how to define a typed entity, persist it to a SQLite database, and load it back.
|
Here is an example of how to define a typed entity, persist it to a SQLite database, and load it back.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use heave::{Catalog, EAV, Entity};
|
use heave::*;
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
// Define a typed entity.
|
// Define a struct named `Product` to represent a product.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
struct Product {
|
struct Product {
|
||||||
id: String,
|
// `id` is a public field of type `String` to uniquely identify the product.
|
||||||
name: String,
|
pub id: String,
|
||||||
model: Option<String>,
|
// `name` is a public field of type `String` for the product's name.
|
||||||
price: u64,
|
pub name: String,
|
||||||
in_stock: bool,
|
// `model` is a public optional field of type `String` for the product's model.
|
||||||
|
pub model: Option<String>,
|
||||||
|
// `price` is a public field of type `i64` for the product's price.
|
||||||
|
pub price: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the EAV trait to define the class of the entity.
|
// Implement the `EAV` trait for the `Product` struct.
|
||||||
impl EAV for Product {
|
impl EAV for Product {
|
||||||
|
// `class` is a function that returns the class name of the entity.
|
||||||
fn class() -> &'static str {
|
fn class() -> &'static str {
|
||||||
"product"
|
"product"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement From<Entity> to map a schemaless entity to a typed one.
|
// Implement the `From<Product>` trait for the `Entity` struct.
|
||||||
impl From<Entity> for Product {
|
impl From<Product> for Entity {
|
||||||
fn from(entity: Entity) -> Self {
|
// `from` is a function that converts a `Product` into an `Entity`.
|
||||||
Product {
|
fn from(value: Product) -> Entity {
|
||||||
id: entity.id.clone(),
|
// Create a new `Entity` for the `Product` class.
|
||||||
name: entity.unwrap("name"),
|
Entity::new::<Product>()
|
||||||
model: entity.unwrap_opt("model"),
|
// Set the entity's ID from the product's ID.
|
||||||
price: entity.unwrap_or("price", 0),
|
.with_id(&value.id)
|
||||||
in_stock: entity.unwrap("in_stock"),
|
// Add the "name" attribute with the product's name.
|
||||||
}
|
.with_attribute("name", value.name)
|
||||||
|
// Add the optional "model" attribute with the product's model.
|
||||||
|
.with_opt_attribute("model", value.model)
|
||||||
|
// Add the "price" attribute with the product's price.
|
||||||
|
.with_attribute("price", value.price)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement From<Product> to map a typed entity to a schemaless one.
|
// Implement the `From<Entity>` trait for the `Product` struct.
|
||||||
impl From<Product> for Entity {
|
impl From<Entity> for Product {
|
||||||
fn from(value: Product) -> Self {
|
// `from` is a function that converts an `Entity` into a `Product`.
|
||||||
let mut entity = Entity::new::<Product>()
|
fn from(value: Entity) -> Self {
|
||||||
.with_id(&value.id)
|
// Create a new `Product` from the entity's attributes.
|
||||||
.with_attribute("name", value.name)
|
Self {
|
||||||
.with_attribute("price", value.price)
|
// Set the product's ID from the entity's ID.
|
||||||
.with_attribute("in_stock", value.in_stock);
|
id: value.id.clone(),
|
||||||
if let Some(model) = value.model {
|
// Unwrap the "name" attribute to get the product's name.
|
||||||
entity.set("model", model);
|
name: value.unwrap("name"),
|
||||||
|
// Unwrap the optional "model" attribute to get the product's model.
|
||||||
|
model: value.unwrap_opt("model"),
|
||||||
|
// Unwrap the "price" attribute to get the product's price.
|
||||||
|
price: value.unwrap("price"),
|
||||||
}
|
}
|
||||||
entity
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let db_path = "example.db";
|
// Define the path for the SQLite database file.
|
||||||
|
let db_path = "./simple_product.sqlite3";
|
||||||
// Initialize a new catalog and database.
|
// Create a new `Catalog` instance with the specified database path.
|
||||||
let mut catalog = Catalog::new(db_path);
|
let mut catalog = Catalog::new(db_path);
|
||||||
catalog.init();
|
// Initialize the catalog, which sets up the database.
|
||||||
|
catalog.init().unwrap();
|
||||||
// Create a new typed object.
|
// Create a new `Product` instance representing a laptop.
|
||||||
let product = Product {
|
let new_laptop = Product {
|
||||||
id: "prod-123".to_string(),
|
id: "LT001".to_string(),
|
||||||
name: String::from("PenguinX Laptop"),
|
name: "SuperPenguin".to_string(),
|
||||||
model: None,
|
model: Some("Mark III.2".to_string()),
|
||||||
price: 135000,
|
price: 125000,
|
||||||
in_stock: true,
|
|
||||||
};
|
};
|
||||||
let product_id = product.id.clone();
|
// Insert the new laptop into the catalog. Note that at this time the product is in memory.
|
||||||
|
catalog.insert(new_laptop);
|
||||||
// Insert the object and persist it to the database.
|
// Persist the changes in the catalog to the database.
|
||||||
catalog.insert(product);
|
catalog.persist().unwrap();
|
||||||
catalog.persist();
|
// Remove the SQLite database file.
|
||||||
|
std::fs::remove_file(db_path).unwrap();
|
||||||
// Create a new catalog to simulate a different application instance.
|
|
||||||
let mut new_catalog = Catalog::new(db_path);
|
|
||||||
|
|
||||||
// Load the entity from the database.
|
|
||||||
new_catalog.load_by_id(&product_id);
|
|
||||||
|
|
||||||
// Retrieve the typed object from the catalog.
|
|
||||||
let read_product = new_catalog.get::<Product>(&product_id).unwrap();
|
|
||||||
|
|
||||||
println!("Successfully persisted and loaded: {:?}", read_product);
|
|
||||||
|
|
||||||
// Clean up the database file.
|
|
||||||
fs::remove_file(db_path).unwrap();
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user