class Avro::Schema

Constants

CRC_EMPTY
DECIMAL_LOGICAL_TYPE
DEFAULT_VALIDATE_OPTIONS
INT_MAX_VALUE
INT_MIN_VALUE
LONG_MAX_VALUE
LONG_MIN_VALUE
NAMED_TYPES
NAMED_TYPES_SYM
NAME_REGEX
PRIMITIVE_TYPES

Sets of strings, for backwards compatibility. See below for sets of symbols, for better performance.

PRIMITIVE_TYPES_SYM
SINGLE_OBJECT_MAGIC_NUMBER
VALID_TYPES
VALID_TYPES_SYM

Attributes

logical_type[R]
type_sym[R]

Public Class Methods

new(type, logical_type=nil) click to toggle source
    # File lib/avro/schema.rb
126 def initialize(type, logical_type=nil)
127   @type_sym = type.is_a?(Symbol) ? type : type.to_sym
128   @logical_type = logical_type
129 end
parse(json_string) click to toggle source
   # File lib/avro/schema.rb
44 def self.parse(json_string)
45   real_parse(MultiJson.load(json_string), {})
46 end
real_parse(json_obj, names=nil, default_namespace=nil) click to toggle source

Build Avro Schema from data parsed out of JSON string.

    # File lib/avro/schema.rb
 49 def self.real_parse(json_obj, names=nil, default_namespace=nil)
 50   if json_obj.is_a? Hash
 51     type = json_obj['type']
 52     logical_type = json_obj['logicalType']
 53     raise SchemaParseError, %Q(No "type" property: #{json_obj}) if type.nil?
 54 
 55     # Check that the type is valid before calling #to_sym, since symbols are never garbage
 56     # collected (important to avoid DoS if we're accepting schemas from untrusted clients)
 57     unless VALID_TYPES.include?(type)
 58       raise SchemaParseError, "Unknown type: #{type}"
 59     end
 60 
 61     type_sym = type.to_sym
 62     if PRIMITIVE_TYPES_SYM.include?(type_sym)
 63       case type_sym
 64       when :bytes
 65         precision = json_obj['precision']
 66         scale = json_obj['scale']
 67         return BytesSchema.new(type_sym, logical_type, precision, scale)
 68       else
 69         return PrimitiveSchema.new(type_sym, logical_type)
 70       end
 71     elsif NAMED_TYPES_SYM.include? type_sym
 72       name = json_obj['name']
 73       if !Avro.disable_schema_name_validation && name !~ NAME_REGEX
 74         raise SchemaParseError, "Name #{name} is invalid for type #{type}!"
 75       end
 76       namespace = json_obj.include?('namespace') ? json_obj['namespace'] : default_namespace
 77       aliases = json_obj['aliases']
 78       case type_sym
 79       when :fixed
 80         size = json_obj['size']
 81         precision = json_obj['precision']
 82         scale = json_obj['scale']
 83         return FixedSchema.new(name, namespace, size, names, logical_type, aliases, precision, scale)
 84       when :enum
 85         symbols = json_obj['symbols']
 86         doc     = json_obj['doc']
 87         default = json_obj['default']
 88         return EnumSchema.new(name, namespace, symbols, names, doc, default, aliases)
 89       when :record, :error
 90         fields = json_obj['fields']
 91         doc    = json_obj['doc']
 92         return RecordSchema.new(name, namespace, fields, names, type_sym, doc, aliases)
 93       else
 94         raise SchemaParseError.new("Unknown named type: #{type}")
 95       end
 96 
 97     else
 98       case type_sym
 99       when :array
100         return ArraySchema.new(json_obj['items'], names, default_namespace)
101       when :map
102         return MapSchema.new(json_obj['values'], names, default_namespace)
103       else
104         raise SchemaParseError.new("Unknown Valid Type: #{type}")
105       end
106     end
107 
108   elsif json_obj.is_a? Array
109     # JSON array (union)
110     return UnionSchema.new(json_obj, names, default_namespace)
111   elsif PRIMITIVE_TYPES.include? json_obj
112     return PrimitiveSchema.new(json_obj)
113   else
114     raise UnknownSchemaError.new(json_obj)
115   end
116 end
validate(expected_schema, logical_datum, options = DEFAULT_VALIDATE_OPTIONS) click to toggle source

Determine if a ruby datum is an instance of a schema

    # File lib/avro/schema.rb
119 def self.validate(expected_schema, logical_datum, options = DEFAULT_VALIDATE_OPTIONS)
120   SchemaValidator.validate!(expected_schema, logical_datum, options)
121   true
122 rescue SchemaValidator::ValidationError
123   false
124 end

Public Instance Methods

==(other, _seen=nil) click to toggle source
    # File lib/avro/schema.rb
209 def ==(other, _seen=nil)
210   other.is_a?(Schema) && type_sym == other.type_sym
211 end
be_read?(other_schema) click to toggle source
    # File lib/avro/schema.rb
201 def be_read?(other_schema)
202   other_schema.read?(self)
203 end
crc_64_avro_fingerprint() click to toggle source
    # File lib/avro/schema.rb
170 def crc_64_avro_fingerprint
171   parsing_form = Avro::SchemaNormalization.to_parsing_form(self)
172   data_bytes = parsing_form.unpack("C*")
173 
174   initFPTable unless @@fp_table
175 
176   fp = CRC_EMPTY
177   data_bytes.each do |b|
178     fp = (fp >> 8) ^ @@fp_table[ (fp ^ b) & 0xff ]
179   end
180   fp
181 end
hash(_seen=nil) click to toggle source
    # File lib/avro/schema.rb
213 def hash(_seen=nil)
214   type_sym.hash
215 end
initFPTable() click to toggle source
    # File lib/avro/schema.rb
159 def initFPTable
160   @@fp_table = Array.new(256)
161   256.times do |i|
162     fp = i
163     8.times do
164       fp = (fp >> 1) ^ ( CRC_EMPTY & -( fp & 1 ) )
165     end
166     @@fp_table[i] = fp
167   end
168 end
md5_fingerprint() click to toggle source

Returns the MD5 fingerprint of the schema as an Integer.

    # File lib/avro/schema.rb
143 def md5_fingerprint
144   parsing_form = SchemaNormalization.to_parsing_form(self)
145   Digest::MD5.hexdigest(parsing_form).to_i(16)
146 end
mutual_read?(other_schema) click to toggle source
    # File lib/avro/schema.rb
205 def mutual_read?(other_schema)
206   SchemaCompatibility.mutual_read?(other_schema, self)
207 end
read?(writers_schema) click to toggle source
    # File lib/avro/schema.rb
197 def read?(writers_schema)
198   SchemaCompatibility.can_read?(writers_schema, self)
199 end
sha256_fingerprint() click to toggle source

Returns the SHA-256 fingerprint of the schema as an Integer.

    # File lib/avro/schema.rb
149 def sha256_fingerprint
150   parsing_form = SchemaNormalization.to_parsing_form(self)
151   Digest::SHA256.hexdigest(parsing_form).to_i(16)
152 end
single_object_encoding_header() click to toggle source
    # File lib/avro/schema.rb
184 def single_object_encoding_header
185   [SINGLE_OBJECT_MAGIC_NUMBER, single_object_schema_fingerprint].flatten
186 end
single_object_schema_fingerprint() click to toggle source
    # File lib/avro/schema.rb
187 def single_object_schema_fingerprint
188   working = crc_64_avro_fingerprint
189   bytes = Array.new(8)
190   8.times do |i|
191     bytes[i] = (working & 0xff)
192     working = working >> 8
193   end
194   bytes
195 end
subparse(json_obj, names=nil, namespace=nil) click to toggle source
    # File lib/avro/schema.rb
217 def subparse(json_obj, names=nil, namespace=nil)
218   if json_obj.is_a?(String) && names
219     fullname = Name.make_fullname(json_obj, namespace)
220     return names[fullname] if names.include?(fullname)
221   end
222 
223   begin
224     Schema.real_parse(json_obj, names, namespace)
225   rescue => e
226     raise e if e.is_a? SchemaParseError
227     raise SchemaParseError, "Sub-schema for #{self.class.name} not a valid Avro schema. Bad schema: #{json_obj}"
228   end
229 end
to_avro(_names=nil) click to toggle source
    # File lib/avro/schema.rb
231 def to_avro(_names=nil)
232   props = {'type' => type}
233   props['logicalType'] = logical_type if logical_type
234   props
235 end
to_s() click to toggle source
    # File lib/avro/schema.rb
237 def to_s
238   MultiJson.dump to_avro
239 end
type() click to toggle source

Returns the type as a string (rather than a symbol), for backwards compatibility. Deprecated in favor of {#type_sym}.

    # File lib/avro/schema.rb
136 def type; @type_sym.to_s; end
type_adapter() click to toggle source
    # File lib/avro/schema.rb
138 def type_adapter
139   @type_adapter ||= LogicalTypes.type_adapter(type, logical_type, self) || LogicalTypes::Identity
140 end

Private Instance Methods

validate_aliases!() click to toggle source
    # File lib/avro/schema.rb
241 def validate_aliases!
242   unless aliases.nil? ||
243     (aliases.is_a?(Array) && aliases.all? { |a| a.is_a?(String) })
244 
245     raise Avro::SchemaParseError,
246           "Invalid aliases value #{aliases.inspect} for #{type} #{name}. Must be an array of strings."
247   end
248 end