summaryrefslogblamecommitdiff
path: root/src/repo/mod.rs
blob: c7992c91444a2b8e89c2f66a0dbfde1cf21fc9fb (plain) (tree)
1
2
3
4
5
6
7
8




                             

                          
             


              




                                                          

   







                                                                           

                                                   
                                        





                                             
                                                  
                           
                                        

                         


































































                                                                    
use crate::error::TwinHError;
use crate::models::Car;
use crate::models::Part;
use bincode::deserialize;
use constants::*;
use once_cell::sync::Lazy;
use sled::{Config, Db};
use std::env;

mod constants;

pub static DB_PATH_INSTANCE: Lazy<String> = Lazy::new(|| {
    env::args()
        .skip(1)
        .last()
        .expect("database directory not provided")
});

static REPO_INSTANCE: Lazy<Db> =
    Lazy::new(
        || match Config::default().path(DB_PATH_INSTANCE.as_str()).open() {
            Err(e) => panic!("failed to open database: {}", e),
            Ok(db) => db,
        },
    );

pub fn create_demo_db() -> Result<(), TwinHError> {
    let db = sled::Config::default()
        .path(DB_PATH_INSTANCE.as_str())
        .create_new(true)
        .open()?;
    let cars_tree = db.open_tree(CARS_TREE)?;
    Ok(())
}

pub fn create_new_db() -> Result<(), TwinHError> {
    sled::Config::default()
        .path(DB_PATH_INSTANCE.as_str())
        .create_new(true)
        .open()?;
    Ok(())
}

pub fn get_all_cars() -> Result<Vec<Car>, TwinHError> {
    let cars = REPO_INSTANCE
        .open_tree(CARS_TREE)?
        .into_iter()
        .values()
        .collect::<Result<Vec<_>, _>>()?
        .iter()
        .map(|c| deserialize::<Car>(&c))
        .collect::<Result<Vec<_>, _>>()?;
    Ok(cars)
}

pub fn insert_part(part: Part) -> Result<u64, TwinHError> {
    todo!()
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::models::{Car, Part};
    use bincode::serialize;
    use std::error::Error;

    #[test]
    fn test_insert_part() -> Result<(), Box<dyn Error>> {
        let db = sled::Config::default()
            .mode(sled::Mode::HighThroughput)
            .temporary(true)
            .open()?;

        let car = Car {
            key: 1,
            make: "Hudson".into(),
            model: "Hornet".into(),
            trim: "Sedan".into(),
            doors: 4,
            year: 1953,
        };

        let tree = db.open_tree(CARS_TREE)?;
        let key = car.key.to_be_bytes();
        let val = serialize(&car)?;
        tree.insert(key, val)?;

        let part = Part {
            key: 2,
            number: "ABC123".into(),
            name: "Rear Wheel Bearing".into(),
            fits_cars: vec![car.key],
            categories: Vec::new(),
            sources: Vec::new(),
        };

        let tree = db.open_tree(PARTS_TREE)?;
        let (key, val) = (serialize(&part.key)?, serialize(&part)?);
        tree.insert(key.clone(), val)?;

        let part_out = tree.get(key)?;
        let part_out = deserialize::<Part>(&part_out.unwrap())?;
        assert_eq!(part.key, part_out.key);

        Ok(())
    }
}