@@ -7,10 +7,12 @@ use crate::inet::CassInet;
7
7
use crate :: metadata:: {
8
8
CassColumnMeta , CassKeyspaceMeta , CassMaterializedViewMeta , CassSchemaMeta , CassTableMeta ,
9
9
} ;
10
+ use crate :: query_result:: Value :: { CollectionValue , RegularValue } ;
10
11
use crate :: types:: * ;
11
12
use crate :: uuid:: CassUuid ;
12
- use scylla:: frame:: response:: result:: { ColumnSpec , CqlValue } ;
13
+ use scylla:: frame:: response:: result:: { ColumnSpec , CqlValue , Row } ;
13
14
use scylla:: transport:: PagingStateResponse ;
15
+ use scylla:: QueryResult ;
14
16
use std:: convert:: TryInto ;
15
17
use std:: os:: raw:: c_char;
16
18
use std:: sync:: Arc ;
@@ -23,6 +25,34 @@ pub struct CassResult {
23
25
pub paging_state_response : PagingStateResponse ,
24
26
}
25
27
28
+ impl CassResult {
29
+ /// It creates CassResult object based on the:
30
+ /// - query result
31
+ /// - paging state response
32
+ /// - optional cached result metadata - it's provided for prepared statements
33
+ pub fn from_result_payload (
34
+ result : QueryResult ,
35
+ paging_state_response : PagingStateResponse ,
36
+ maybe_result_metadata : Option < Arc < CassResultMetadata > > ,
37
+ ) -> Self {
38
+ // maybe_result_metadata is:
39
+ // - Some(_) for prepared statements
40
+ // - None for unprepared statements
41
+ let metadata = maybe_result_metadata
42
+ . unwrap_or_else ( || Arc :: new ( CassResultMetadata :: from_column_specs ( result. col_specs ( ) ) ) ) ;
43
+ let cass_rows = result
44
+ . rows
45
+ . map ( |rows| create_cass_rows_from_rows ( rows, & metadata) ) ;
46
+
47
+ CassResult {
48
+ rows : cass_rows,
49
+ metadata,
50
+ tracing_id : result. tracing_id ,
51
+ paging_state_response,
52
+ }
53
+ }
54
+ }
55
+
26
56
#[ derive( Debug ) ]
27
57
pub struct CassResultMetadata {
28
58
pub col_specs : Vec < CassColumnSpec > ,
@@ -51,6 +81,18 @@ pub struct CassRow {
51
81
pub result_metadata : Arc < CassResultMetadata > ,
52
82
}
53
83
84
+ pub fn create_cass_rows_from_rows (
85
+ rows : Vec < Row > ,
86
+ metadata : & Arc < CassResultMetadata > ,
87
+ ) -> Vec < CassRow > {
88
+ rows. into_iter ( )
89
+ . map ( |r| CassRow {
90
+ columns : create_cass_row_columns ( r, metadata) ,
91
+ result_metadata : metadata. clone ( ) ,
92
+ } )
93
+ . collect ( )
94
+ }
95
+
54
96
pub enum Value {
55
97
RegularValue ( CqlValue ) ,
56
98
CollectionValue ( Collection ) ,
@@ -73,6 +115,120 @@ pub struct CassValue {
73
115
pub value_type : Arc < CassDataType > ,
74
116
}
75
117
118
+ fn create_cass_row_columns ( row : Row , metadata : & Arc < CassResultMetadata > ) -> Vec < CassValue > {
119
+ row. columns
120
+ . into_iter ( )
121
+ . zip ( metadata. col_specs . iter ( ) )
122
+ . map ( |( val, col_spec) | {
123
+ let column_type = Arc :: clone ( & col_spec. data_type ) ;
124
+ CassValue {
125
+ value : val. map ( |col_val| get_column_value ( col_val, & column_type) ) ,
126
+ value_type : column_type,
127
+ }
128
+ } )
129
+ . collect ( )
130
+ }
131
+
132
+ fn get_column_value ( column : CqlValue , column_type : & Arc < CassDataType > ) -> Value {
133
+ match ( column, column_type. as_ref ( ) ) {
134
+ (
135
+ CqlValue :: List ( list) ,
136
+ CassDataType :: List {
137
+ typ : Some ( list_type) ,
138
+ ..
139
+ } ,
140
+ ) => CollectionValue ( Collection :: List (
141
+ list. into_iter ( )
142
+ . map ( |val| CassValue {
143
+ value_type : list_type. clone ( ) ,
144
+ value : Some ( get_column_value ( val, list_type) ) ,
145
+ } )
146
+ . collect ( ) ,
147
+ ) ) ,
148
+ (
149
+ CqlValue :: Map ( map) ,
150
+ CassDataType :: Map {
151
+ typ : MapDataType :: KeyAndValue ( key_type, value_type) ,
152
+ ..
153
+ } ,
154
+ ) => CollectionValue ( Collection :: Map (
155
+ map. into_iter ( )
156
+ . map ( |( key, val) | {
157
+ (
158
+ CassValue {
159
+ value_type : key_type. clone ( ) ,
160
+ value : Some ( get_column_value ( key, key_type) ) ,
161
+ } ,
162
+ CassValue {
163
+ value_type : value_type. clone ( ) ,
164
+ value : Some ( get_column_value ( val, value_type) ) ,
165
+ } ,
166
+ )
167
+ } )
168
+ . collect ( ) ,
169
+ ) ) ,
170
+ (
171
+ CqlValue :: Set ( set) ,
172
+ CassDataType :: Set {
173
+ typ : Some ( set_type) ,
174
+ ..
175
+ } ,
176
+ ) => CollectionValue ( Collection :: Set (
177
+ set. into_iter ( )
178
+ . map ( |val| CassValue {
179
+ value_type : set_type. clone ( ) ,
180
+ value : Some ( get_column_value ( val, set_type) ) ,
181
+ } )
182
+ . collect ( ) ,
183
+ ) ) ,
184
+ (
185
+ CqlValue :: UserDefinedType {
186
+ keyspace,
187
+ type_name,
188
+ fields,
189
+ } ,
190
+ CassDataType :: UDT ( udt_type) ,
191
+ ) => CollectionValue ( Collection :: UserDefinedType {
192
+ keyspace,
193
+ type_name,
194
+ fields : fields
195
+ . into_iter ( )
196
+ . enumerate ( )
197
+ . map ( |( index, ( name, val_opt) ) | {
198
+ let udt_field_type_opt = udt_type. get_field_by_index ( index) ;
199
+ if let ( Some ( val) , Some ( udt_field_type) ) = ( val_opt, udt_field_type_opt) {
200
+ return (
201
+ name,
202
+ Some ( CassValue {
203
+ value_type : udt_field_type. clone ( ) ,
204
+ value : Some ( get_column_value ( val, udt_field_type) ) ,
205
+ } ) ,
206
+ ) ;
207
+ }
208
+ ( name, None )
209
+ } )
210
+ . collect ( ) ,
211
+ } ) ,
212
+ ( CqlValue :: Tuple ( tuple) , CassDataType :: Tuple ( tuple_types) ) => {
213
+ CollectionValue ( Collection :: Tuple (
214
+ tuple
215
+ . into_iter ( )
216
+ . enumerate ( )
217
+ . map ( |( index, val_opt) | {
218
+ val_opt
219
+ . zip ( tuple_types. get ( index) )
220
+ . map ( |( val, tuple_field_type) | CassValue {
221
+ value_type : tuple_field_type. clone ( ) ,
222
+ value : Some ( get_column_value ( val, tuple_field_type) ) ,
223
+ } )
224
+ } )
225
+ . collect ( ) ,
226
+ ) )
227
+ }
228
+ ( regular_value, _) => RegularValue ( regular_value) ,
229
+ }
230
+ }
231
+
76
232
pub struct CassResultIterator {
77
233
result : Arc < CassResult > ,
78
234
position : Option < usize > ,
@@ -1392,11 +1548,11 @@ mod tests {
1392
1548
cass_result_column_data_type, cass_result_column_name, cass_result_first_row,
1393
1549
ptr_to_cstr_n, ptr_to_ref, size_t,
1394
1550
} ,
1395
- session:: create_cass_rows_from_rows,
1396
1551
} ;
1397
1552
1398
1553
use super :: {
1399
- cass_result_column_count, cass_result_column_type, CassResult , CassResultMetadata ,
1554
+ cass_result_column_count, cass_result_column_type, create_cass_rows_from_rows, CassResult ,
1555
+ CassResultMetadata ,
1400
1556
} ;
1401
1557
1402
1558
fn col_spec ( name : & ' static str , typ : ColumnType < ' static > ) -> ColumnSpec < ' static > {
0 commit comments