You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@avro.apache.org by Douglas Creager <do...@creagertino.net> on 2013/06/06 22:52:35 UTC

Re: Avro C value and records

Hi Grisha!

> My apologies for emailing you directly - I didn't see much Avro C
> discussion on the users list, if you'd prefer, I'd be happy to post this
> to the list.

Not a problem.  There are Avro C questions on the users list from time
to time, but I think the lack of traffic is just because fewer people
are using the C bindings.  I'm CCing the users list so that the question
and answer can be in the archives.  Feel free to send any followups to
the list.  (There are a couple of other C developers who can step in to
answer questions when I'm away, for instance.)

> I'm tinkering with Avro C, and not clear on whether it is possible to
> create a record using the avro_value interface. The docs suggest that
> avro_datum is obsolete, yet the example uses datum to create a record,
> and there are no setters in the value interface for records.
> 
> If I want to create records, is the datum interface the way to go for
> the time being?

With the old datum API, you could create an empty record value and then
add fields to it using avro_record_set.  You can't use that same idiom
with the new value API, but the value API does work with records.

The key with the value API is that you always have to start with a
schema (as an avro_schema_t instance), and then create a "value
implementation" for that schema.  You're almost always going to use the
built-in generic value implementation.  Once you have that, you can
allocate an actual value.  And from there, you *get* the fields that
were created for you, based on what's in the schema.  (That's the
reverse of what happened in the datum API, where you had to construct
the record yourself.)

So end result, you'll usually see something like:

  avro_schema_t  schema = /* from somewhere */;
  avro_value_iface_t  *iface =
      avro_generic_class_from_schema(schema);
  avro_value_t  value;
  avro_value_t  field;

  avro_generic_value_new(iface, &value);
  avro_value_get_by_name(&value, "age", &field, NULL);
  avro_value_set_int(&field, 31);

  avro_value_decref(&value);
  avro_value_iface_decref(iface);
  avro_schema_decref(schema);

That's an example of creating a record, and pulling out an `age` field
(which should be an `int`) from that record.  So again, with the value
API, you always get record fields and union branches; you can only set
the value of a scalar.

(Also note that `avro_value_get_by_name` is also the function you use to
extract a particular key from an Avro map — it's used to get any child
value that can be identified by a string.)

Hope that helps!

cheers
–doug