@@ -27,10 +27,13 @@ use chashmap::CHashMap;
27
27
use clap:: Parser ;
28
28
use client:: {
29
29
ClearArgs , Client , Color , Commands , DeleteProfileSetArgs , ElectricalProfilesCommands ,
30
- GenerateArgs , ImportProfileSetArgs , ImportRailjsonArgs , ImportRollingStockArgs , InfraCloneArgs ,
31
- InfraCommands , ListProfileSetArgs , MakeMigrationArgs , RedisConfig , RefreshArgs , RunserverArgs ,
32
- SearchCommands ,
30
+ GenerateArgs , ImportProfileSetArgs , ImportRailjsonArgs , ImportRollingStockArgs ,
31
+ ImportTrainArgs , InfraCloneArgs , InfraCommands , ListProfileSetArgs , MakeMigrationArgs ,
32
+ RedisConfig , RefreshArgs , RunserverArgs , SearchCommands , TrainsCommands ,
33
33
} ;
34
+ use modelsv2:: train_schedule:: TrainScheduleChangeset ;
35
+ use views:: v2:: train_schedule:: TrainScheduleForm ;
36
+
34
37
use colored:: * ;
35
38
use core:: CoreClient ;
36
39
use diesel:: { sql_query, ConnectionError , ConnectionResult } ;
@@ -185,9 +188,65 @@ async fn run() -> Result<(), Box<dyn Error + Send + Sync>> {
185
188
}
186
189
InfraCommands :: ImportRailjson ( args) => import_railjson ( args, create_db_pool ( ) ?) . await ,
187
190
} ,
191
+ Commands :: Trains ( subcommand) => match subcommand {
192
+ TrainsCommands :: Import ( args) => trains_import ( args, create_db_pool ( ) ?) . await ,
193
+ } ,
188
194
}
189
195
}
190
196
197
+ async fn trains_import (
198
+ args : ImportTrainArgs ,
199
+ db_pool : Data < DbPool > ,
200
+ ) -> Result < ( ) , Box < dyn Error + Send + Sync > > {
201
+ let train_file = match File :: open ( args. path . clone ( ) ) {
202
+ Ok ( file) => file,
203
+ Err ( e) => {
204
+ let error = CliError :: new (
205
+ 1 ,
206
+ format ! ( "❌ Could not open file {:?} ({:?})" , args. path, e) ,
207
+ ) ;
208
+ return Err ( Box :: new ( error) ) ;
209
+ }
210
+ } ;
211
+
212
+ let conn = & mut db_pool. get ( ) . await ?;
213
+ let timetable = match args. timetable {
214
+ Some ( timetable) => match Timetable :: retrieve ( conn, timetable) . await ? {
215
+ Some ( timetable) => timetable,
216
+ None => {
217
+ let error = CliError :: new ( 1 , format ! ( "❌ Timetable not found, id: {0}" , timetable) ) ;
218
+ return Err ( Box :: new ( error) ) ;
219
+ }
220
+ } ,
221
+ None => {
222
+ let changeset = Timetable :: changeset ( ) ;
223
+ changeset. create ( conn) . await ?
224
+ }
225
+ } ;
226
+
227
+ let train_schedules: Vec < TrainScheduleBase > =
228
+ serde_json:: from_reader ( BufReader :: new ( train_file) ) ?;
229
+ let changesets: Vec < TrainScheduleChangeset > = train_schedules
230
+ . into_iter ( )
231
+ . map ( |train_schedule| {
232
+ TrainScheduleForm {
233
+ timetable_id : timetable. id ,
234
+ train_schedule,
235
+ }
236
+ . into ( )
237
+ } )
238
+ . collect ( ) ;
239
+ let inserted: Vec < _ > = TrainSchedule :: create_batch ( conn, changesets) . await ?;
240
+
241
+ println ! (
242
+ "✅ {} train schedules created for timetable with id {}" ,
243
+ inserted. len( ) ,
244
+ timetable. id
245
+ ) ;
246
+
247
+ Ok ( ( ) )
248
+ }
249
+
191
250
fn init_sentry ( args : & RunserverArgs ) -> Option < ClientInitGuard > {
192
251
match ( args. sentry_dsn . clone ( ) , args. sentry_env . clone ( ) ) {
193
252
( Some ( sentry_dsn) , Some ( sentry_env) ) => Some ( sentry:: init ( (
@@ -790,10 +849,11 @@ mod tests {
790
849
use super :: * ;
791
850
792
851
use crate :: fixtures:: tests:: {
793
- db_pool, electrical_profile_set, get_fast_rolling_stock, TestFixture ,
852
+ db_pool, electrical_profile_set, get_fast_rolling_stock, get_trainschedule_json_array,
853
+ TestFixture ,
794
854
} ;
795
855
use diesel:: sql_query;
796
- use diesel:: sql_types:: Text ;
856
+ use diesel:: sql_types:: { BigInt , Text } ;
797
857
use diesel_async:: RunQueryDsl ;
798
858
use rand:: distributions:: Alphanumeric ;
799
859
use rand:: { thread_rng, Rng } ;
@@ -802,6 +862,32 @@ mod tests {
802
862
use std:: io:: Write ;
803
863
use tempfile:: NamedTempFile ;
804
864
865
+ #[ rstest]
866
+ async fn import_train_schedule_v2 ( db_pool : Data < DbPool > ) {
867
+ let conn = & mut db_pool. get ( ) . await . unwrap ( ) ;
868
+
869
+ let changeset = Timetable :: changeset ( ) ;
870
+ let timetable = changeset. create ( conn) . await . unwrap ( ) ;
871
+
872
+ let mut file = NamedTempFile :: new ( ) . unwrap ( ) ;
873
+ file. write ( get_trainschedule_json_array ( ) . as_bytes ( ) ) ;
874
+
875
+ let args = ImportTrainArgs {
876
+ path : file. path ( ) . into ( ) ,
877
+ timetable : Some ( timetable. id ) ,
878
+ } ;
879
+
880
+ let result = trains_import ( args, db_pool. clone ( ) ) . await ;
881
+
882
+ assert ! ( result. is_ok( ) , "{:?}" , result) ;
883
+
884
+ sql_query ( "DELETE FROM timetable_v2 WHERE id = $1" )
885
+ . bind :: < BigInt , _ > ( timetable. id )
886
+ . execute ( conn)
887
+ . await
888
+ . unwrap ( ) ;
889
+ }
890
+
805
891
#[ rstest]
806
892
async fn import_rolling_stock_ko_file_not_found ( db_pool : Data < DbPool > ) {
807
893
// GIVEN
0 commit comments