diff --git a/src/it/resources/migration/1__test_tables.cql b/src/it/resources/migration/1__test_tables.cql index 0147e22..aea4f1e 100644 --- a/src/it/resources/migration/1__test_tables.cql +++ b/src/it/resources/migration/1__test_tables.cql @@ -180,38 +180,38 @@ VALUES (3, {data: 'three', count: 30, flag: true, dataset: {300, 301, 302}, data INSERT INTO tests.udt_reads_type_test (id, udt) VALUES (4, {data: 'four'}); -CREATE TYPE tests.udt_for_udt_reads_default_name_test( +CREATE TYPE tests.udt_for_udt_codec_default_name_test( allupper text, alllower text, somename text, somelongname text ); -CREATE TABLE tests.udt_reads_default_name_test +CREATE TABLE tests.udt_codec_default_name_test ( id bigint, - udt udt_for_udt_reads_default_name_test, + udt udt_for_udt_codec_default_name_test, PRIMARY KEY (id) ); -INSERT INTO tests.udt_reads_default_name_test (id, udt) +INSERT INTO tests.udt_codec_default_name_test (id, udt) VALUES (0, {allupper: 'ALL-UPPER', alllower: 'all-lower', somename: 'some-name', somelongname: 'some-long-name'}); -CREATE TYPE tests.udt_for_udt_reads_snake_name_test( +CREATE TYPE tests.udt_for_udt_codec_snake_name_test( allupper text, alllower text, some_name text, some_long_name text ); -CREATE TABLE tests.udt_reads_snake_name_test +CREATE TABLE tests.udt_codec_snake_name_test ( id bigint, - udt udt_for_udt_reads_snake_name_test, + udt udt_for_udt_codec_snake_name_test, PRIMARY KEY (id) ); -INSERT INTO tests.udt_reads_snake_name_test (id, udt) +INSERT INTO tests.udt_codec_snake_name_test (id, udt) VALUES (0, {allupper: 'ALL-UPPER', alllower: 'all-lower', some_name: 'some-name', some_long_name: 'some-long-name'}); CREATE TABLE tests.nullable_collection_tests diff --git a/src/it/scala/zio/cassandra/session/IntegrationSpec.scala b/src/it/scala/zio/cassandra/session/IntegrationSpec.scala index 35b1cb5..e529ed7 100644 --- a/src/it/scala/zio/cassandra/session/IntegrationSpec.scala +++ b/src/it/scala/zio/cassandra/session/IntegrationSpec.scala @@ -2,7 +2,7 @@ package zio.cassandra.session import wvlet.log.{ LogFormatter, LogLevel, LogSupport, Logger } import zio.cassandra.session.cql.CqlSpec -import zio.cassandra.session.cql.codec.{ ReadsSpec, UdtReadsSpec } +import zio.cassandra.session.cql.codec.{ ReadsSpec, UdtReadsSpec, UdtWritesSpec } import zio.container.TestsSharedInstances import zio.test.DefaultRunnableSpec @@ -13,6 +13,12 @@ object IntegrationSpec extends DefaultRunnableSpec with TestsSharedInstances wit Logger.scanLogLevels override def spec = - suite("zio-cassandra")(SessionSpec.sessionTests, CqlSpec.cqlSuite, ReadsSpec.readsTests, UdtReadsSpec.readsTests) + suite("zio-cassandra")( + SessionSpec.sessionTests, + CqlSpec.cqlSuite, + ReadsSpec.readsTests, + UdtReadsSpec.readsTests, + UdtWritesSpec.writesTests + ) .provideCustomLayerShared(layer) } diff --git a/src/it/scala/zio/cassandra/session/cql/CqlSpec.scala b/src/it/scala/zio/cassandra/session/cql/CqlSpec.scala index 405561b..257a15b 100644 --- a/src/it/scala/zio/cassandra/session/cql/CqlSpec.scala +++ b/src/it/scala/zio/cassandra/session/cql/CqlSpec.scala @@ -450,28 +450,28 @@ object CqlSpec { } } } - ), - suite("put lifted values as is")( - testM("should handle lifted values (though redundant) in cqlConst") { - val tableName = "tests.test_data" - for { - results <- cqlConst"select data from ${lift(tableName)} where id in (1)".as[String].select.runCollect - } yield assertTrue(results == Chunk("one")) - }, - testM("should handle lifted values in cql") { - val tableName = "tests.test_data" - for { - results <- cql"select data from ${lift(tableName)} where id in ${List(1L)}".as[String].select.runCollect - } yield assertTrue(results == Chunk("one")) - }, - testM("should handle lifted values in cqlt") { - val tableName = "tests.test_data" - for { - query <- cqlt"select data from ${lift(tableName)} where id in ${Put[List[Long]]}".as[String].prepare - results <- query(List(1L)).select.runCollect - } yield assertTrue(results == Chunk("one")) - } ) + ), + suite("put lifted values as is")( + testM("should handle lifted values (though redundant) in cqlConst") { + val tableName = "tests.test_data" + for { + results <- cqlConst"select data from ${lift(tableName)} where id in (1)".as[String].select.runCollect + } yield assertTrue(results == Chunk("one")) + }, + testM("should handle lifted values in cql") { + val tableName = "tests.test_data" + for { + results <- cql"select data from ${lift(tableName)} where id in ${List(1L)}".as[String].select.runCollect + } yield assertTrue(results == Chunk("one")) + }, + testM("should handle lifted values in cqlt") { + val tableName = "tests.test_data" + for { + query <- cqlt"select data from ${lift(tableName)} where id in ${Put[List[Long]]}".as[String].prepare + results <- query(List(1L)).select.runCollect + } yield assertTrue(results == Chunk("one")) + } ) ) } diff --git a/src/it/scala/zio/cassandra/session/cql/codec/UdtReadsSpec.scala b/src/it/scala/zio/cassandra/session/cql/codec/UdtReadsSpec.scala index 3b8c043..45e3d7b 100644 --- a/src/it/scala/zio/cassandra/session/cql/codec/UdtReadsSpec.scala +++ b/src/it/scala/zio/cassandra/session/cql/codec/UdtReadsSpec.scala @@ -64,7 +64,7 @@ object UdtReadsSpec extends CassandraSpecUtils { session <- ZIO.service[Session] result <- session .selectFirst( - s"select id, udt FROM $keyspace.udt_reads_default_name_test" + s"select id, udt FROM $keyspace.udt_codec_default_name_test" ) .flatMap(readOpt[NameTestData](_)) } yield assertTrue(result.contains(nameTestData)) @@ -76,7 +76,7 @@ object UdtReadsSpec extends CassandraSpecUtils { session <- ZIO.service[Session] result <- session .selectFirst( - s"select udt, id FROM $keyspace.udt_reads_default_name_test" + s"select udt, id FROM $keyspace.udt_codec_default_name_test" ) .flatMap(readOpt[NameTestData](_)) } yield assertTrue(result.contains(nameTestData)) @@ -86,7 +86,7 @@ object UdtReadsSpec extends CassandraSpecUtils { session <- ZIO.service[Session] result <- session .selectFirst( - s"select id, udt FROM $keyspace.udt_reads_snake_name_test" + s"select id, udt FROM $keyspace.udt_codec_snake_name_test" ) .flatMap(readOpt[NameTestData](_)) } yield assertTrue(result.contains(nameTestData)) @@ -96,7 +96,7 @@ object UdtReadsSpec extends CassandraSpecUtils { session <- ZIO.service[Session] result <- session .selectFirst( - s"select udt, id FROM $keyspace.udt_reads_snake_name_test" + s"select udt, id FROM $keyspace.udt_codec_snake_name_test" ) .flatMap(readOpt[NameTestData](_)) } yield assertTrue(result.contains(nameTestData)) diff --git a/src/it/scala/zio/cassandra/session/cql/codec/UdtWritesSpec.scala b/src/it/scala/zio/cassandra/session/cql/codec/UdtWritesSpec.scala new file mode 100644 index 0000000..94463cc --- /dev/null +++ b/src/it/scala/zio/cassandra/session/cql/codec/UdtWritesSpec.scala @@ -0,0 +1,34 @@ +package zio.cassandra.session.cql.codec + +import zio.cassandra.session.CassandraSpecUtils +import zio.cassandra.session.cql.CqlStringContext +import zio.cassandra.session.cql.unsafe.lift +import zio.test._ + +object UdtWritesSpec extends CassandraSpecUtils { + + final case class Udt(ALLUPPER: String, alllower: String, someName: String, someLongName: String) + + final case class Data(id: Long, udt: Udt) + + private val data = + Data(0, Udt("ALL-UPPER", "all-lower", "some-name", "some-long-name")) + + val writesTests = suite("UdtWrites")( + testM("should write names as is") { + implicit val configuration: Configuration = Configuration(identity(_)) + + val query = + cql"insert into ${lift(keyspace)}.udt_codec_default_name_test(id, udt) values (${data.id}, ${data.udt})".execute + + query.as(assertCompletes) + }, + testM("should write names transformed to snake_case") { + val query = + cql"insert into ${lift(keyspace)}.udt_codec_snake_name_test(id, udt) values (${data.id}, ${data.udt})".execute + + query.as(assertCompletes) + } + ) + +} diff --git a/src/main/scala/zio/cassandra/session/cql/codec/UdtWrites.scala b/src/main/scala/zio/cassandra/session/cql/codec/UdtWrites.scala index d2fc861..bc8c1a7 100644 --- a/src/main/scala/zio/cassandra/session/cql/codec/UdtWrites.scala +++ b/src/main/scala/zio/cassandra/session/cql/codec/UdtWrites.scala @@ -40,19 +40,21 @@ trait UdtWritesInstances1 { implicit val hNilUdtWrites: UdtWrites[HNil] = instance((_, udtValue) => udtValue) implicit def hConsUdtWrites[K <: Symbol, H, T <: HList](implicit + configuration: Configuration, hWrites: Lazy[CellWrites[H]], tWrites: UdtWrites[T], fieldNameW: Witness.Aux[K] ): UdtWrites[FieldType[K, H] :: T] = instance { (t, udtValue) => - val fieldName = fieldNameW.value.name + val fieldName = configuration.transformFieldNames(fieldNameW.value.name) val hType = udtValue.getType(fieldName) val hBytes = hWrites.value.write(t.head, udtValue.protocolVersion(), hType) - val valueWithH = udtValue.setBytesUnsafe(fieldNameW.value.name, hBytes) + val valueWithH = udtValue.setBytesUnsafe(fieldName, hBytes) tWrites.write(t.tail, valueWithH) } implicit def genericUdtWrites[T, Repr](implicit + configuration: Configuration, gen: LabelledGeneric.Aux[T, Repr], writes: Lazy[UdtWrites[Repr]] ): UdtWrites[T] =