嘿 avro 用户和专家,
我想使用 avro logicalType,意味着自己创建一些 - 而不仅仅是使用内置的。
问题是如何让编译器从模式生成代码以使用我自己创建的代码。
我创建了我的架构(相关部分(:
{
"name": "street",
"type": {
"type": "string",
"logicalType": "custom-street"
},
"doc": "Street format ending with house number"
}
(当然还有创建的类型和转换,请参阅 https://github.com/markush81/avro-examples(
而且我现在不知道如何配置编译器以使用它。
我通过 gradle 插件使用编译器(但我想这首先没有任何区别(
plugins {
id 'com.commercehub.gradle.plugin.avro' version '0.14.2'
}
avro {
enableDecimalLogicalType = true //enable built-in decimal type
}
感谢您的任何提示(或解决方法(。
PS:当然,我知道如何操作生成的类来支持我的逻辑类型(参见:https://github.com/markush81/avro-examples/tree/master/src/main/manual(,但这意味着我永远无法从我的模式定义中重新编译。
在 avro 代码 1.8.2 中搜索了很多之后,我得出的结论是,目前编译器工具不支持用于代码生成的自定义逻辑类型。
如果我们看一下record.vm
速度模板
#if ($this.hasLogicalTypeField($schema))
protected static final org.apache.avro.data.TimeConversions.DateConversion DATE_CONVERSION = new org.apache.avro.data.TimeConversions.DateConversion();
protected static final org.apache.avro.data.TimeConversions.TimeConversion TIME_CONVERSION = new org.apache.avro.data.TimeConversions.TimeConversion();
protected static final org.apache.avro.data.TimeConversions.TimestampConversion TIMESTAMP_CONVERSION = new org.apache.avro.data.TimeConversions.TimestampConversion();
protected static final org.apache.avro.Conversions.DecimalConversion DECIMAL_CONVERSION = new org.apache.avro.Conversions.DecimalConversion();
private static final org.apache.avro.Conversion<?>[] conversions = new org.apache.avro.Conversion<?>[] {
#foreach ($field in $schema.getFields())
${this.conversionInstance($field.schema())},
#end
null
};
@Override
public org.apache.avro.Conversion<?> getConversion(int field) {
return conversions[field];
}
#end
只添加了四个转换,由 Avro 本身提供。
另一件值得一看的作品是org.apache.avro.compiler.specific.SpecificCompiler
public String conversionInstance(Schema schema) {
if (schema == null || schema.getLogicalType() == null) {
return "null";
}
if (LogicalTypes.date().equals(schema.getLogicalType())) {
return "DATE_CONVERSION";
} else if (LogicalTypes.timeMillis().equals(schema.getLogicalType())) {
return "TIME_CONVERSION";
} else if (LogicalTypes.timestampMillis().equals(schema.getLogicalType())) {
return "TIMESTAMP_CONVERSION";
} else if (LogicalTypes.Decimal.class.equals(schema.getLogicalType().getClass())) {
return enableDecimalLogicalType ? "DECIMAL_CONVERSION" : "null";
}
return "null";
}
也没有可以添加自定义逻辑类型的部分。
从 Avro 1.9.x 开始,现在可以注册自定义logicalType
和conversion
.
重点是写作
- 逻辑类型
- 逻辑类型工厂
- 转换
使用maven 和 gradle,还支持使用 avro 架构中的自定义类型生成代码。请参阅 https://github.com/markush81/avro-examples 中的示例。
Gradle 插件配置
plugins {
id 'com.commercehub.gradle.plugin.avro' version '0.18.0'
}
avro {
enableDecimalLogicalType = true
dateTimeLogicalType = "JSR310"
stringType = "CharSequence"
outputCharacterEncoding = "UTF-8"
logicalTypeFactory("street", de.mh.examples.avro.StreetLogicalTypeFactory)
customConversion(de.mh.examples.avro.StreetConversion)
}