1818
1919import com .datastax .oss .driver .api .core .CqlIdentifier ;
2020import com .datastax .oss .driver .api .core .cql .ColumnDefinition ;
21- import com .datastax .oss .driver .api .core .cql .ColumnDefinitions ;
2221import com .datastax .oss .driver .api .core .cql .Row ;
2322import com .datastax .oss .driver .api .core .data .UdtValue ;
2423import com .datastax .oss .driver .api .core .type .DataType ;
25- import com .datastax .oss .driver .api .core .type .ListType ;
2624import com .datastax .oss .driver .api .core .type .UserDefinedType ;
2725import com .datastax .oss .driver .api .core .type .codec .TypeCodec ;
28- import com .datastax .oss .driver .api .core .type .codec .TypeCodecs ;
2926import com .datastax .oss .driver .api .core .type .codec .registry .CodecRegistry ;
30- import com .datastax .oss .driver .shaded .guava .common .reflect .TypeToken ;
3127import com .datastax .oss .protocol .internal .ProtocolConstants ;
3228import jakarta .nosql .Value ;
3329import jakarta .nosql .column .Column ;
3430import jakarta .nosql .column .ColumnEntity ;
3531
36- import java .nio .ByteBuffer ;
3732import java .util .ArrayList ;
3833import java .util .List ;
3934import java .util .Objects ;
4035import java .util .stream .StreamSupport ;
4136
42- import static java .util .stream .Collectors .reducing ;
4337import static java .util .stream .Collectors .toList ;
4438
4539final class CassandraConverter {
@@ -69,6 +63,11 @@ private static Column getColumn(ColumnDefinition definition, Object result) {
6963 return Column .class .cast (result );
7064 case ProtocolConstants .DataType .LIST :
7165 case ProtocolConstants .DataType .SET :
66+ if (isUDTIterable (result )) {
67+ return UDT .builder (getUserType (result )).withName (definition .getName ().asInternal ())
68+ .addUDTs (getColumns (definition , result )).build ();
69+ }
70+
7271 default :
7372 return Column .of (definition .getName ().asInternal (), Value .of (result ));
7473 }
@@ -79,13 +78,14 @@ static Object get(ColumnDefinition definition, Row row) {
7978 String name = definition .getName ().asInternal ();
8079 final DataType type = definition .getType ();
8180 if (type instanceof UserDefinedType ) {
82- return getUDT (name , row .getUdtValue (name ));
81+ return getUDT (definition , row .getUdtValue (name ));
8382 }
8483 final TypeCodec <Object > codec = row .codecRegistry ().codecFor (type );
8584 return row .get (name , codec );
8685 }
8786
88- private static UDT getUDT (String name , UdtValue udtValue ) {
87+ private static UDT getUDT (ColumnDefinition definition , UdtValue udtValue ) {
88+ String name = definition .getName ().asInternal ();
8989 final UserDefinedType type = udtValue .getType ();
9090 List <Column > columns = new ArrayList <>();
9191 List <String > names = type .getFieldNames ().stream ().map (CqlIdentifier ::asInternal ).collect (toList ());
@@ -100,4 +100,34 @@ private static UDT getUDT(String name, UdtValue udtValue) {
100100 return UDT .builder (type .getName ().asInternal ()).withName (name ).addUDT (columns ).build ();
101101 }
102102
103+ private static String getUserType (Object result ) {
104+ return StreamSupport .stream (Iterable .class .cast (result ).spliterator (), false )
105+ .limit (1L )
106+ .map (c -> UdtValue .class .cast (c ).getType ().getName ().asInternal ())
107+ .findFirst ()
108+ .get ().toString ();
109+ }
110+
111+ private static Iterable <Iterable <Column >> getColumns (ColumnDefinition definition , Object result ) {
112+
113+ List <Iterable <Column >> columns = new ArrayList <>();
114+ for (Object value : Iterable .class .cast (result )) {
115+ final UdtValue udtValue = UdtValue .class .cast (value );
116+ final UDT udt = getUDT (definition , udtValue );
117+ columns .add ((Iterable <Column >) udt .get ());
118+ }
119+
120+ return columns ;
121+ }
122+
123+ private static boolean isUDTIterable (Object result ) {
124+ final Iterable <?> iterable = Iterable .class .cast (result );
125+ if (!iterable .iterator ().hasNext ()) {
126+ return false ;
127+ }
128+ return StreamSupport .stream (iterable .spliterator (), false )
129+ .allMatch (UdtValue .class ::isInstance );
130+ }
131+
132+
103133}
0 commit comments