如何在 avro-c 中使用数组作为 map 的值
how to use array as value of map in avro-c
我怎样才能得到一个包含数组值的地图?
我使用 avro1.7.7,我的架构是这样的:
{
"type":"map",
"values":{
"type":"array",
"items":"int"
}
}
我的程序是这样的:
main.c
/*
* File: main.c
* Author: zwlin
*
* Created on 2016年4月21日, 下午5:16
*/
#include <stdio.h>
#include <stdarg.h>
#include <avro.h>
#define iout(i); sout("%d",i);
#define cout(c); sout("%c",c);
#define lout(l); sout("%ld",l);
#define piout(str,i); sout("%s:%d",str,i);
#define psout(str,s); sout("%s:%s",str,s);
#define pcout(str,c); sout("%s:%c",str,c);
#define plout(str,l);sout("%s,%l",str,l);
//for output
void sout(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
fprintf(stdout, "\n");
va_end(args);
}
int main() {
int res, i, j, k;
avro_schema_t schema;
avro_datum_t rec;
//schema
avro_schema_t int_array_schema = avro_schema_array(avro_schema_int());
avro_schema_t int_map_schema = avro_schema_map(int_array_schema);
avro_schema_t int_union_schema = avro_schema_union();
avro_schema_union_append(int_union_schema, int_map_schema);
avro_schema_union_append(int_union_schema, avro_schema_null());
//choose schema
// schema = int_array_schema;
schema = int_map_schema;
// schema = int_union_schema;
//print schema
char schemaPrintBuf [1024];
avro_writer_t jswriter = avro_writer_memory(schemaPrintBuf, 1024);
avro_schema_to_json(schema, jswriter);
psout("schema", schemaPrintBuf);
//data
int intry[] = {9, 8, 7, 6, 5, 4, 3};
avro_datum_t int_array = avro_array(int_array_schema);
for (i = 0; i < 7; ++i) {
avro_datum_t vt = avro_int32(intry[i]);
res = avro_array_append_datum(int_array, vt);
avro_datum_decref(vt);
}
avro_datum_t int_map = avro_map(int_map_schema);
res = avro_map_set(int_map, "intarray", int_array);
avro_datum_decref(int_array);
avro_datum_t int_a_union_datum = avro_union(int_union_schema, 0, int_map);
//choose data
// rec = int_array;
rec = int_map;
// rec = int_a_union_datum;
//print data detail
sout("");
char * json;
sout("rec:");
avro_datum_to_json(rec, 0, &json);
sout(json);
//serialize
char buf[1024];
avro_writer_t writer = avro_writer_memory(buf, 1024);
res = avro_write_data(writer, schema, rec);
if (res) {
psout("write result", avro_strerror());
}
long len = avro_size_data(writer, schema, rec);
piout("data len", len);
//read
avro_reader_t reader = avro_reader_memory(buf, 1024);
avro_datum_t rslt;
res = avro_read_data(reader, schema, schema, &rslt);
if (res) {
psout("read error ", avro_strerror());
}
//read data
sout("");
sout("rslt:");
avro_datum_to_json(rslt, 0, &json);
sout(json);
return 0;
}
这是我的目标模式:avro_schema_t 模式;
这是我的数据:avro_datum_t rec;
在//choose schema
和//choose data
部分,
如果schema = int_array_schema
和rec = int_array
,
输出是这样的:
int_arry_schema output picture
如果schema = int_map_schema
和rec = int_map
,
输出是这样的:
int_map_schema output picture
段错误出现在这里:res = avro_write_data(writer, schema, rec);
.
那么,我怎样才能拥有一个包含数组值的地图?
你似乎没有做错任何与代码相关的事情;但是看起来自从项目转移到 'generic value' 格式并为新的 API 实现了遗留包装器后,这似乎是向后兼容性的一个错误。
如果您从您在代码中构建的 json 重新生成架构,它会起作用,这似乎表明功能回归:
所以在这里,如果我们生成一个新的架构副本:
psout("schema", schemaPrintBuf);
avro_schema_t from_json;
if (!avro_schema_from_json_literal(schemaPrintBuf, &from_json)) {
fprintf(stderr, "Cannot convert from json literal: %s", avro_strerror());
exit(1);
}
// then in the write:
res = avro_write_data(writer, from_json, rec);
它不再崩溃 - 这只是替换了那个单一的模式引用 - 如果你在重新阅读时留下对模式的其他引用它看起来像它工作。
或者,因为您构建的 avro_datum_t
基于已知的、手动构建的模式,您可以禁用编写器验证,这似乎是崩溃的根源:
res = avro_write_data(writer, NULL, rec);
在这种情况下不会崩溃 - 在这种情况下可能是架构验证有些复杂。
我怎样才能得到一个包含数组值的地图?
我使用 avro1.7.7,我的架构是这样的:
{
"type":"map",
"values":{
"type":"array",
"items":"int"
}
}
我的程序是这样的:
main.c
/*
* File: main.c
* Author: zwlin
*
* Created on 2016年4月21日, 下午5:16
*/
#include <stdio.h>
#include <stdarg.h>
#include <avro.h>
#define iout(i); sout("%d",i);
#define cout(c); sout("%c",c);
#define lout(l); sout("%ld",l);
#define piout(str,i); sout("%s:%d",str,i);
#define psout(str,s); sout("%s:%s",str,s);
#define pcout(str,c); sout("%s:%c",str,c);
#define plout(str,l);sout("%s,%l",str,l);
//for output
void sout(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
fprintf(stdout, "\n");
va_end(args);
}
int main() {
int res, i, j, k;
avro_schema_t schema;
avro_datum_t rec;
//schema
avro_schema_t int_array_schema = avro_schema_array(avro_schema_int());
avro_schema_t int_map_schema = avro_schema_map(int_array_schema);
avro_schema_t int_union_schema = avro_schema_union();
avro_schema_union_append(int_union_schema, int_map_schema);
avro_schema_union_append(int_union_schema, avro_schema_null());
//choose schema
// schema = int_array_schema;
schema = int_map_schema;
// schema = int_union_schema;
//print schema
char schemaPrintBuf [1024];
avro_writer_t jswriter = avro_writer_memory(schemaPrintBuf, 1024);
avro_schema_to_json(schema, jswriter);
psout("schema", schemaPrintBuf);
//data
int intry[] = {9, 8, 7, 6, 5, 4, 3};
avro_datum_t int_array = avro_array(int_array_schema);
for (i = 0; i < 7; ++i) {
avro_datum_t vt = avro_int32(intry[i]);
res = avro_array_append_datum(int_array, vt);
avro_datum_decref(vt);
}
avro_datum_t int_map = avro_map(int_map_schema);
res = avro_map_set(int_map, "intarray", int_array);
avro_datum_decref(int_array);
avro_datum_t int_a_union_datum = avro_union(int_union_schema, 0, int_map);
//choose data
// rec = int_array;
rec = int_map;
// rec = int_a_union_datum;
//print data detail
sout("");
char * json;
sout("rec:");
avro_datum_to_json(rec, 0, &json);
sout(json);
//serialize
char buf[1024];
avro_writer_t writer = avro_writer_memory(buf, 1024);
res = avro_write_data(writer, schema, rec);
if (res) {
psout("write result", avro_strerror());
}
long len = avro_size_data(writer, schema, rec);
piout("data len", len);
//read
avro_reader_t reader = avro_reader_memory(buf, 1024);
avro_datum_t rslt;
res = avro_read_data(reader, schema, schema, &rslt);
if (res) {
psout("read error ", avro_strerror());
}
//read data
sout("");
sout("rslt:");
avro_datum_to_json(rslt, 0, &json);
sout(json);
return 0;
}
这是我的目标模式:avro_schema_t 模式;
这是我的数据:avro_datum_t rec;
在//choose schema
和//choose data
部分,
如果schema = int_array_schema
和rec = int_array
,
输出是这样的:
int_arry_schema output picture
如果schema = int_map_schema
和rec = int_map
,
输出是这样的:
int_map_schema output picture
段错误出现在这里:res = avro_write_data(writer, schema, rec);
.
那么,我怎样才能拥有一个包含数组值的地图?
你似乎没有做错任何与代码相关的事情;但是看起来自从项目转移到 'generic value' 格式并为新的 API 实现了遗留包装器后,这似乎是向后兼容性的一个错误。
如果您从您在代码中构建的 json 重新生成架构,它会起作用,这似乎表明功能回归:
所以在这里,如果我们生成一个新的架构副本:
psout("schema", schemaPrintBuf);
avro_schema_t from_json;
if (!avro_schema_from_json_literal(schemaPrintBuf, &from_json)) {
fprintf(stderr, "Cannot convert from json literal: %s", avro_strerror());
exit(1);
}
// then in the write:
res = avro_write_data(writer, from_json, rec);
它不再崩溃 - 这只是替换了那个单一的模式引用 - 如果你在重新阅读时留下对模式的其他引用它看起来像它工作。
或者,因为您构建的 avro_datum_t
基于已知的、手动构建的模式,您可以禁用编写器验证,这似乎是崩溃的根源:
res = avro_write_data(writer, NULL, rec);
在这种情况下不会崩溃 - 在这种情况下可能是架构验证有些复杂。