You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by br...@apache.org on 2011/01/11 15:56:52 UTC
svn commit: r1057676 - in /avro/trunk: CHANGES.txt lang/c/src/avro.h
lang/c/src/datum.c lang/c/src/datum.h lang/c/src/schema.c
lang/c/src/schema.h lang/c/tests/test_avro_data.c
lang/c/tests/test_avro_schema.c
Author: brucem
Date: Tue Jan 11 14:56:51 2011
New Revision: 1057676
URL: http://svn.apache.org/viewvc?rev=1057676&view=rev
Log:
AVRO-727. This patchs several missing accessor and mutator methods for Avro
schemas and data instances.
For the most part, their definitions are straightforward. Some notes for the
more interesting cases:
- You can create the appropriate avro_datum_t instance for an
arbitrary schema with the new avro_datum_from_schema() function.
For records, this includes creating a datum instance for each of the
record's fields. Arrays and maps are initially created empty, while
a union is created with none of its branches initially selected.
This prevents the function from going into an endless loop for
recursive schemas.
- The active branch of a union can now be changed. If the desired
branch is already active, this has no result. Otherwise, a new
avro_datum_t is created for the new branch.
- Map values can now be accessed by index as well as by key. The
index of a map entry is based on the order that it was added to the
map.
- Enum values can be retrieved or set either by integer value or by
symbol name.
A couple of the new functions need access to the schema of a datum in
order to work. These functions take in the schema instance as an extra
parameter. A better solution might be to include a reference to a
schema object in each avro_datum_t instance.
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/c/src/avro.h
avro/trunk/lang/c/src/datum.c
avro/trunk/lang/c/src/datum.h
avro/trunk/lang/c/src/schema.c
avro/trunk/lang/c/src/schema.h
avro/trunk/lang/c/tests/test_avro_data.c
avro/trunk/lang/c/tests/test_avro_schema.c
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Tue Jan 11 14:56:51 2011
@@ -94,6 +94,9 @@ Avro 1.5.0 (unreleased)
AVRO-630. C: Add size accessors for map and list data. (Douglas Creager
via brucem)
+ AVRO-727. C: Add many new accessor and mutator functions. (Douglas Creager
+ via brucem)
+
BUG FIXES
AVRO-675. C: Bytes and fixed setters don't update datum size.
Modified: avro/trunk/lang/c/src/avro.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/avro.h?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/src/avro.h (original)
+++ avro/trunk/lang/c/src/avro.h Tue Jan 11 14:56:51 2011
@@ -110,21 +110,38 @@ avro_schema_t avro_schema_null(void);
avro_schema_t avro_schema_record(const char *name, const char *space);
avro_schema_t avro_schema_record_field_get(const avro_schema_t
record, const char *field_name);
+const char *avro_schema_record_field_name(const avro_schema_t schema, int index);
+avro_schema_t avro_schema_record_field_get_by_index
+(const avro_schema_t record, int index);
int avro_schema_record_field_append(const avro_schema_t record,
const char *field_name,
const avro_schema_t type);
+size_t avro_schema_record_size(const avro_schema_t record);
avro_schema_t avro_schema_enum(const char *name);
+const char *avro_schema_enum_get(const avro_schema_t enump,
+ int index);
+int avro_schema_enum_get_by_name(const avro_schema_t enump,
+ const char *symbol_name);
int avro_schema_enum_symbol_append(const avro_schema_t
enump, const char *symbol);
avro_schema_t avro_schema_fixed(const char *name, const int64_t len);
+int64_t avro_schema_fixed_size(const avro_schema_t fixed);
+
avro_schema_t avro_schema_map(const avro_schema_t values);
+avro_schema_t avro_schema_map_values(avro_schema_t map);
+
avro_schema_t avro_schema_array(const avro_schema_t items);
+avro_schema_t avro_schema_array_items(avro_schema_t array);
avro_schema_t avro_schema_union(void);
int avro_schema_union_append(const avro_schema_t
union_schema, const avro_schema_t schema);
+avro_schema_t avro_schema_union_branch(avro_schema_t union_schema,
+ int branch_index);
+avro_schema_t avro_schema_union_branch_by_name
+(avro_schema_t union_schema, int *branch_index, const char *name);
avro_schema_t avro_schema_link(avro_schema_t schema);
@@ -198,6 +215,13 @@ avro_datum_t avro_map(void);
avro_datum_t avro_array(void);
avro_datum_t avro_union(int64_t discriminant, const avro_datum_t datum);
+/*
+ * Constructs a new avro_datum_t instance that's appropriate for holding
+ * values of the given schema.
+ */
+
+avro_datum_t avro_datum_from_schema(const avro_schema_t schema);
+
/* getters */
int avro_string_get(avro_datum_t datum, char **p);
int avro_bytes_get(avro_datum_t datum, char **bytes, int64_t * size);
@@ -207,15 +231,34 @@ int avro_float_get(avro_datum_t datum, f
int avro_double_get(avro_datum_t datum, double *d);
int avro_boolean_get(avro_datum_t datum, int8_t * i);
+int avro_enum_get(const avro_datum_t datum);
+const char *avro_enum_get_name(const avro_datum_t datum,
+ const avro_schema_t schema);
int avro_fixed_get(avro_datum_t datum, char **bytes, int64_t * size);
int avro_record_get(const avro_datum_t record, const char *field_name,
avro_datum_t * value);
int avro_map_get(const avro_datum_t datum, const char *key,
avro_datum_t * value);
+/*
+ * For maps, the "index" for each entry is based on the order that they
+ * were added to the map.
+ */
+int avro_map_get_key(const avro_datum_t datum, int index,
+ const char **key);
size_t avro_map_size(const avro_datum_t datum);
int avro_array_get(const avro_datum_t datum, int64_t index, avro_datum_t * value);
size_t avro_array_size(const avro_datum_t datum);
+/*
+ * These accessors allow you to query the current branch of a union
+ * value, returning either the branch's discriminant value or the
+ * avro_datum_t of the branch. A union value can be uninitialized, in
+ * which case the discriminant will be -1 and the datum NULL.
+ */
+
+int64_t avro_union_discriminant(const avro_datum_t datum);
+avro_datum_t avro_union_current_branch(avro_datum_t datum);
+
/* setters */
int avro_string_set(avro_datum_t datum, const char *p);
int avro_givestring_set(avro_datum_t datum, const char *p);
@@ -233,18 +276,37 @@ int avro_float_set(avro_datum_t datum, c
int avro_double_set(avro_datum_t datum, const double d);
int avro_boolean_set(avro_datum_t datum, const int8_t i);
+int avro_enum_set(avro_datum_t datum, const int symbol_value);
+int avro_enum_set_name(avro_datum_t datum, avro_schema_t schema,
+ const char *symbol_name);
int avro_fixed_set(avro_datum_t datum, const char *bytes, const int64_t size);
int avro_givefixed_set(avro_datum_t datum, const char *bytes,
const int64_t size);
int avro_wrapfixed_set(avro_datum_t datum, const char *bytes,
const int64_t size);
-int avro_record_set(const avro_datum_t record, const char *field_name,
- const avro_datum_t value);
-int avro_map_set(const avro_datum_t map, const char *key,
- const avro_datum_t value);
-int avro_array_append_datum(const avro_datum_t array_datum,
- const avro_datum_t datum);
+int avro_record_set(avro_datum_t record, const char *field_name,
+ avro_datum_t value);
+int avro_map_set(avro_datum_t map, const char *key,
+ avro_datum_t value);
+int avro_array_append_datum(avro_datum_t array_datum,
+ avro_datum_t datum);
+
+/*
+ * This function selects the active branch of a union value, and can be
+ * safely called on an existing union to change the current branch. If
+ * the branch changes, we'll automatically construct a new avro_datum_t
+ * for the new branch's schema type. If the desired branch is already
+ * the active branch of the union, we'll leave the existing datum
+ * instance as-is. The branch datum will be placed into the "branch"
+ * parameter, regardless of whether we have to create a new datum
+ * instance or not.
+ */
+
+int avro_union_set_discriminant(avro_datum_t unionp,
+ avro_schema_t schema,
+ int discriminant,
+ avro_datum_t *branch);
/* reference counting */
avro_datum_t avro_datum_incref(avro_datum_t value);
Modified: avro/trunk/lang/c/src/datum.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datum.c?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datum.c (original)
+++ avro/trunk/lang/c/src/datum.c Tue Jan 11 14:56:51 2011
@@ -398,6 +398,59 @@ avro_datum_t avro_union(int64_t discrimi
return &datum->obj;
}
+int64_t avro_union_discriminant(const avro_datum_t datum)
+{
+ return avro_datum_to_union(datum)->discriminant;
+}
+
+avro_datum_t avro_union_current_branch(avro_datum_t datum)
+{
+ return avro_datum_to_union(datum)->value;
+}
+
+int avro_union_set_discriminant(avro_datum_t datum,
+ avro_schema_t schema,
+ int discriminant,
+ avro_datum_t *branch)
+{
+ if (!is_avro_union(datum) || !is_avro_union(schema)) {
+ return EINVAL;
+ }
+
+ struct avro_union_datum_t *unionp =
+ avro_datum_to_union(datum);
+
+ avro_schema_t branch_schema =
+ avro_schema_union_branch(schema, discriminant);
+
+ if (branch_schema == NULL) {
+ // That branch doesn't exist!
+ return EINVAL;
+ }
+
+ if (unionp->discriminant != discriminant) {
+ // If we're changing the branch, throw away any old
+ // branch value.
+ if (unionp->value != NULL) {
+ avro_datum_decref(unionp->value);
+ unionp->value = NULL;
+ }
+
+ unionp->discriminant = discriminant;
+ }
+
+ // Create a new branch value, if there isn't one already.
+ if (unionp->value == NULL) {
+ unionp->value = avro_datum_from_schema(branch_schema);
+ }
+
+ if (branch != NULL) {
+ *branch = unionp->value;
+ }
+
+ return 0;
+}
+
avro_datum_t avro_record(const char *name, const char *space)
{
struct avro_record_datum_t *datum =
@@ -460,7 +513,7 @@ avro_record_get(const avro_datum_t datum
}
int
-avro_record_set(const avro_datum_t datum, const char *field_name,
+avro_record_set(avro_datum_t datum, const char *field_name,
const avro_datum_t field_value)
{
char *key = (char *)field_name;
@@ -504,6 +557,42 @@ avro_datum_t avro_enum(const char *name,
return &datum->obj;
}
+int avro_enum_get(const avro_datum_t datum)
+{
+ return avro_datum_to_enum(datum)->value;
+}
+
+const char *avro_enum_get_name(const avro_datum_t datum,
+ const avro_schema_t schema)
+{
+ int value = avro_enum_get(datum);
+ return avro_schema_enum_get(schema, value);
+}
+
+int avro_enum_set(avro_datum_t datum, const int symbol_value)
+{
+ if (!is_avro_enum(datum)) {
+ return EINVAL;
+ }
+
+ avro_datum_to_enum(datum)->value = symbol_value;
+ return 0;
+}
+
+int avro_enum_set_name(avro_datum_t datum, avro_schema_t schema,
+ const char *symbol_name)
+{
+ if (!is_avro_enum(datum) || !is_avro_enum(schema)) {
+ return EINVAL;
+ }
+ int symbol_value = avro_schema_enum_get_by_name(schema, symbol_name);
+ if (symbol_value == -1) {
+ return EINVAL;
+ }
+ avro_datum_to_enum(datum)->value = symbol_value;
+ return 0;
+}
+
static avro_datum_t avro_fixed_private(const char *name, const char *bytes,
const int64_t size,
void (*fixed_free) (void *ptr))
@@ -616,6 +705,12 @@ avro_datum_t avro_map(void)
free(datum);
return NULL;
}
+ datum->keys_by_index = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
+ if (!datum->keys_by_index) {
+ st_free_table(datum->map);
+ free(datum);
+ return NULL;
+ }
avro_datum_init(&datum->obj, AVRO_MAP);
return &datum->obj;
@@ -649,8 +744,30 @@ avro_map_get(const avro_datum_t datum, c
return EINVAL;
}
+int avro_map_get_key(const avro_datum_t datum, int index,
+ const char **key)
+{
+ if (!(is_avro_datum(datum) && is_avro_map(datum) &&
+ index >= 0 && key)) {
+ return EINVAL;
+ }
+
+ union {
+ st_data_t data;
+ char *key;
+ } val;
+ struct avro_map_datum_t *map = avro_datum_to_map(datum);
+
+ if (st_lookup(map->keys_by_index, (st_data_t) index, &val.data)) {
+ *key = val.key;
+ return 0;
+ }
+
+ return EINVAL;
+}
+
int
-avro_map_set(const avro_datum_t datum, const char *key,
+avro_map_set(avro_datum_t datum, const char *key,
const avro_datum_t value)
{
char *save_key = (char *)key;
@@ -661,6 +778,8 @@ avro_map_set(const avro_datum_t datum, c
return EINVAL;
}
+ struct avro_map_datum_t *map = avro_datum_to_map(datum);
+
if (avro_map_get(datum, key, &old_datum) == 0) {
/* Overwriting an old value */
avro_datum_decref(old_datum);
@@ -670,10 +789,12 @@ avro_map_set(const avro_datum_t datum, c
if (!save_key) {
return ENOMEM;
}
+ int new_index = map->map->num_entries;
+ st_insert(map->keys_by_index, (st_data_t) new_index,
+ (st_data_t) save_key);
}
avro_datum_incref(value);
- st_insert(avro_datum_to_map(datum)->map, (st_data_t) save_key,
- (st_data_t) value);
+ st_insert(map->map, (st_data_t) save_key, (st_data_t) value);
return 0;
}
@@ -719,7 +840,7 @@ avro_array_size(const avro_datum_t datum
}
int
-avro_array_append_datum(const avro_datum_t array_datum,
+avro_array_append_datum(avro_datum_t array_datum,
const avro_datum_t datum)
{
struct avro_array_datum_t *array;
@@ -844,6 +965,7 @@ static void avro_datum_free(avro_datum_t
st_foreach(map->map, char_datum_free_foreach,
0);
st_free_table(map->map);
+ st_free_table(map->keys_by_index);
free(map);
}
break;
Modified: avro/trunk/lang/c/src/datum.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datum.h?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datum.h (original)
+++ avro/trunk/lang/c/src/datum.h Tue Jan 11 14:56:51 2011
@@ -70,6 +70,7 @@ struct avro_fixed_datum_t {
struct avro_map_datum_t {
struct avro_obj_t obj;
st_table *map;
+ st_table *keys_by_index;
};
struct avro_record_datum_t {
Modified: avro/trunk/lang/c/src/schema.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema.c?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema.c (original)
+++ avro/trunk/lang/c/src/schema.c Tue Jan 11 14:56:51 2011
@@ -163,6 +163,7 @@ static void avro_schema_free(avro_schema
st_foreach(unionp->branches, union_free_foreach,
0);
st_free_table(unionp->branches);
+ st_free_table(unionp->branches_byname);
free(unionp);
}
break;
@@ -290,6 +291,11 @@ avro_schema_t avro_schema_fixed(const ch
return &fixed->obj;
}
+int64_t avro_schema_fixed_size(const avro_schema_t fixed)
+{
+ return avro_schema_to_fixed(fixed)->size;
+}
+
avro_schema_t avro_schema_union(void)
{
struct avro_union_schema_t *schema =
@@ -302,6 +308,13 @@ avro_schema_t avro_schema_union(void)
free(schema);
return NULL;
}
+ schema->branches_byname =
+ st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
+ if (!schema->branches_byname) {
+ st_free_table(schema->branches);
+ free(schema);
+ return NULL;
+ }
avro_schema_init(&schema->obj, AVRO_UNION);
return &schema->obj;
@@ -316,12 +329,46 @@ avro_schema_union_append(const avro_sche
return EINVAL;
}
unionp = avro_schema_to_union(union_schema);
- st_insert(unionp->branches, unionp->branches->num_entries,
- (st_data_t) schema);
+ int new_index = unionp->branches->num_entries;
+ st_insert(unionp->branches, new_index, (st_data_t) schema);
+ const char *name = avro_schema_type_name(schema);
+ st_insert(unionp->branches_byname, (st_data_t) name,
+ (st_data_t) new_index);
avro_schema_incref(schema);
return 0;
}
+avro_schema_t avro_schema_union_branch(avro_schema_t unionp,
+ int branch_index)
+{
+ union {
+ st_data_t data;
+ avro_schema_t schema;
+ } val;
+ st_lookup(avro_schema_to_union(unionp)->branches,
+ branch_index, &val.data);
+ return val.schema;
+}
+
+avro_schema_t avro_schema_union_branch_by_name
+(avro_schema_t unionp, int *branch_index, const char *name)
+{
+ union {
+ st_data_t data;
+ int branch_index;
+ } val;
+
+ if (!st_lookup(avro_schema_to_union(unionp)->branches_byname,
+ (st_data_t) name, &val.data)) {
+ return NULL;
+ }
+
+ if (branch_index != NULL) {
+ *branch_index = val.branch_index;
+ }
+ return avro_schema_union_branch(unionp, val.branch_index);
+}
+
avro_schema_t avro_schema_array(const avro_schema_t items)
{
struct avro_array_schema_t *array =
@@ -334,6 +381,11 @@ avro_schema_t avro_schema_array(const av
return &array->obj;
}
+avro_schema_t avro_schema_array_items(avro_schema_t array)
+{
+ return avro_schema_to_array(array)->items;
+}
+
avro_schema_t avro_schema_map(const avro_schema_t values)
{
struct avro_map_schema_t *map =
@@ -346,6 +398,11 @@ avro_schema_t avro_schema_map(const avro
return &map->obj;
}
+avro_schema_t avro_schema_map_values(avro_schema_t map)
+{
+ return avro_schema_to_map(map)->values;
+}
+
avro_schema_t avro_schema_enum(const char *name)
{
struct avro_enum_schema_t *enump;
@@ -379,6 +436,32 @@ avro_schema_t avro_schema_enum(const cha
return &enump->obj;
}
+const char *avro_schema_enum_get(const avro_schema_t enump,
+ int index)
+{
+ union {
+ st_data_t data;
+ char *sym;
+ } val;
+ st_lookup(avro_schema_to_enum(enump)->symbols, index, &val.data);
+ return val.sym;
+}
+
+int avro_schema_enum_get_by_name(const avro_schema_t enump,
+ const char *symbol_name)
+{
+ union {
+ st_data_t data;
+ long idx;
+ } val;
+
+ return
+ (st_lookup(avro_schema_to_enum(enump)->symbols_byname,
+ (st_data_t) symbol_name, &val.data))?
+ val.idx:
+ -1;
+}
+
int
avro_schema_enum_symbol_append(const avro_schema_t enum_schema,
const char *symbol)
@@ -468,6 +551,44 @@ avro_schema_t avro_schema_record(const c
return &record->obj;
}
+size_t avro_schema_record_size(const avro_schema_t record)
+{
+ return avro_schema_to_record(record)->fields->num_entries;
+}
+
+avro_schema_t avro_schema_record_field_get(const avro_schema_t
+ record, const char *field_name)
+{
+ union {
+ st_data_t data;
+ struct avro_record_field_t *field;
+ } val;
+ st_lookup(avro_schema_to_record(record)->fields_byname,
+ (st_data_t) field_name, &val.data);
+ return val.field->type;
+}
+
+const char *avro_schema_record_field_name(const avro_schema_t schema, int index)
+{
+ union {
+ st_data_t data;
+ struct avro_record_field_t *field;
+ } val;
+ st_lookup(avro_schema_to_record(schema)->fields, index, &val.data);
+ return val.field->name;
+}
+
+avro_schema_t avro_schema_record_field_get_by_index
+(const avro_schema_t record, int index)
+{
+ union {
+ st_data_t data;
+ struct avro_record_field_t *field;
+ } val;
+ st_lookup(avro_schema_to_record(record)->fields, index, &val.data);
+ return val.field->type;
+}
+
static int
save_named_schemas(const char *name, avro_schema_t schema,
avro_schema_error_t * error)
@@ -1129,6 +1250,98 @@ const char *avro_schema_type_name(const
return NULL;
}
+avro_datum_t avro_datum_from_schema(const avro_schema_t schema)
+{
+ if (!is_avro_schema(schema)) {
+ return NULL;
+ }
+
+ switch (avro_typeof(schema)) {
+ case AVRO_STRING:
+ return avro_wrapstring("");
+
+ case AVRO_BYTES:
+ return avro_wrapbytes("", 0);
+
+ case AVRO_INT32:
+ return avro_int32(0);
+
+ case AVRO_INT64:
+ return avro_int64(0);
+
+ case AVRO_FLOAT:
+ return avro_float(0);
+
+ case AVRO_DOUBLE:
+ return avro_double(0);
+
+ case AVRO_BOOLEAN:
+ return avro_boolean(0);
+
+ case AVRO_NULL:
+ return avro_null();
+
+ case AVRO_RECORD:
+ {
+ const struct avro_record_schema_t *record_schema =
+ avro_schema_to_record(schema);
+
+ avro_datum_t rec =
+ avro_record(record_schema->name,
+ record_schema->space);
+
+ int i;
+ for (i = 0; i < record_schema->fields->num_entries; i++) {
+ union {
+ st_data_t data;
+ struct avro_record_field_t *field;
+ } val;
+ st_lookup(record_schema->fields, i, &val.data);
+
+ avro_datum_t field =
+ avro_datum_from_schema(val.field->type);
+ avro_record_set(rec, val.field->name, field);
+ avro_datum_decref(field);
+ }
+
+ return rec;
+ }
+
+ case AVRO_ENUM:
+ {
+ const struct avro_enum_schema_t *enum_schema =
+ avro_schema_to_enum(schema);
+ return avro_enum(enum_schema->name, 0);
+ }
+
+ case AVRO_FIXED:
+ {
+ const struct avro_fixed_schema_t *fixed_schema =
+ avro_schema_to_fixed(schema);
+ return avro_wrapfixed(fixed_schema->name, "", 0);
+ }
+
+ case AVRO_MAP:
+ return avro_map();
+
+ case AVRO_ARRAY:
+ return avro_array();
+
+ case AVRO_UNION:
+ return avro_union(-1, NULL);
+
+ case AVRO_LINK:
+ {
+ const struct avro_link_schema_t *link_schema =
+ avro_schema_to_link(schema);
+ return avro_datum_from_schema(link_schema->to);
+ }
+
+ default:
+ return NULL;
+ }
+}
+
/* simple helper for writing strings */
static int avro_write_str(avro_writer_t out, const char *str)
{
Modified: avro/trunk/lang/c/src/schema.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema.h?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema.h (original)
+++ avro/trunk/lang/c/src/schema.h Tue Jan 11 14:56:51 2011
@@ -57,6 +57,7 @@ struct avro_map_schema_t {
struct avro_union_schema_t {
struct avro_obj_t obj;
st_table *branches;
+ st_table *branches_byname;
};
struct avro_fixed_schema_t {
Modified: avro/trunk/lang/c/tests/test_avro_data.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_data.c?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_data.c (original)
+++ avro/trunk/lang/c/tests/test_avro_data.c Tue Jan 11 14:56:51 2011
@@ -258,7 +258,34 @@ static int test_enum(void)
avro_schema_enum_symbol_append(schema, "Ruby");
avro_schema_enum_symbol_append(schema, "Java");
+ if (avro_enum_get(datum) != AVRO_C) {
+ fprintf(stderr, "Unexpected enum value AVRO_C\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (strcmp(avro_enum_get_name(datum, schema), "C") != 0) {
+ fprintf(stderr, "Unexpected enum value name C\n");
+ exit(EXIT_FAILURE);
+ }
+
+ write_read_check(schema, NULL, datum, "enum");
+
+ avro_enum_set(datum, AVRO_CPP);
+ if (strcmp(avro_enum_get_name(datum, schema), "C++") != 0) {
+ fprintf(stderr, "Unexpected enum value name C++\n");
+ exit(EXIT_FAILURE);
+ }
+
+ write_read_check(schema, NULL, datum, "enum");
+
+ avro_enum_set_name(datum, schema, "Python");
+ if (avro_enum_get(datum) != AVRO_PYTHON) {
+ fprintf(stderr, "Unexpected enum value AVRO_PYTHON\n");
+ exit(EXIT_FAILURE);
+ }
+
write_read_check(schema, NULL, datum, "enum");
+
avro_datum_decref(datum);
avro_schema_decref(schema);
return 0;
@@ -305,7 +332,19 @@ static int test_map(void)
}
if (avro_array_size(datum) != 7) {
- fprintf(stderr, "Unexpected array size");
+ fprintf(stderr, "Unexpected map size\n");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_datum_t value;
+ const char *key;
+ avro_map_get_key(datum, 2, &key);
+ avro_map_get(datum, key, &value);
+ int64_t val;
+ avro_int64_get(value, &val);
+
+ if (val != 2) {
+ fprintf(stderr, "Unexpected map value 2\n");
exit(EXIT_FAILURE);
}
@@ -320,6 +359,8 @@ static int test_union(void)
avro_schema_t schema = avro_schema_union();
avro_datum_t union_datum;
avro_datum_t datum;
+ avro_datum_t union_datum1;
+ avro_datum_t datum1;
avro_schema_union_append(schema, avro_schema_string());
avro_schema_union_append(schema, avro_schema_int());
@@ -328,9 +369,29 @@ static int test_union(void)
datum = avro_wrapstring("Follow your bliss.");
union_datum = avro_union(0, datum);
+ if (avro_union_discriminant(union_datum) != 0) {
+ fprintf(stderr, "Unexpected union discriminant\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (avro_union_current_branch(union_datum) != datum) {
+ fprintf(stderr, "Unexpected union branch datum\n");
+ exit(EXIT_FAILURE);
+ }
+
+ union_datum1 = avro_datum_from_schema(schema);
+ avro_union_set_discriminant(union_datum1, schema, 0, &datum1);
+ avro_wrapstring_set(datum1, "Follow your bliss.");
+
+ if (!avro_datum_equal(datum, datum1)) {
+ fprintf(stderr, "Union values should be equal\n");
+ exit(EXIT_FAILURE);
+ }
+
write_read_check(schema, NULL, union_datum, "union");
avro_datum_decref(union_datum);
avro_datum_decref(datum);
+ avro_datum_decref(union_datum1);
avro_schema_decref(schema);
return 0;
}
Modified: avro/trunk/lang/c/tests/test_avro_schema.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_schema.c?rev=1057676&r1=1057675&r2=1057676&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_schema.c (original)
+++ avro/trunk/lang/c/tests/test_avro_schema.c Tue Jan 11 14:56:51 2011
@@ -18,6 +18,7 @@
#include "avro_private.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <dirent.h>
@@ -97,6 +98,132 @@ static void run_tests(char *dirpath, int
while (dent != NULL);
}
+static int test_array(void)
+{
+ avro_schema_t schema = avro_schema_array(avro_schema_int());
+
+ if (!avro_schema_equal
+ (avro_schema_array_items(schema), avro_schema_int())) {
+ fprintf(stderr, "Unexpected array items schema");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_decref(schema);
+ return 0;
+}
+
+static int test_enum(void)
+{
+ enum avro_languages {
+ AVRO_C,
+ AVRO_CPP,
+ AVRO_PYTHON,
+ AVRO_RUBY,
+ AVRO_JAVA
+ };
+ avro_schema_t schema = avro_schema_enum("language");
+
+ avro_schema_enum_symbol_append(schema, "C");
+ avro_schema_enum_symbol_append(schema, "C++");
+ avro_schema_enum_symbol_append(schema, "Python");
+ avro_schema_enum_symbol_append(schema, "Ruby");
+ avro_schema_enum_symbol_append(schema, "Java");
+
+ const char *symbol1 = avro_schema_enum_get(schema, 1);
+ if (strcmp(symbol1, "C++") != 0) {
+ fprintf(stderr, "Unexpected enum schema symbol\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (avro_schema_enum_get_by_name(schema, "C++") != 1) {
+ fprintf(stderr, "Unexpected enum schema index\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (avro_schema_enum_get_by_name(schema, "Haskell") != -1) {
+ fprintf(stderr, "Unexpected enum schema index\n");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_decref(schema);
+ return 0;
+}
+
+static int test_fixed(void)
+{
+ avro_schema_t schema = avro_schema_fixed("msg", 8);
+ if (avro_schema_fixed_size(schema) != 8) {
+ fprintf(stderr, "Unexpected fixed size\n");
+ exit(EXIT_FAILURE);
+ }
+ return 0;
+}
+
+static int test_map(void)
+{
+ avro_schema_t schema = avro_schema_map(avro_schema_long());
+
+ if (!avro_schema_equal
+ (avro_schema_map_values(schema), avro_schema_long())) {
+ fprintf(stderr, "Unexpected map values schema");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_decref(schema);
+ return 0;
+}
+
+static int test_record(void)
+{
+ avro_schema_t schema = avro_schema_record("person", NULL);
+
+ avro_schema_record_field_append(schema, "name", avro_schema_string());
+ avro_schema_record_field_append(schema, "age", avro_schema_int());
+
+ avro_schema_t name_field =
+ avro_schema_record_field_get(schema, "name");
+ if (!avro_schema_equal(name_field, avro_schema_string())) {
+ fprintf(stderr, "Unexpected name field\n");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_t field1 =
+ avro_schema_record_field_get_by_index(schema, 1);
+ if (!avro_schema_equal(field1, avro_schema_int())) {
+ fprintf(stderr, "Unexpected field 1\n");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_decref(schema);
+ return 0;
+}
+
+static int test_union(void)
+{
+ avro_schema_t schema = avro_schema_union();
+
+ avro_schema_union_append(schema, avro_schema_string());
+ avro_schema_union_append(schema, avro_schema_int());
+ avro_schema_union_append(schema, avro_schema_null());
+
+ if (!avro_schema_equal
+ (avro_schema_string(),
+ avro_schema_union_branch(schema, 0))) {
+ fprintf(stderr, "Unexpected union schema branch 0\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (!avro_schema_equal
+ (avro_schema_string(),
+ avro_schema_union_branch_by_name(schema, NULL, "string"))) {
+ fprintf(stderr, "Unexpected union schema branch \"string\"\n");
+ exit(EXIT_FAILURE);
+ }
+
+ avro_schema_decref(schema);
+ return 0;
+}
+
int main(int argc, char *argv[])
{
char *srcdir = getenv("srcdir");
@@ -121,6 +248,19 @@ int main(int argc, char *argv[])
fprintf(stderr, "RUNNING %s\n", path);
run_tests(path, 0);
+ fprintf(stderr, "*** Running array tests **\n");
+ test_array();
+ fprintf(stderr, "*** Running enum tests **\n");
+ test_enum();
+ fprintf(stderr, "*** Running fixed tests **\n");
+ test_fixed();
+ fprintf(stderr, "*** Running map tests **\n");
+ test_map();
+ fprintf(stderr, "*** Running record tests **\n");
+ test_record();
+ fprintf(stderr, "*** Running union tests **\n");
+ test_union();
+
fprintf(stderr, "==================================================\n");
fprintf(stderr,
"Finished running %d schema test cases successfully \n",