@@ -9,12 +9,14 @@ import doobie.util.TestTypes.*
99import doobie .util .transactor .Transactor
1010import doobie .testutils .VoidExtensions
1111import doobie .syntax .all .*
12+ import doobie .util .Read .CompositeOfInstances
1213import doobie .{ConnectionIO , Query }
1314import doobie .util .analysis .{Analysis , ColumnMisalignment , ColumnTypeError , ColumnTypeWarning , NullabilityMisalignment }
1415import doobie .util .fragment .Fragment
1516import munit .Location
1617
1718import scala .annotation .nowarn
19+ import scala .collection .immutable .ArraySeq
1820
1921class ReadSuite extends munit.CatsEffectSuite with ReadSuitePlatform {
2022
@@ -201,6 +203,54 @@ class ReadSuite extends munit.CatsEffectSuite with ReadSuitePlatform {
201203 q2.transact(xa).assertEquals(List (Some ((1 , 2 , 3 , 4 ))))
202204 }
203205
206+ test(" Read.CompositeOfInstances reads columns correctly" ) {
207+ import cats .syntax .functor .*
208+ val rscc : Read [SimpleCaseClass ] = Read .derived[SimpleCaseClass ]
209+
210+ implicit val read : Read [ComplexCaseClass ] =
211+ new Read .CompositeOfInstances (ArraySeq (
212+ rscc.widen[Any ],
213+ rscc.toOpt.widen[Any ],
214+ Read [Option [Int ]].widen[Any ],
215+ Read [String ].widen[Any ]))
216+ .map { arr =>
217+ ComplexCaseClass (
218+ arr(0 ).asInstanceOf [SimpleCaseClass ],
219+ arr(1 ).asInstanceOf [Option [SimpleCaseClass ]],
220+ arr(2 ).asInstanceOf [Option [Int ]],
221+ arr(3 ).asInstanceOf [String ])
222+ }
223+
224+ assertEquals(read.length, 8 )
225+
226+ sql " SELECT 1, '2', '3', 4, '5', '6', 7, '8' "
227+ .query[ComplexCaseClass ].unique.transact(xa)
228+ .assertEquals(
229+ ComplexCaseClass (
230+ SimpleCaseClass (Some (1 ), " 2" , Some (" 3" )),
231+ Some (SimpleCaseClass (Some (4 ), " 5" , Some (" 6" ))),
232+ Some (7 ),
233+ " 8"
234+ )
235+ )
236+
237+ // The 's' field in Option[SimpleCaseClass] is NULL, so whole case class value is None
238+ sql " SELECT NULL, '2', '3', 4, NULL, '6', 7, '8' "
239+ .query[ComplexCaseClass ].unique.transact(xa)
240+ .assertEquals(
241+ ComplexCaseClass (
242+ SimpleCaseClass (None , " 2" , Some (" 3" )),
243+ None ,
244+ Some (7 ),
245+ " 8"
246+ )
247+ )
248+
249+ sql " SELECT 1, NULL, '3', 4, '5', '6', 7, '8' "
250+ .query[Option [ComplexCaseClass ]].unique.transact(xa)
251+ .assertEquals(None )
252+ }
253+
204254 test(" Read should select correct columns when combined with `ap`" ) {
205255 import cats .syntax .all .*
206256 import doobie .implicits .*
0 commit comments