diff --git a/scraper/src/refresh.rs b/scraper/src/refresh.rs index 322ee53..dacb243 100644 --- a/scraper/src/refresh.rs +++ b/scraper/src/refresh.rs @@ -119,7 +119,9 @@ pub async fn check_refresh(db: &sqlx::PgPool, date: NaiveDate, canteens: &[Cante .difference(&db_dishes) .collect::>(); - if let Err(err) = update_stale_dishes(db, date, &stale_dishes, &new_dishes).await { + if let Err(err) = + update_stale_dishes(db, date, &stale_dishes, &new_dishes, canteens).await + { tracing::error!("Error updating stale dishes in db: {}", err); false } else { @@ -151,32 +153,43 @@ async fn update_stale_dishes( date: NaiveDate, stale_dishes: &HashSet<&(Canteen, Dish)>, new_dishes: &HashSet<&(Canteen, Dish)>, + canteens: &[Canteen], ) -> Result<(), sqlx::Error> { let mut tx = db.begin().await?; - QueryBuilder::new("UPDATE meals SET is_latest = FALSE WHERE date = ") - .push_bind(date) - .push(r#" AND ("name", canteen) IN "#) - .push_tuples(stale_dishes, |mut sep, (canteen, dish)| { - sep.push_bind(&dish.name) - .push_bind(canteen.get_identifier()); - }) - .push(";") - .build() - .execute(&mut *tx) - .await?; + if !stale_dishes.is_empty() { + QueryBuilder::new("UPDATE meals SET is_latest = FALSE WHERE date = ") + .push_bind(date) + .push(r#" AND ("name", canteen) IN "#) + .push_tuples(stale_dishes, |mut sep, (canteen, dish)| { + sep.push_bind(&dish.name) + .push_bind(canteen.get_identifier()); + }) + .push(";") + .build() + .execute(&mut *tx) + .await?; + } let chunks = new_dishes .iter() .sorted_by_key(|(c, _)| c) .chunk_by(|(c, _)| c); - let new_dishes_iter = chunks.into_iter().map(|(canteen, g)| { - ( - *canteen, - g.map(|(_, dish)| dish).cloned().collect::>(), - ) - }); + let new_dishes_iter = chunks + .into_iter() + .map(|(canteen, g)| { + ( + *canteen, + g.map(|(_, dish)| dish).cloned().collect::>(), + ) + }) + .chain( + canteens + .iter() + .map(|canteen| (*canteen, Vec::new())) + .unique_by(|(c, _)| *c), + ); for (canteen, menu) in new_dishes_iter { add_menu_to_db(&mut tx, &date, canteen, menu).await?; diff --git a/scraper/src/util.rs b/scraper/src/util.rs index 19f3076..b6886b7 100644 --- a/scraper/src/util.rs +++ b/scraper/src/util.rs @@ -85,35 +85,33 @@ pub async fn add_menu_to_db( canteen: Canteen, menu: Vec, ) -> Result<(), sqlx::Error> { - if menu.is_empty() { - return Ok(()); + if !menu.is_empty() { + let mut query = sqlx::QueryBuilder::new("INSERT INTO meals (date,canteen,name,dish_type,image_src,price_students,price_employees,price_guests,vegan,vegetarian,kjoules,proteins,carbohydrates,fats) "); + + query + .push_values(menu, |mut sep, item| { + let vegan = item.is_vegan(); + + sep.push_bind(date) + .push_bind(canteen.get_identifier()) + .push_bind(item.get_name().to_string()) + .push_bind(item.get_type() as DishType) + .push_bind(item.get_image_src().map(str::to_string)) + .push_bind(item.get_price_students().to_owned()) + .push_bind(item.get_price_employees().to_owned()) + .push_bind(item.get_price_guests().to_owned()) + .push_bind(vegan) + .push_bind(vegan || item.is_vegetarian()) + .push_bind(item.nutrition_values.kjoule) + .push_bind(item.nutrition_values.protein.to_owned()) + .push_bind(item.nutrition_values.carbs.to_owned()) + .push_bind(item.nutrition_values.fat.to_owned()); + }) + .build() + .execute(&mut **db) + .await?; } - let mut query = sqlx::QueryBuilder::new("INSERT INTO meals (date,canteen,name,dish_type,image_src,price_students,price_employees,price_guests,vegan,vegetarian,kjoules,proteins,carbohydrates,fats) "); - - query - .push_values(menu, |mut sep, item| { - let vegan = item.is_vegan(); - - sep.push_bind(date) - .push_bind(canteen.get_identifier()) - .push_bind(item.get_name().to_string()) - .push_bind(item.get_type() as DishType) - .push_bind(item.get_image_src().map(str::to_string)) - .push_bind(item.get_price_students().to_owned()) - .push_bind(item.get_price_employees().to_owned()) - .push_bind(item.get_price_guests().to_owned()) - .push_bind(vegan) - .push_bind(vegan || item.is_vegetarian()) - .push_bind(item.nutrition_values.kjoule) - .push_bind(item.nutrition_values.protein.to_owned()) - .push_bind(item.nutrition_values.carbs.to_owned()) - .push_bind(item.nutrition_values.fat.to_owned()); - }) - .build() - .execute(&mut **db) - .await?; - sqlx::query!( "INSERT INTO canteens_scraped (scraped_for, canteen) VALUES ($1, $2)", date,