Add cache option to from_db_model functions

This commit is contained in:
Tobias Reisinger 2023-11-29 17:13:15 +01:00
parent 5e738501dd
commit 5b54f40ec0
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
3 changed files with 74 additions and 42 deletions

View file

@ -218,23 +218,6 @@ paths:
operationId: get-controllers operationId: get-controllers
description: Return all controllers. description: Return all controllers.
parameters: [ ] parameters: [ ]
/api/v1/controllers/discover:
put:
summary: discover controllers
tags:
- controllers
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/controller'
operationId: put-controllers-discover
description: Start a discovery process to find controllers in the network. This operations needs multiple seconds to complete.
parameters: [ ]
'/api/v1/controllers/{controller_id}': '/api/v1/controllers/{controller_id}':
parameters: parameters:
- schema: - schema:

View file

@ -22,7 +22,6 @@ pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, ApiErr
let mut pool_conn = pool.acquire().await?; let mut pool_conn = pool.acquire().await?;
let db_schedules = DbSchedule::get_all(&mut pool_conn).await?; let db_schedules = DbSchedule::get_all(&mut pool_conn).await?;
let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?; let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?;
Ok(HttpResponse::Ok().json(schedules)) Ok(HttpResponse::Ok().json(schedules))
@ -41,7 +40,6 @@ pub async fn tagged(
.ok_or(DatabaseError::NotFound)?; .ok_or(DatabaseError::NotFound)?;
let db_schedules = DbSchedule::get_by_tag(&mut pool_conn, &tag_db).await?; let db_schedules = DbSchedule::get_by_tag(&mut pool_conn, &tag_db).await?;
let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?; let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?;
Ok(HttpResponse::Ok().json(schedules)) Ok(HttpResponse::Ok().json(schedules))

View file

@ -9,6 +9,7 @@ use crate::types::ControllerUid;
pub trait FromDbModel { pub trait FromDbModel {
type DbModel: Clone; type DbModel: Clone;
type DbModelCache: Clone;
fn from_db_model( fn from_db_model(
conn: &mut PoolConnection<Sqlite>, conn: &mut PoolConnection<Sqlite>,
@ -16,6 +17,14 @@ pub trait FromDbModel {
) -> Result<Self, DatabaseError> ) -> Result<Self, DatabaseError>
where where
Self: Sized; Self: Sized;
fn from_db_model_cache(
conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel,
cache: Self::DbModelCache,
) -> Result<Self, DatabaseError>
where
Self: Sized;
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
@ -43,33 +52,53 @@ pub struct Controller {
impl FromDbModel for Schedule { impl FromDbModel for Schedule {
type DbModel = DbSchedule; type DbModel = DbSchedule;
type DbModelCache = Vec<String>;
fn from_db_model( fn from_db_model(
conn: &mut PoolConnection<Sqlite>, conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel, db_model: Self::DbModel,
) -> Result<Self, DatabaseError> { ) -> Result<Self, DatabaseError> {
let schedule = db_model.clone(); let cache = executor::block_on(db_model.get_tags(conn))?;
let tags = executor::block_on(schedule.get_tags(conn))?; Self::from_db_model_cache(conn, db_model, cache)
}
Ok(Schedule { s: schedule, tags }) fn from_db_model_cache(
_conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel,
cache: Self::DbModelCache,
) -> Result<Self, DatabaseError> {
let schedule = db_model.clone();
Ok(Schedule {
s: schedule,
tags: cache,
})
} }
} }
impl FromDbModel for Relay { impl FromDbModel for Relay {
type DbModel = DbRelay; type DbModel = DbRelay;
type DbModelCache = DbController;
fn from_db_model( fn from_db_model(
conn: &mut PoolConnection<Sqlite>, conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel, db_model: Self::DbModel,
) -> Result<Self, DatabaseError> { ) -> Result<Self, DatabaseError> {
let relay = db_model.clone(); let cache = executor::block_on(db_model.get_controller(conn))?;
let controller = executor::block_on(relay.get_controller(conn))?; Self::from_db_model_cache(conn, db_model, cache)
let controller_id = controller.uid.clone(); }
let tags = executor::block_on(relay.get_tags(conn))?;
fn from_db_model_cache(
conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel,
cache: Self::DbModelCache,
) -> Result<Self, DatabaseError> {
let tags = executor::block_on(db_model.get_tags(conn))?;
let controller_id = cache.uid.clone();
Ok(Relay { Ok(Relay {
r: relay, r: db_model,
controller, controller: cache,
controller_id, controller_id,
tags, tags,
}) })
@ -78,34 +107,56 @@ impl FromDbModel for Relay {
impl FromDbModel for Controller { impl FromDbModel for Controller {
type DbModel = DbController; type DbModel = DbController;
type DbModelCache = Vec<Relay>;
fn from_db_model( fn from_db_model(
conn: &mut PoolConnection<Sqlite>, conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel, db_model: Self::DbModel,
) -> Result<Self, DatabaseError> { ) -> Result<Self, DatabaseError> {
let relays_db = executor::block_on(db_model.get_relays(conn))?; let relays_db = executor::block_on(db_model.get_relays(conn))?;
let relays = convert_db_list(conn, relays_db)?; let cache = convert_db_list_cache(conn, relays_db, db_model.clone())?;
Self::from_db_model_cache(conn, db_model, cache)
}
fn from_db_model_cache(
_conn: &mut PoolConnection<Sqlite>,
db_model: Self::DbModel,
cache: Self::DbModelCache,
) -> Result<Self, DatabaseError> {
Ok(Controller { Ok(Controller {
c: db_model, c: db_model,
relays, relays: cache,
}) })
} }
} }
fn convert_db_list_generic<T: FromDbModel>(
conn: &mut PoolConnection<Sqlite>,
db_models: Vec<T::DbModel>,
cache: Option<T::DbModelCache>,
) -> Result<Vec<T>, DatabaseError> {
let mut result: Vec<T> = Vec::new();
for db_model in db_models {
let new = match &cache {
Some(c) => T::from_db_model_cache(conn, db_model, c.clone()),
None => T::from_db_model(conn, db_model),
}?;
result.push(new);
}
Ok(result)
}
pub fn convert_db_list<T: FromDbModel>( pub fn convert_db_list<T: FromDbModel>(
conn: &mut PoolConnection<Sqlite>, conn: &mut PoolConnection<Sqlite>,
db_models: Vec<T::DbModel>, db_models: Vec<T::DbModel>,
) -> Result<Vec<T>, DatabaseError> { ) -> Result<Vec<T>, DatabaseError> {
let mut result: Vec<T> = Vec::new(); convert_db_list_generic(conn, db_models, None)
db_models.into_iter().try_for_each(|s| { }
let new = T::from_db_model(conn, s);
match new { pub fn convert_db_list_cache<T: FromDbModel>(
Ok(new) => { conn: &mut PoolConnection<Sqlite>,
result.push(new); db_models: Vec<T::DbModel>,
Ok(()) cache: T::DbModelCache,
} ) -> Result<Vec<T>, DatabaseError> {
Err(e) => Err(e), convert_db_list_generic(conn, db_models, Some(cache))
}
})?;
Ok(result)
} }