@@ -2,8 +2,10 @@ use std::str::FromStr;
2
2
3
3
use super :: extern_db:: ExternDBTrait ;
4
4
use crate :: common:: BlockPtr ;
5
+ use crate :: debug;
5
6
use crate :: error;
6
7
use crate :: errors:: DatabaseError ;
8
+ use crate :: info;
7
9
use crate :: messages:: RawEntity ;
8
10
use crate :: runtime:: asc:: native_types:: store:: Bytes ;
9
11
use crate :: runtime:: asc:: native_types:: store:: StoreValueKind ;
@@ -92,24 +94,28 @@ impl Scylladb {
92
94
. to_string ( )
93
95
}
94
96
95
- fn cql_value_to_store_value ( field_kind : FieldKind , value : CqlValue ) -> Value {
97
+ fn cql_value_to_store_value ( field_kind : FieldKind , value : Option < CqlValue > ) -> Value {
96
98
match field_kind. kind {
97
- StoreValueKind :: Int => Value :: Int ( value. as_int ( ) . unwrap ( ) ) ,
98
- StoreValueKind :: Int8 => Value :: Int8 ( value. as_bigint ( ) . unwrap ( ) ) ,
99
- StoreValueKind :: String => Value :: String ( value. as_text ( ) . unwrap ( ) . to_owned ( ) ) ,
100
- StoreValueKind :: Bool => Value :: Bool ( value. as_boolean ( ) . unwrap ( ) ) ,
99
+ StoreValueKind :: Int => Value :: Int ( value. unwrap ( ) . as_int ( ) . unwrap ( ) ) ,
100
+ StoreValueKind :: Int8 => Value :: Int8 ( value. unwrap ( ) . as_bigint ( ) . unwrap ( ) ) ,
101
+ StoreValueKind :: String => Value :: String ( value. unwrap ( ) . as_text ( ) . unwrap ( ) . to_owned ( ) ) ,
102
+ StoreValueKind :: Bool => Value :: Bool ( value. unwrap ( ) . as_boolean ( ) . unwrap ( ) ) ,
101
103
StoreValueKind :: BigDecimal => {
102
- Value :: BigDecimal ( BigDecimal :: from_str ( value. as_text ( ) . unwrap ( ) ) . unwrap ( ) )
104
+ Value :: BigDecimal ( BigDecimal :: from_str ( value. unwrap ( ) . as_text ( ) . unwrap ( ) ) . unwrap ( ) )
103
105
}
104
106
StoreValueKind :: BigInt => {
105
- Value :: BigInt ( BigInt :: from_str ( value. as_text ( ) . unwrap ( ) ) . unwrap ( ) )
107
+ Value :: BigInt ( BigInt :: from_str ( value. unwrap ( ) . as_text ( ) . unwrap ( ) ) . unwrap ( ) )
106
108
}
107
109
StoreValueKind :: Bytes => {
108
- let bytes = value. as_blob ( ) . unwrap ( ) ;
110
+ let bytes_value = value. unwrap ( ) ;
111
+ let bytes = bytes_value. as_blob ( ) . unwrap ( ) ;
109
112
Value :: Bytes ( Bytes :: from ( bytes. as_slice ( ) ) )
110
113
}
111
114
StoreValueKind :: Array => {
112
- let inner_values = value. as_list ( ) . cloned ( ) . unwrap_or_default ( ) ;
115
+ if value. is_none ( ) {
116
+ return Value :: List ( vec ! [ ] ) ;
117
+ }
118
+ let inner_values = value. unwrap ( ) . as_list ( ) . cloned ( ) . unwrap_or_default ( ) ;
113
119
let inner_values = inner_values
114
120
. into_iter ( )
115
121
. map ( |inner_val| {
@@ -119,7 +125,7 @@ impl Scylladb {
119
125
relation : None ,
120
126
list_inner_kind : None ,
121
127
} ,
122
- inner_val,
128
+ Some ( inner_val) ,
123
129
)
124
130
} )
125
131
. collect :: < Vec < _ > > ( ) ;
@@ -141,28 +147,28 @@ impl Scylladb {
141
147
142
148
for row in rows {
143
149
let mut entity = RawEntity :: new ( ) ;
144
- for ( idx, column) in row. columns . into_iter ( ) . flatten ( ) . enumerate ( ) {
145
- let col_spec = col_specs[ idx] . to_owned ( ) ;
146
- let field_name = col_spec. name ;
150
+ for ( idx, column) in row. columns . iter ( ) . enumerate ( ) {
151
+ let col_spec = col_specs[ idx] . clone ( ) ;
152
+ let field_name = col_spec. name . clone ( ) ;
147
153
148
154
if field_name == "is_deleted" {
149
155
entity. insert (
150
156
"is_deleted" . to_string ( ) ,
151
- Value :: Bool ( column. as_boolean ( ) . unwrap ( ) ) ,
157
+ Value :: Bool ( column. clone ( ) . unwrap ( ) . as_boolean ( ) . unwrap ( ) ) ,
152
158
) ;
153
159
continue ;
154
160
}
155
161
156
162
if field_name == "block_ptr_number" {
157
163
entity. insert (
158
164
"block_ptr_number" . to_string ( ) ,
159
- Value :: Int8 ( column. as_bigint ( ) . unwrap ( ) ) ,
165
+ Value :: Int8 ( column. clone ( ) . unwrap ( ) . as_bigint ( ) . unwrap ( ) ) ,
160
166
) ;
161
167
continue ;
162
168
}
163
169
164
170
let field_kind = self . schema_lookup . get_field ( entity_type, & field_name) ;
165
- let value = Scylladb :: cql_value_to_store_value ( field_kind, column) ;
171
+ let value = Scylladb :: cql_value_to_store_value ( field_kind, column. clone ( ) ) ;
166
172
entity. insert ( field_name, value) ;
167
173
}
168
174
@@ -249,10 +255,25 @@ impl Scylladb {
249
255
CqlValue :: BigInt ( block_ptr. number as i64 ) ,
250
256
data. get( "is_deleted" ) . unwrap( ) . clone( ) . into( ) ,
251
257
] ;
252
- for ( field_name, _field_kind) in schema. iter ( ) {
253
- let value = data. get ( field_name) . cloned ( ) . unwrap ( ) ;
258
+ for ( field_name, field_kind) in schema. iter ( ) {
259
+ let value = match data. get ( field_name) {
260
+ None => {
261
+ //handle case when field is missing but has in schema
262
+ debug ! (
263
+ Scylladb ,
264
+ "Missing field" ;
265
+ entity_type => entity_type,
266
+ field_name => field_name,
267
+ data => format!( "{:?}" , data)
268
+ ) ;
269
+ let default_value =
270
+ Scylladb :: cql_value_to_store_value ( field_kind. clone ( ) , None ) ;
271
+ CqlValue :: from ( default_value)
272
+ }
273
+ Some ( val) => CqlValue :: from ( val. clone ( ) ) ,
274
+ } ;
275
+ values_params. push ( value) ;
254
276
fields. push ( format ! ( "\" {}\" " , field_name) ) ;
255
- values_params. push ( CqlValue :: from ( value) ) ;
256
277
column_values. push ( "?" . to_string ( ) ) ;
257
278
}
258
279
0 commit comments