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