Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

editoast: add cli commands to list / delete electrical profile sets #5167

Merged
merged 1 commit into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion editoast/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,25 @@ pub enum Commands {
Generate(GenerateArgs),
Clear(ClearArgs),
ImportRailjson(ImportRailjsonArgs),
ImportProfileSet(ImportProfileSetArgs),
#[command(
subcommand,
about,
long_about = "Commands related to electrical profile sets"
)]
ElectricalProfiles(ElectricalProfilesCommands),
ImportRollingStock(ImportRollingStockArgs),
OsmToRailjson(OsmToRailjsonArgs),
#[command(about, long_about = "Prints the OpenApi of the service")]
Openapi,
}

#[derive(Subcommand, Debug)]
pub enum ElectricalProfilesCommands {
Import(ImportProfileSetArgs),
Delete(DeleteProfileSetArgs),
List(ListProfileSetArgs),
}

#[derive(Args, Debug, Derivative, Clone)]
#[derivative(Default)]
pub struct MapLayersConfig {
Expand Down Expand Up @@ -118,6 +130,27 @@ pub struct ImportProfileSetArgs {
pub electrical_profile_set_path: PathBuf,
}

#[derive(Args, Debug)]
#[command(
about,
long_about = "Delete electrical profile sets corresponding to the given ids"
)]
pub struct DeleteProfileSetArgs {
/// List of infra ids
pub profile_set_ids: Vec<i64>,
}

#[derive(Args, Debug)]
#[command(
about,
long_about = "List electrical profile sets in the database, <id> - <name>"
)]
pub struct ListProfileSetArgs {
// Wether to display the list in a ready to parse format
#[arg(long, default_value_t = false)]
pub quiet: bool,
}

#[derive(Args, Debug)]
#[command(about, long_about = "Import a rolling stock given a json file")]
pub struct ImportRollingStockArgs {
Expand Down
110 changes: 99 additions & 11 deletions editoast/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod views;
use crate::core::CoreClient;
use crate::error::InternalError;
use crate::map::redis_utils::RedisClient;
use crate::models::{Create, Infra};
use crate::models::{Create, Delete, Infra};
use crate::schema::electrical_profiles::ElectricalProfileSetData;
use crate::schema::RailJson;
use crate::views::infra::InfraForm;
Expand All @@ -30,8 +30,9 @@ use actix_web::{App, HttpServer};
use chashmap::CHashMap;
use clap::Parser;
use client::{
ClearArgs, Client, Color, Commands, GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs,
ImportRollingStockArgs, PostgresConfig, RedisConfig, RunserverArgs,
ClearArgs, Client, Color, Commands, DeleteProfileSetArgs, ElectricalProfilesCommands,
GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs, ImportRollingStockArgs,
ListProfileSetArgs, PostgresConfig, RedisConfig, RunserverArgs,
};
use colored::*;
use diesel::{ConnectionError, ConnectionResult};
Expand Down Expand Up @@ -88,7 +89,6 @@ async fn run() -> Result<(), Box<dyn Error + Send + Sync>> {
Commands::Generate(args) => generate(args, pg_config, redis_config).await,
Commands::Clear(args) => clear(args, pg_config, redis_config).await,
Commands::ImportRailjson(args) => import_railjson(args, pg_config).await,
Commands::ImportProfileSet(args) => add_electrical_profile_set(args, pg_config).await,
Commands::ImportRollingStock(args) => import_rolling_stock(args, pg_config).await,
Commands::OsmToRailjson(args) => {
converters::osm_to_railjson(args.osm_pbf_in, args.railjson_out)
Expand All @@ -97,6 +97,17 @@ async fn run() -> Result<(), Box<dyn Error + Send + Sync>> {
generate_openapi();
Ok(())
}
Commands::ElectricalProfiles(subcommand) => match subcommand {
ElectricalProfilesCommands::Import(args) => {
electrical_profile_set_import(args, pg_config).await
}
ElectricalProfilesCommands::List(args) => {
electrical_profile_set_list(args, pg_config).await
}
ElectricalProfilesCommands::Delete(args) => {
electrical_profile_set_delete(args, pg_config).await
}
},
}
}

Expand Down Expand Up @@ -389,7 +400,7 @@ async fn import_railjson(
Ok(())
}

async fn add_electrical_profile_set(
async fn electrical_profile_set_import(
args: ImportProfileSetArgs,
pg_config: PostgresConfig,
) -> Result<(), Box<dyn Error + Send + Sync>> {
Expand All @@ -411,6 +422,44 @@ async fn add_electrical_profile_set(
Ok(())
}

async fn electrical_profile_set_list(
args: ListProfileSetArgs,
pg_config: PostgresConfig,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let mut conn = PgConnection::establish(&pg_config.url()).await?;
let electrical_profile_sets = ElectricalProfileSet::list_light(&mut conn).await.unwrap();
if !args.quiet {
println!("Electrical profile sets:\nID - Name");
}
for electrical_profile_set in electrical_profile_sets {
println!(
"{:<2} - {}",
electrical_profile_set.id.unwrap(),
electrical_profile_set.name.unwrap()
);
}
Ok(())
}

async fn electrical_profile_set_delete(
args: DeleteProfileSetArgs,
pg_config: PostgresConfig,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let manager = ConnectionManager::<PgConnection>::new(pg_config.url());
let pool = Data::new(Pool::builder(manager).max_size(1).build().unwrap());
for profile_set_id in args.profile_set_ids {
let deleted = ElectricalProfileSet::delete(pool.clone(), profile_set_id)
.await
.unwrap();
if !deleted {
println!("Electrical profile set {} not found", profile_set_id);
} else {
println!("Electrical profile set {} deleted", profile_set_id);
}
}
Ok(())
}

/// Run the clear subcommand
/// This command clear all generated data for the given infra
async fn clear(
Expand Down Expand Up @@ -475,18 +524,16 @@ fn generate_openapi() {

#[cfg(test)]
mod tests {
use crate::client::{ImportRailjsonArgs, PostgresConfig};
use super::*;

use crate::import_railjson;
use crate::schema::RailJson;
use crate::fixtures::tests::{electrical_profile_set, TestFixture};
use actix_web::test as actix_test;
use diesel::sql_query;
use diesel::sql_types::Text;
use diesel_async::{
AsyncConnection as Connection, AsyncPgConnection as PgConnection, RunQueryDsl,
};
use diesel_async::RunQueryDsl;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use rstest::rstest;
use std::io::Write;
use tempfile::NamedTempFile;

Expand Down Expand Up @@ -548,4 +595,45 @@ mod tests {
write!(tmp_file, "{}", serde_json::to_string(railjson).unwrap()).unwrap();
tmp_file
}

#[rstest]
async fn test_electrical_profile_set_delete(
#[future] electrical_profile_set: TestFixture<ElectricalProfileSet>,
) {
let pg_config = PostgresConfig::default();
let electrical_profile_set = electrical_profile_set.await;

let mut conn = PgConnection::establish(&pg_config.url()).await.unwrap();
let previous_length = ElectricalProfileSet::list_light(&mut conn)
.await
.unwrap()
.len();

let args = DeleteProfileSetArgs {
profile_set_ids: vec![electrical_profile_set.id()],
};
electrical_profile_set_delete(args, pg_config.clone())
.await
.unwrap();

let mut conn = PgConnection::establish(&pg_config.url()).await.unwrap();
let new_length = ElectricalProfileSet::list_light(&mut conn)
.await
.unwrap()
.len();
assert_eq!(new_length, previous_length - 1);
}

#[rstest]
async fn test_electrical_profile_set_list_doesnt_fail(
#[future] electrical_profile_set: TestFixture<ElectricalProfileSet>,
) {
let _electrical_profile_set = electrical_profile_set.await;
for quiet in [true, false] {
let args = ListProfileSetArgs { quiet };
electrical_profile_set_list(args, PostgresConfig::default())
.await
.unwrap();
}
}
}
10 changes: 10 additions & 0 deletions editoast/src/models/electrical_profile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::error::Result;
use crate::schema::electrical_profiles::ElectricalProfileSetData;
use crate::tables::electrical_profile_set;

Expand All @@ -7,6 +8,7 @@ use crate::models::Identifiable;
use crate::DieselJson;
use derivative::Derivative;
use diesel::result::Error as DieselError;
use diesel_async::{AsyncPgConnection as PgConnection, RunQueryDsl};
use editoast_derive::Model;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -42,6 +44,14 @@ impl Identifiable for ElectricalProfileSet {
}
}

impl ElectricalProfileSet {
pub async fn list_light(conn: &mut PgConnection) -> Result<Vec<LightElectricalProfileSet>> {
use crate::tables::electrical_profile_set::dsl::*;
let result = electrical_profile_set.select((id, name)).load(conn).await?;
Ok(result)
}
}

#[derive(Debug, Default, Queryable, Identifiable, Serialize, Deserialize)]
#[diesel(table_name = electrical_profile_set)]
pub struct LightElectricalProfileSet {
Expand Down
10 changes: 0 additions & 10 deletions editoast/src/views/electrical_profiles.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::diesel::QueryDsl;
use crate::error::Result;
use crate::models::electrical_profile::{ElectricalProfileSet, LightElectricalProfileSet};
use crate::models::{Create, Retrieve};
Expand All @@ -9,7 +8,6 @@ use crate::DieselJson;
use actix_web::dev::HttpServiceFactory;
use actix_web::web::{self, Data, Json, Path, Query};
use actix_web::{get, post};
use diesel_async::{AsyncPgConnection as PgConnection, RunQueryDsl};
use editoast_derive::EditoastError;
use serde::Deserialize;
use std::collections::HashMap;
Expand Down Expand Up @@ -82,14 +80,6 @@ async fn get_level_order(
Ok(Json(ep_set.data.unwrap().0.level_order))
}

impl ElectricalProfileSet {
async fn list_light(conn: &mut PgConnection) -> Result<Vec<LightElectricalProfileSet>> {
use crate::tables::electrical_profile_set::dsl::*;
let result = electrical_profile_set.select((id, name)).load(conn).await?;
Ok(result)
}
}

#[derive(Debug, Error, EditoastError)]
#[editoast_error(base_id = "electrical_profiles")]
pub enum ElectricalProfilesError {
Expand Down