I am programming in Objective-C. I am using Apache Avro for data serialization.
My avro schema is this:
{
"name": "School",
"type":"record",
"fields":[
{
"name":"Employees",
"type":["null", {"type": "array",
"items":{
"name":"Teacher",
"type":"record",
"fields":[
{"name":"name", "type":"string"}
{"name":"age", "type":"int"}
]
}
}
],
"default":null
}
]
}
In my Objective-C code, I have an Array of Teacher
objects, each teacher object contains value of name
& age
.
I want to write the teacher array data to file using Avro with the schema showing above. I am mainly concern about how to write data to the Employees
array defined in above schema.
Here is my code (I have to use C style code to do it, I follow the Avro C documentation):
// I don't show this function, it constructs the a `avro_value_t` based on the schema. No problem here.
avro_value_t school = [self constructSchoolValueForSchema];
// get "Employees" field
avro_value_t employees;
avro_value_get_by_name(school, "employees", &employees, 0);
int idx = 0;
for (Teacher *teacher in teacherArray) {
// get name and age
NSString *name = teacher.name;
int age = teacher.age;
// set value to avro data type.
// here 'unionField' is the field of 'Employees', it is a Avro union type which is either null or an array as defined in schema above
avro_value_t field, unionField;
avro_value_set_branch(&employees, 1, &unionField);
// based on documentation, I should use 'avro_value_append'
avro_value_append(&employees, name, idx);
// I get confused here!!!!
// in above line of code, I append 'name' to 'employees',
//which looks not correct,
// because the 'Employees' array is an array of 'Teacher', not arrary of 'name'
// What is the correct way to add teacher to 'employees' ?
idx ++;
}
The question I want to ask is actually in the code comment above.
I am following that Avro C documentation, but I get lost how can I add each teacher
to employees
? In my above code, I only added each teacher's name
to the employees
array.
I think there are two things wrong with your code, but I am not familiar with Avro, so I can't guarantee one of them. I just quickly peeked at the documentation you linked and here's how I understood avro_value_append
:
It creates a new element, i.e. Teacher and returns that via the reference in the second parameter (so it returns-by-reference). My guess is that you then need to use the other avro...
methods to fill that element (i.e. set the teacher's name and so forth). In the end, do this:
avro_value_t teacher;
size_t idx;
avro_value_append(&employees, &teacher, &idx); // note that idx is also returned by reference and now contains the new elements index
I'm not sure if you set up employees correctly, btw, I didn't have the time to look into that.
The second problem will arise with your usage of name
at some point. I assume Avro expects C strings, but you're using an NSString
here. You'll have to use the getCString:maxLength:encoding:
method on it to fill a prepared buffer to create a C string that you can pass around within Avro. You can probably also use UTF8String
, but read up its documentation: You'll likely have to copy the memory (memcpy
shenanigans), otherwise your Avro container will get its data swiped away from under its feet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With