@@ -7,9 +7,9 @@ pub use light_rolling_stock::LightRollingStockModel;
7
7
pub use rolling_stock_image:: RollingStockSeparatedImageModel ;
8
8
pub use rolling_stock_livery:: RollingStockLiveryModel ;
9
9
10
- use crate :: error:: Result ;
10
+ use crate :: error:: { InternalError , Result } ;
11
11
use crate :: models:: rolling_stock:: rolling_stock_livery:: RollingStockLiveryMetadata ;
12
- use crate :: models:: { Identifiable , TextArray , Update } ;
12
+ use crate :: models:: { Create , Identifiable , TextArray , Update } ;
13
13
use crate :: schema:: rolling_stock:: {
14
14
EffortCurves , EnergySource , Gamma , RollingResistance , RollingStock , RollingStockCommon ,
15
15
RollingStockMetadata , RollingStockWithLiveries ,
@@ -19,8 +19,8 @@ use crate::views::rolling_stocks::RollingStockError;
19
19
use crate :: DbPool ;
20
20
use actix_web:: web:: Data ;
21
21
use derivative:: Derivative ;
22
- use diesel:: result:: Error as DieselError ;
23
- use diesel:: { update, ExpressionMethods , QueryDsl , SelectableHelper } ;
22
+ use diesel:: result:: { DatabaseErrorInformation , DatabaseErrorKind , Error as DieselError } ;
23
+ use diesel:: { insert_into , update, ExpressionMethods , QueryDsl , SelectableHelper } ;
24
24
use diesel_async:: { AsyncPgConnection as PgConnection , RunQueryDsl } ;
25
25
use diesel_json:: Json as DieselJson ;
26
26
use editoast_derive:: Model ;
@@ -41,7 +41,7 @@ use serde_json::Value as JsonValue;
41
41
) ]
42
42
#[ derivative( Default , PartialEq ) ]
43
43
#[ model( table = "rolling_stock" ) ]
44
- #[ model( create , retrieve, delete) ]
44
+ #[ model( retrieve, delete) ]
45
45
#[ diesel( table_name = rolling_stock) ]
46
46
pub struct RollingStockModel {
47
47
#[ diesel( deserialize_as = i64 ) ]
@@ -70,8 +70,8 @@ pub struct RollingStockModel {
70
70
pub gamma : Option < DieselJson < Gamma > > ,
71
71
#[ diesel( deserialize_as = f64 ) ]
72
72
pub inertia_coefficient : Option < f64 > ,
73
- #[ diesel( deserialize_as = String ) ]
74
- pub base_power_class : Option < String > ,
73
+ #[ diesel( deserialize_as = Option < String > ) ]
74
+ pub base_power_class : Option < Option < String > > ,
75
75
#[ diesel( deserialize_as = TextArray ) ]
76
76
pub features : Option < Vec < String > > ,
77
77
#[ diesel( deserialize_as = f64 ) ]
@@ -136,6 +136,32 @@ impl RollingStockModel {
136
136
}
137
137
}
138
138
139
+ fn is_given_constraint (
140
+ error_info : & ( dyn DatabaseErrorInformation + Send + Sync ) ,
141
+ column_name : & str ,
142
+ ) -> bool {
143
+ error_info
144
+ . constraint_name ( )
145
+ . map ( |name| name == column_name)
146
+ . unwrap_or ( false )
147
+ }
148
+
149
+ fn map_diesel_error ( e : DieselError , rs_name : String ) -> InternalError {
150
+ match e {
151
+ DieselError :: DatabaseError ( DatabaseErrorKind :: UniqueViolation , info)
152
+ if is_given_constraint ( info. as_ref ( ) , "rolling_stock_name_key" ) =>
153
+ {
154
+ RollingStockError :: NameAlreadyUsed { name : rs_name } . into ( )
155
+ }
156
+ DieselError :: DatabaseError ( DatabaseErrorKind :: CheckViolation , info)
157
+ if is_given_constraint ( info. as_ref ( ) , "base_power_class_null_or_non_empty" ) =>
158
+ {
159
+ RollingStockError :: BasePowerClassEmpty . into ( )
160
+ }
161
+ e => e. into ( ) ,
162
+ }
163
+ }
164
+
139
165
#[ async_trait]
140
166
impl Update for RollingStockModel {
141
167
async fn update_conn (
@@ -151,17 +177,23 @@ impl Update for RollingStockModel {
151
177
. await
152
178
{
153
179
Ok ( rs) => Ok ( Some ( rs) ) ,
154
- Err ( DieselError :: NotFound ) => {
155
- Err ( RollingStockError :: NotFound { rolling_stock_id } . into ( ) )
156
- }
157
- Err ( DieselError :: DatabaseError (
158
- diesel:: result:: DatabaseErrorKind :: UniqueViolation ,
159
- _,
160
- ) ) => Err ( RollingStockError :: NameAlreadyUsed {
161
- name : self . name . unwrap ( ) ,
162
- }
163
- . into ( ) ) ,
164
- Err ( e) => Err ( e. into ( ) ) ,
180
+ Err ( DieselError :: NotFound ) => Ok ( None ) ,
181
+ Err ( e) => Err ( map_diesel_error ( e, self . name . unwrap ( ) ) ) ,
182
+ }
183
+ }
184
+ }
185
+
186
+ #[ async_trait]
187
+ impl Create for RollingStockModel {
188
+ async fn create_conn ( self , conn : & mut PgConnection ) -> Result < Self > {
189
+ use crate :: tables:: rolling_stock:: dsl:: * ;
190
+ match insert_into ( rolling_stock)
191
+ . values ( & self )
192
+ . get_result ( conn)
193
+ . await
194
+ {
195
+ Ok ( rs) => Ok ( rs) ,
196
+ Err ( e) => Err ( map_diesel_error ( e, self . name . unwrap ( ) ) ) ,
165
197
}
166
198
}
167
199
}
0 commit comments