From a20e53da1160857a5c25fd597133b07f0a136f5e Mon Sep 17 00:00:00 2001 From: sksamuel Date: Sat, 13 Apr 2024 20:25:50 -0500 Subject: [PATCH] Added DataClassWriter --- build.gradle.kts | 9 ++- centurion-avro/build.gradle.kts | 2 +- .../com/sksamuel/centurion/avro/extractors.kt | 16 ++--- .../avro/generation/DataClassGenerator.kt | 60 +++++++++++++++++++ settings.gradle.kts | 10 +--- 5 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/generation/DataClassGenerator.kt diff --git a/build.gradle.kts b/build.gradle.kts index 7bfd582..3507aa2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,8 +25,9 @@ allprojects { version = Ci.version java { - this.sourceCompatibility = JavaVersion.VERSION_1_8 - this.targetCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_11 + withSourcesJar() } repositories { @@ -49,6 +50,10 @@ allprojects { } } + kotlin { + target { this. } + } + tasks.withType { kotlinOptions.jvmTarget = "1.8" } diff --git a/centurion-avro/build.gradle.kts b/centurion-avro/build.gradle.kts index 64b2241..2b2ec15 100644 --- a/centurion-avro/build.gradle.kts +++ b/centurion-avro/build.gradle.kts @@ -1,6 +1,6 @@ dependencies { api(project(Projects.schemas)) - implementation("org.apache.avro:avro:1.10.2") + implementation("org.apache.avro:avro:1.11.3") } apply("../publish.gradle.kts") diff --git a/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/extractors.kt b/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/extractors.kt index a1ec865..c724ca1 100644 --- a/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/extractors.kt +++ b/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/extractors.kt @@ -12,7 +12,7 @@ object RequiredStringExtractor : Extractor { return when (val value = record.get(key)) { is String -> value is Utf8 -> value.toString() - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -23,7 +23,7 @@ object OptionalStringExtractor : Extractor { null -> null is String -> value is Utf8 -> value.toString() - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -32,7 +32,7 @@ object RequiredDoubleExtractor : Extractor { override fun extract(record: GenericRecord, key: String): Double { return when (val value = record.get(key)) { is Double -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -42,7 +42,7 @@ object OptionalDoubleExtractor : Extractor { return when (val value = record.get(key)) { null -> null is Double -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -51,7 +51,7 @@ object RequiredLongExtractor : Extractor { override fun extract(record: GenericRecord, key: String): Long { return when (val value = record.get(key)) { is Long -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -61,7 +61,7 @@ object OptionalLongExtractor : Extractor { return when (val value = record.get(key)) { null -> null is Long -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -70,7 +70,7 @@ object RequiredIntExtractor : Extractor { override fun extract(record: GenericRecord, key: String): Int { return when (val value = record.get(key)) { is Int -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } @@ -80,7 +80,7 @@ object OptionalIntExtractor : Extractor { return when (val value = record.get(key)) { null -> null is Int -> value - else -> error("Unknown type $value for key $key") + else -> error("Unsupported type $value for key $key") } } } diff --git a/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/generation/DataClassGenerator.kt b/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/generation/DataClassGenerator.kt new file mode 100644 index 0000000..ab2a84d --- /dev/null +++ b/centurion-avro/src/main/kotlin/com/sksamuel/centurion/avro/generation/DataClassGenerator.kt @@ -0,0 +1,60 @@ +package com.sksamuel.centurion.avro.generation + +import org.apache.avro.Schema + +/** + * Generates a data class for a given schema. + */ +class DataClassGenerator { + + fun generate(schema: Schema): DataClass { + require(schema.type == Schema.Type.RECORD) { "Type must be a record in order to generate a data class" } + val members = schema.fields.map { member(it) } + return DataClass(schema.namespace, schema.name, members) + } + + fun member(field: Schema.Field): Member { + val type = when (field.schema().type) { + Schema.Type.RECORD -> Type.RecordType(field.schema().namespace, field.schema().name) + Schema.Type.STRING -> Type.StringType + Schema.Type.INT -> Type.IntType + Schema.Type.LONG -> Type.LongType + Schema.Type.FLOAT -> Type.FloatType + Schema.Type.DOUBLE -> Type.DoubleType + Schema.Type.BOOLEAN -> Type.BooleanType + else -> error("Invalid code path") + } + return Member(field.name(), type) + } +} + +/** + * Creates a string representation of a data class. + */ +object DataClassWriter { + fun write(ds: DataClass): String { + return buildString { + appendLine("package ${ds.packageName}") + appendLine() + appendLine("data class ${ds.className}(") + appendLine(")") + } + } +} + +/** + * Models a data class. + */ +data class DataClass(val packageName: String, val className: String, val members: List) + +sealed interface Type { + data class RecordType(val packageName: String, val className: String) : Type + object BooleanType : Type + object StringType : Type + object IntType : Type + object LongType : Type + object FloatType : Type + object DoubleType : Type +} + +data class Member(val name: String, val type: Type) diff --git a/settings.gradle.kts b/settings.gradle.kts index e6e9899..e365b8b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,12 +4,8 @@ pluginManagement { repositories { mavenLocal() mavenCentral() - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots/") - } - maven { - url = uri("https://plugins.gradle.org/m2/") - } + maven("https://oss.sonatype.org/content/repositories/snapshots/") + maven("https://plugins.gradle.org/m2/") } } @@ -18,6 +14,6 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") include("centurion-arrow") include("centurion-avro") -include("centurion-schemas") include("centurion-orc") include("centurion-parquet") +include("centurion-schemas")