249 lines
7.7 KiB
Rust
249 lines
7.7 KiB
Rust
// File for database functions
|
|
use crate::structures::*;
|
|
|
|
use std::env;
|
|
use std::fs::{File, OpenOptions};
|
|
use std::io::prelude::*;
|
|
use std::path::PathBuf;
|
|
|
|
// Open the database
|
|
pub fn open_database(keyspace: &str) -> Option<sled::Tree> {
|
|
let db: sled::Db;
|
|
let key = "HOME";
|
|
let database_path = match env::var(key) {
|
|
Ok(val) => {
|
|
let mut tmp_path = PathBuf::new();
|
|
tmp_path.push(val);
|
|
tmp_path.push(".local/share/catgirl-pharmacy");
|
|
tmp_path.push("database");
|
|
tmp_path
|
|
}
|
|
Err(e) => {
|
|
panic!("failed to get key: {}", e);
|
|
}
|
|
};
|
|
|
|
match sled::open(database_path) {
|
|
Ok(database) => db = database,
|
|
Err(error) => {
|
|
println!("error in opening database: {}", error);
|
|
return None;
|
|
}
|
|
}
|
|
|
|
let database: Option<sled::Tree> = match db.open_tree(keyspace) {
|
|
Ok(tree) => Some(tree),
|
|
Err(e) => {
|
|
println!("error in opening Tree: {}", e);
|
|
None
|
|
}
|
|
};
|
|
return database;
|
|
}
|
|
|
|
// Register a new product
|
|
pub fn register_product(short_name: &str, product: &Product) -> Result<String, sled::Error> {
|
|
let db = match open_database("products") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
info!("Registering new product {:?}", &product);
|
|
let bytes = bincode::serialize(&product).unwrap(); //Serialize the data
|
|
|
|
match db.insert(short_name, bytes) {
|
|
// Insert the product using the short name as a key
|
|
Ok(_) => info!("inserted product"),
|
|
Err(error) => return Err(error),
|
|
}
|
|
|
|
match db.flush() {
|
|
Ok(_) => info!("flushed database"),
|
|
Err(error) => return Err(error),
|
|
}
|
|
|
|
return Ok("succesfully registered product".to_string());
|
|
}
|
|
|
|
// Read info about a product
|
|
pub fn read_product(short_name: &str) -> Result<Product, sled::Error> {
|
|
let db = match open_database("products") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
info!("Reading product from shortcode {}", short_name);
|
|
let entry = match db.get(short_name) {
|
|
Ok(entry) => entry,
|
|
Err(error) => return Err(error),
|
|
}; // Get a product entry out of the database using the short name
|
|
|
|
if let Some(product_entry) = entry {
|
|
let read_product = match bincode::deserialize(&product_entry) {
|
|
Ok(product) => product,
|
|
Err(error) => panic!("could not deserialize product: {:?}", error),
|
|
};
|
|
return Ok(read_product);
|
|
} else {
|
|
warn!("product not found");
|
|
return Err(sled::Error::Unsupported(
|
|
sled::Error::ReportableBug("product not found".to_string()).to_string(),
|
|
));
|
|
};
|
|
}
|
|
|
|
// Read all products pushed to the database
|
|
pub fn read_all_products() -> Result<Vec<Product>, sled::Error> {
|
|
let db = match open_database("products") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
info!("Reading all products from database");
|
|
|
|
let first_key = match db.first() {
|
|
Ok(key) => match key {
|
|
Some(v) => v.0,
|
|
None => {
|
|
return Err(sled::Error::Unsupported(
|
|
sled::Error::ReportableBug("product not found".to_string()).to_string(),
|
|
));
|
|
}
|
|
},
|
|
Err(error) => return Err(error),
|
|
}; // Get the first key from the database
|
|
|
|
let iter = db.range(first_key..); // Create an iterator of all keys from the first one
|
|
let mut all_products: Vec<Product> = Vec::new(); // Create a new vector to store the orders
|
|
|
|
for product in iter {
|
|
// Iterate over the orders
|
|
if let product_entry = product.unwrap().1 {
|
|
// If we can unwrap it:
|
|
let read_product: Product = match bincode::deserialize(&product_entry) {
|
|
Ok(product) => product,
|
|
Err(error) => panic!("could not deserialize product: {:?}", error),
|
|
}; // Deserialize the entry
|
|
all_products.push(read_product); // Add the entry to the vector
|
|
} else {
|
|
// Fail
|
|
warn!("Could not find any more products");
|
|
db.flush().unwrap();
|
|
}
|
|
}
|
|
return Ok(all_products); // Return the orders
|
|
}
|
|
|
|
// Create a new order
|
|
pub fn make_order(order: &Order) -> Result<String, sled::Error> {
|
|
info!(
|
|
"Creating new order with Uuid {}",
|
|
&order.uuid.to_hyphenated().to_string()
|
|
);
|
|
|
|
let db = match open_database("orders") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
let bytes = match bincode::serialize(&order) {
|
|
// Serialize the new order
|
|
Ok(bytes) => bytes,
|
|
Err(error) => panic!("could not serialize order: {:?}", error),
|
|
};
|
|
|
|
match db.insert(order.uuid.to_hyphenated().to_string(), bytes) {
|
|
// Insert using the UUID as key
|
|
Ok(_) => info!("succesfully inserted order"),
|
|
Err(error) => return Err(error),
|
|
}
|
|
|
|
match db.flush() {
|
|
Ok(_) => info!("flushed database"),
|
|
Err(error) => return Err(error),
|
|
}
|
|
return Ok("succesfully made new order".to_string());
|
|
}
|
|
|
|
// Read an order from UUID
|
|
pub fn read_order(uuid: &str) -> Result<Order, sled::Error> {
|
|
let db = match open_database("orders") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
info!("Reading order with Uuid {}", uuid);
|
|
|
|
let entry = match db.get(uuid) {
|
|
// Read an entry using UUID as a key
|
|
Ok(order) => order,
|
|
Err(error) => return Err(error),
|
|
};
|
|
|
|
if let Some(order_entry) = entry {
|
|
let read_order: Order = match bincode::deserialize(&order_entry) {
|
|
// If succesful, deserialize & return
|
|
Ok(order) => order,
|
|
Err(error) => panic!("could not deserialize order: {:?}", error),
|
|
};
|
|
info!("Succesfully deserialized order");
|
|
db.flush().unwrap();
|
|
return Ok(read_order);
|
|
} else {
|
|
// Fail
|
|
warn!("Failed on reading order from database with Uuid {}", uuid);
|
|
db.flush().unwrap();
|
|
return Err(sled::Error::ReportableBug("order not found".to_string()));
|
|
};
|
|
}
|
|
|
|
// Read all orders pushed to the database
|
|
pub fn read_all_orders() -> Result<Vec<Order>, sled::Error> {
|
|
let db = match open_database("orders") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
info!("Reading all orders from database");
|
|
|
|
let first_key = match db.first() {
|
|
Ok(key) => key.unwrap().0,
|
|
Err(error) => return Err(error),
|
|
}; // Get the first key from the database
|
|
|
|
let iter = db.range(first_key..); // Create an iterator of all keys from the first one
|
|
let mut all_orders: Vec<Order> = Vec::new(); // Create a new vector to store the orders
|
|
|
|
for order in iter {
|
|
// Iterate over the orders
|
|
if let order_entry = order.unwrap().1 {
|
|
// If we can unwrap it:
|
|
let read_order: Order = match bincode::deserialize(&order_entry) {
|
|
Ok(order) => order,
|
|
Err(error) => panic!("could not deserialize order: {:?}", error),
|
|
}; // Deserialize the entry
|
|
all_orders.push(read_order); // Add the entry to the vector
|
|
} else {
|
|
// Fail
|
|
warn!("Could not find any more orders");
|
|
db.flush().unwrap();
|
|
}
|
|
}
|
|
return Ok(all_orders); // Return the orders
|
|
}
|
|
|
|
// Remove an order from the database
|
|
pub fn remove_order(uuid: &str) -> Result<String, sled::Error> {
|
|
info!("Removing order with Uuid {}", uuid);
|
|
|
|
let db = match open_database("orders") {
|
|
Some(database) => database,
|
|
None => panic!(),
|
|
};
|
|
|
|
match db.remove(uuid) {
|
|
Ok(_) => Ok("removed order".to_string()),
|
|
Err(error) => return Err(error),
|
|
}
|
|
}
|