lib/avro/schema.rb in avro-1.3.0 vs lib/avro/schema.rb in avro-1.3.3
- old
+ new
@@ -49,11 +49,11 @@
return EnumSchema.new(name, namespace, symbols, names)
when 'record', 'error'
fields = json_obj['fields']
return RecordSchema.new(name, namespace, fields, names, type)
else
- raise SchemaParseError.new("Unknown Named Type: #{type}")
+ raise SchemaParseError.new("Unknown named type: #{type}")
end
elsif VALID_TYPES.include?(type)
case type
when 'array'
return ArraySchema.new(json_obj['items'], names)
@@ -71,11 +71,11 @@
# JSON array (union)
return UnionSchema.new(json_obj, names)
elsif PRIMITIVE_TYPES.include? json_obj
return PrimitiveSchema.new(json_obj)
else
- msg = "Could not make an Avro Schema object from #{json_obj}"
+ msg = "#{json_obj.inspect} is not a schema we know about."
raise SchemaParseError.new(msg)
end
end
# Determine if a ruby datum is an instance of a schema
@@ -127,27 +127,36 @@
def hash(seen=nil)
@type.hash
end
- def to_hash
+ def subparse(json_obj, names=nil)
+ begin
+ Schema.real_parse(json_obj, names)
+ rescue => e
+ raise e if e.is_a? SchemaParseError
+ raise SchemaParseError, "Sub-schema for #{self.class.name} not a valid Avro schema. Bad schema: #{json_obj}"
+ end
+ end
+
+ def to_avro
{'type' => @type}
end
def to_s
- Yajl.dump to_hash
+ Yajl.dump to_avro
end
class NamedSchema < Schema
attr_reader :name, :namespace
def initialize(type, name, namespace=nil, names=nil)
super(type)
@name, @namespace = Name.extract_namespace(name, namespace)
names = Name.add_name(names, self)
end
- def to_hash
+ def to_avro
props = {'name' => @name}
props.merge!('namespace' => @namespace) if @namespace
super.merge props
end
@@ -192,12 +201,12 @@
def fields_hash
fields.inject({}){|hsh, field| hsh[field.name] = field; hsh }
end
- def to_hash
- hsh = super.merge('fields' => @fields.map {|f|Yajl.load(f.to_s)} )
+ def to_avro
+ hsh = super.merge('fields' => @fields.map {|f| f.to_avro } )
if type == 'request'
hsh['fields']
else
hsh
end
@@ -213,24 +222,19 @@
if items.is_a?(String) && names.has_key?(items)
@items = names[items]
@items_schema_from_names = true
else
- begin
- @items = Schema.real_parse(items, names)
- rescue => e
- msg = "Items schema not a valid Avro schema" + e.to_s
- raise SchemaParseError, msg
- end
+ @items = subparse(items, names)
end
end
- def to_hash
+ def to_avro
name_or_json = if items_schema_from_names
items.fullname
else
- Yajl.load(items.to_s)
+ items.to_avro
end
super.merge('items' => name_or_json)
end
end
@@ -242,25 +246,21 @@
super('map')
if values.is_a?(String) && names.has_key?(values)
values_schema = names[values]
@values_schema_from_names = true
else
- begin
- values_schema = Schema.real_parse(values, names)
- rescue => e
- raise SchemaParseError.new('Values schema not a valid Avro schema.' + e.to_s)
- end
+ values_schema = subparse(values, names)
end
@values = values_schema
end
- def to_hash
+ def to_avro
to_dump = super
if values_schema_from_names
to_dump['values'] = values
else
- to_dump['values'] = Yajl.load(values.to_s)
+ to_dump['values'] = values.to_avro
end
to_dump
end
end
@@ -275,15 +275,11 @@
from_names = false
if schema.is_a?(String) && names.has_key?(schema)
new_schema = names[schema]
from_names = true
else
- begin
- new_schema = Schema.real_parse(schema, names)
- rescue
- raise SchemaParseError, 'Union item must be a valid Avro schema'
- end
+ new_schema = subparse(schema, names)
end
ns_type = new_schema.type
if VALID_TYPES.include?(ns_type) &&
!NAMED_TYPES.include?(ns_type) &&
@@ -297,22 +293,22 @@
end
@schemas = schema_objects
end
end
- def to_s
+ def to_avro
# FIXME(jmhodges) this from_name pattern is really weird and
# seems code-smelly.
to_dump = []
schemas.each_with_index do |schema, i|
if schema_from_names_indices.include?(i)
to_dump << schema.fullname
else
- to_dump << Yajl.load(schema.to_s)
+ to_dump << schema.to_avro
end
end
- Yajl.dump(to_dump)
+ to_dump
end
end
class EnumSchema < NamedSchema
attr_reader :symbols
@@ -323,11 +319,11 @@
end
super('enum', name, space, names)
@symbols = symbols
end
- def to_hash
+ def to_avro
super.merge('symbols' => symbols)
end
end
# Valid primitive types are in PRIMITIVE_TYPES.
@@ -338,12 +334,13 @@
end
super(type)
end
- def to_s
- to_hash.size == 1 ? type.inspect : Yajl.dump(to_hash)
+ def to_avro
+ hsh = super
+ hsh.size == 1 ? type : hsh
end
end
class FixedSchema < NamedSchema
attr_reader :size
@@ -354,43 +351,39 @@
end
super('fixed', name, space, names)
@size = size
end
- def to_hash
+ def to_avro
super.merge('size' => @size)
end
end
- class Field
+ class Field < Schema
attr_reader :type, :name, :default, :order, :type_from_names
def initialize(type, name, default=nil, order=nil, names=nil)
@type_from_names = false
if type.is_a?(String) && names && names.has_key?(type)
type_schema = names[type]
@type_from_names = true
else
- type_schema = Schema.real_parse(type, names)
+ type_schema = subparse(type, names)
end
@type = type_schema
@name = name
@default = default
@order = order
end
- def to_hash
- sigh_type = type_from_names ? type.fullname : Yajl.load(type.to_s)
+ def to_avro
+ sigh_type = type_from_names ? type.fullname : type.to_avro
hsh = {
'name' => name,
'type' => sigh_type
}
hsh['default'] = default if default
hsh['order'] = order if order
hsh
- end
-
- def to_s
- Yajl.dump(to_hash)
end
end
end
class SchemaParseError < AvroError; end