avro 1.7.7 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 87cb7e254e68c38b88c8b88da666a8fa7e82a2cf
4
+ data.tar.gz: 0b2d18424b7186f1fb67408a0d123663f9d59878
5
+ SHA512:
6
+ metadata.gz: 0ef8f99ff41b179b150a2c68be7428bc003d0b7d7a21cc43e5bd22604f437e67e18833425afb08378fb68a1be7f8baba741d0be990be904f58e5c62700968c5b
7
+ data.tar.gz: 6b3d8465d9d6a3699155c346bfab8c7bc2044adcfdc89ded920c0c2cff68038d3b4e81ddb615cc17f2112c0d8ec1a2634f590ef96511072c8fd1fd5b4e99b373
data/LICENSE ADDED
@@ -0,0 +1,203 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
203
+
data/Manifest CHANGED
@@ -1,4 +1,6 @@
1
1
  CHANGELOG
2
+ LICENSE
3
+ NOTICE
2
4
  Manifest
3
5
  Rakefile
4
6
  avro.gemspec
@@ -9,14 +11,19 @@ lib/avro/io.rb
9
11
  lib/avro/ipc.rb
10
12
  lib/avro/protocol.rb
11
13
  lib/avro/schema.rb
14
+ lib/avro/schema_normalization.rb
15
+ test/case_finder.rb
12
16
  test/random_data.rb
13
17
  test/sample_ipc_client.rb
14
18
  test/sample_ipc_http_client.rb
15
19
  test/sample_ipc_http_server.rb
16
20
  test/sample_ipc_server.rb
17
21
  test/test_datafile.rb
22
+ test/test_fingerprints.rb
18
23
  test/test_help.rb
19
24
  test/test_io.rb
20
25
  test/test_protocol.rb
26
+ test/test_schema.rb
27
+ test/test_schema_normalization.rb
21
28
  test/test_socket_transport.rb
22
29
  test/tool.rb
data/NOTICE ADDED
@@ -0,0 +1,6 @@
1
+ Apache Avro
2
+ Copyright 2010-2015 The Apache Software Foundation
3
+
4
+ This product includes software developed at
5
+ The Apache Software Foundation (http://www.apache.org/).
6
+
data/Rakefile CHANGED
@@ -19,11 +19,12 @@ require 'echoe'
19
19
  VERSION = File.open('../../share/VERSION.txt').read.sub('-SNAPSHOT', '.pre1').chomp
20
20
  Echoe.new('avro', VERSION) do |p|
21
21
  p.author = "Apache Software Foundation"
22
- p.email = "avro-dev@hadoop.apache.org"
22
+ p.email = "dev@avro.apache.org"
23
23
  p.summary = "Apache Avro for Ruby"
24
24
  p.description = "Avro is a data serialization and RPC format"
25
- p.url = "http://hadoop.apache.org/avro/"
25
+ p.url = "http://avro.apache.org/"
26
26
  p.runtime_dependencies = %w[multi_json]
27
+ p.licenses = ["Apache License 2.0 (Apache-2.0)"]
27
28
  end
28
29
 
29
30
  t = Rake::TestTask.new(:interop)
@@ -1,26 +1,28 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # stub: avro 1.8.0 ruby lib
2
3
 
3
4
  Gem::Specification.new do |s|
4
5
  s.name = "avro"
5
- s.version = "1.7.7"
6
+ s.version = "1.8.0"
6
7
 
7
8
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib"]
8
10
  s.authors = ["Apache Software Foundation"]
9
- s.date = "2014-07-18"
11
+ s.date = "2016-01-22"
10
12
  s.description = "Avro is a data serialization and RPC format"
11
- s.email = "avro-dev@hadoop.apache.org"
12
- s.extra_rdoc_files = ["CHANGELOG", "lib/avro.rb", "lib/avro/data_file.rb", "lib/avro/io.rb", "lib/avro/ipc.rb", "lib/avro/protocol.rb", "lib/avro/schema.rb"]
13
- s.files = ["CHANGELOG", "Manifest", "Rakefile", "avro.gemspec", "interop/test_interop.rb", "lib/avro.rb", "lib/avro/data_file.rb", "lib/avro/io.rb", "lib/avro/ipc.rb", "lib/avro/protocol.rb", "lib/avro/schema.rb", "test/random_data.rb", "test/sample_ipc_client.rb", "test/sample_ipc_http_client.rb", "test/sample_ipc_http_server.rb", "test/sample_ipc_server.rb", "test/test_datafile.rb", "test/test_help.rb", "test/test_io.rb", "test/test_protocol.rb", "test/test_socket_transport.rb", "test/tool.rb", "test/test_schema.rb"]
14
- s.homepage = "http://hadoop.apache.org/avro/"
13
+ s.email = "dev@avro.apache.org"
14
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "lib/avro.rb", "lib/avro/data_file.rb", "lib/avro/io.rb", "lib/avro/ipc.rb", "lib/avro/protocol.rb", "lib/avro/schema.rb", "lib/avro/schema_normalization.rb"]
15
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "NOTICE", "Rakefile", "avro.gemspec", "interop/test_interop.rb", "lib/avro.rb", "lib/avro/data_file.rb", "lib/avro/io.rb", "lib/avro/ipc.rb", "lib/avro/protocol.rb", "lib/avro/schema.rb", "lib/avro/schema_normalization.rb", "test/case_finder.rb", "test/random_data.rb", "test/sample_ipc_client.rb", "test/sample_ipc_http_client.rb", "test/sample_ipc_http_server.rb", "test/sample_ipc_server.rb", "test/test_datafile.rb", "test/test_fingerprints.rb", "test/test_help.rb", "test/test_io.rb", "test/test_protocol.rb", "test/test_schema.rb", "test/test_schema_normalization.rb", "test/test_socket_transport.rb", "test/tool.rb"]
16
+ s.homepage = "http://avro.apache.org/"
17
+ s.licenses = ["Apache License 2.0 (Apache-2.0)"]
15
18
  s.rdoc_options = ["--line-numbers", "--title", "Avro"]
16
- s.require_paths = ["lib"]
17
19
  s.rubyforge_project = "avro"
18
- s.rubygems_version = "1.8.15"
20
+ s.rubygems_version = "2.2.2"
19
21
  s.summary = "Apache Avro for Ruby"
20
- s.test_files = ["test/test_datafile.rb", "test/test_help.rb", "test/test_protocol.rb", "test/test_socket_transport.rb", "test/test_schema.rb", "test/test_io.rb"]
22
+ s.test_files = ["test/test_datafile.rb", "test/test_fingerprints.rb", "test/test_help.rb", "test/test_io.rb", "test/test_protocol.rb", "test/test_schema.rb", "test/test_schema_normalization.rb", "test/test_socket_transport.rb"]
21
23
 
22
24
  if s.respond_to? :specification_version then
23
- s.specification_version = 3
25
+ s.specification_version = 4
24
26
 
25
27
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
28
  s.add_runtime_dependency(%q<multi_json>, [">= 0"])
@@ -39,3 +39,4 @@ require 'avro/io'
39
39
  require 'avro/data_file'
40
40
  require 'avro/protocol'
41
41
  require 'avro/ipc'
42
+ require 'avro/schema_normalization'
@@ -93,23 +93,22 @@ module Avro
93
93
  attr_reader :writer, :encoder, :datum_writer, :buffer_writer, :buffer_encoder, :sync_marker, :meta, :codec
94
94
  attr_accessor :block_count
95
95
 
96
- def initialize(writer, datum_writer, writers_schema=nil, codec=nil)
96
+ def initialize(writer, datum_writer, writers_schema=nil, codec=nil, meta={})
97
97
  # If writers_schema is not present, presume we're appending
98
98
  @writer = writer
99
99
  @encoder = IO::BinaryEncoder.new(@writer)
100
100
  @datum_writer = datum_writer
101
+ @meta = meta
101
102
  @buffer_writer = StringIO.new('', 'w')
102
103
  @buffer_writer.set_encoding('BINARY') if @buffer_writer.respond_to?(:set_encoding)
103
104
  @buffer_encoder = IO::BinaryEncoder.new(@buffer_writer)
104
105
  @block_count = 0
105
106
 
106
- @meta = {}
107
-
108
107
  if writers_schema
109
108
  @sync_marker = Writer.generate_sync_marker
110
109
  @codec = DataFile.get_codec(codec)
111
- meta['avro.codec'] = @codec.codec_name.to_s
112
- meta['avro.schema'] = writers_schema.to_s
110
+ @meta['avro.codec'] = @codec.codec_name.to_s
111
+ @meta['avro.schema'] = writers_schema.to_s
113
112
  datum_writer.writers_schema = writers_schema
114
113
  write_header
115
114
  else
@@ -119,12 +118,12 @@ module Avro
119
118
  # FIXME(jmhodges): collect arbitrary metadata
120
119
  # collect metadata
121
120
  @sync_marker = dfr.sync_marker
122
- meta['avro.codec'] = dfr.meta['avro.codec']
121
+ @meta['avro.codec'] = dfr.meta['avro.codec']
123
122
  @codec = DataFile.get_codec(meta['avro.codec'])
124
123
 
125
124
  # get schema used to write existing file
126
125
  schema_from_file = dfr.meta['avro.schema']
127
- meta['avro.schema'] = schema_from_file
126
+ @meta['avro.schema'] = schema_from_file
128
127
  datum_writer.writers_schema = Schema.parse(schema_from_file)
129
128
 
130
129
  # seek to the end of the file and prepare for writing
@@ -334,8 +333,31 @@ module Avro
334
333
  end
335
334
  end
336
335
 
336
+ class SnappyCodec
337
+ def codec_name; 'snappy'; end
338
+
339
+ def decompress(data)
340
+ load_snappy!
341
+ Snappy.inflate(data)
342
+ end
343
+
344
+ def compress(data)
345
+ load_snappy!
346
+ Snappy.deflate(data)
347
+ end
348
+
349
+ private
350
+
351
+ def load_snappy!
352
+ require 'snappy' unless defined?(Snappy)
353
+ rescue LoadError
354
+ raise LoadError, "Snappy compression is not available, please install the `snappy` gem."
355
+ end
356
+ end
357
+
337
358
  DataFile.register_codec NullCodec
338
359
  DataFile.register_codec DeflateCodec
360
+ DataFile.register_codec SnappyCodec
339
361
 
340
362
  # TODO this constant won't be updated if you register another codec.
341
363
  # Deprecated in favor of Avro::DataFile::codecs
@@ -209,7 +209,7 @@ module Avro
209
209
  # A string is encoded as a long followed by that many bytes of
210
210
  # UTF-8 encoded character data
211
211
  def write_string(datum)
212
- # FIXME utf-8 encode this in 1.9
212
+ datum = datum.encode('utf-8') if datum.respond_to? :encode
213
213
  write_bytes(datum)
214
214
  end
215
215
 
@@ -100,7 +100,7 @@ module Avro::IPC
100
100
  def request(message_name, request_datum)
101
101
  # Writes a request message and reads a response or error message.
102
102
  # build handshake and call request
103
- buffer_writer = StringIO.new('', 'w+')
103
+ buffer_writer = StringIO.new(''.force_encoding('BINARY'))
104
104
  buffer_encoder = Avro::IO::BinaryEncoder.new(buffer_writer)
105
105
  write_handshake_request(buffer_encoder)
106
106
  write_call_request(message_name, request_datum, buffer_encoder)
@@ -244,7 +244,7 @@ module Avro::IPC
244
244
  # a response or error. Compare to 'handle()' in Thrift.
245
245
  def respond(call_request, transport=nil)
246
246
  buffer_decoder = Avro::IO::BinaryDecoder.new(StringIO.new(call_request))
247
- buffer_writer = StringIO.new('', 'w+')
247
+ buffer_writer = StringIO.new(''.force_encoding('BINARY'))
248
248
  buffer_encoder = Avro::IO::BinaryEncoder.new(buffer_writer)
249
249
  error = nil
250
250
  response_metadata = {}
@@ -294,6 +294,7 @@ module Avro::IPC
294
294
  end
295
295
  rescue Avro::AvroError => e
296
296
  error = AvroRemoteException.new(e.to_s)
297
+ # TODO does the stuff written here ever get used?
297
298
  buffer_encoder = Avro::IO::BinaryEncoder.new(StringIO.new)
298
299
  META_WRITER.write(response_metadata, buffer_encoder)
299
300
  buffer_encoder.write_boolean(true)
@@ -393,7 +394,7 @@ module Avro::IPC
393
394
  def read_framed_message
394
395
  message = []
395
396
  loop do
396
- buffer = StringIO.new
397
+ buffer = StringIO.new(''.force_encoding('BINARY'))
397
398
  buffer_length = read_buffer_length
398
399
  if buffer_length == 0
399
400
  return message.join
@@ -410,7 +411,7 @@ module Avro::IPC
410
411
  end
411
412
 
412
413
  def write_framed_message(message)
413
- message_length = message.size
414
+ message_length = message.bytesize
414
415
  total_bytes_sent = 0
415
416
  while message_length - total_bytes_sent > 0
416
417
  if message_length - total_bytes_sent > BUFFER_SIZE
@@ -426,7 +427,7 @@ module Avro::IPC
426
427
  end
427
428
 
428
429
  def write_buffer(chunk)
429
- buffer_length = chunk.size
430
+ buffer_length = chunk.bytesize
430
431
  write_buffer_length(buffer_length)
431
432
  total_bytes_sent = 0
432
433
  while total_bytes_sent < buffer_length
@@ -467,7 +468,7 @@ module Avro::IPC
467
468
  end
468
469
 
469
470
  def write_framed_message(message)
470
- message_size = message.size
471
+ message_size = message.bytesize
471
472
  total_bytes_sent = 0
472
473
  while message_size - total_bytes_sent > 0
473
474
  if message_size - total_bytes_sent > BUFFER_SIZE
@@ -485,7 +486,7 @@ module Avro::IPC
485
486
 
486
487
  private
487
488
  def write_buffer(chunk)
488
- buffer_size = chunk.size
489
+ buffer_size = chunk.bytesize
489
490
  write_buffer_size(buffer_size)
490
491
  writer << chunk
491
492
  end
@@ -505,13 +506,13 @@ module Avro::IPC
505
506
  def read_framed_message
506
507
  message = []
507
508
  loop do
508
- buffer = ""
509
+ buffer = ''.force_encoding('BINARY')
509
510
  buffer_size = read_buffer_size
510
511
 
511
512
  return message.join if buffer_size == 0
512
513
 
513
- while buffer.size < buffer_size
514
- chunk = reader.read(buffer_size - buffer.size)
514
+ while buffer.bytesize < buffer_size
515
+ chunk = reader.read(buffer_size - buffer.bytesize)
515
516
  chunk_error?(chunk)
516
517
  buffer << chunk
517
518
  end
@@ -541,7 +542,7 @@ module Avro::IPC
541
542
  end
542
543
 
543
544
  def transceive(message)
544
- writer = FramedWriter.new(StringIO.new)
545
+ writer = FramedWriter.new(StringIO.new(''.force_encoding('BINARY')))
545
546
  writer.write_framed_message(message)
546
547
  resp = @conn.post('/', writer.to_s, {'Content-Type' => 'avro/binary'})
547
548
  FramedReader.new(StringIO.new(resp.body)).read_framed_message
@@ -86,8 +86,7 @@ module Avro
86
86
  elsif PRIMITIVE_TYPES.include? json_obj
87
87
  return PrimitiveSchema.new(json_obj)
88
88
  else
89
- msg = "#{json_obj.inspect} is not a schema we know about."
90
- raise SchemaParseError.new(msg)
89
+ raise UnknownSchemaError.new(json_obj)
91
90
  end
92
91
  end
93
92
 
@@ -109,7 +108,7 @@ module Avro
109
108
  when :float, :double
110
109
  datum.is_a?(Float) || datum.is_a?(Fixnum) || datum.is_a?(Bignum)
111
110
  when :fixed
112
- datum.is_a?(String) && datum.size == expected_schema.size
111
+ datum.is_a?(String) && datum.bytesize == expected_schema.size
113
112
  when :enum
114
113
  expected_schema.symbols.include? datum
115
114
  when :array
@@ -138,6 +137,18 @@ module Avro
138
137
  # Deprecated in favor of {#type_sym}.
139
138
  def type; @type_sym.to_s; end
140
139
 
140
+ # Returns the MD5 fingerprint of the schema as an Integer.
141
+ def md5_fingerprint
142
+ parsing_form = SchemaNormalization.to_parsing_form(self)
143
+ Digest::MD5.hexdigest(parsing_form).to_i(16)
144
+ end
145
+
146
+ # Returns the SHA-256 fingerprint of the schema as an Integer.
147
+ def sha256_fingerprint
148
+ parsing_form = SchemaNormalization.to_parsing_form(self)
149
+ Digest::SHA256.hexdigest(parsing_form).to_i(16)
150
+ end
151
+
141
152
  def ==(other, seen=nil)
142
153
  other.is_a?(Schema) && type_sym == other.type_sym
143
154
  end
@@ -370,6 +381,15 @@ module Avro
370
381
 
371
382
  class SchemaParseError < AvroError; end
372
383
 
384
+ class UnknownSchemaError < SchemaParseError
385
+ attr_reader :type_name
386
+
387
+ def initialize(type)
388
+ @type_name = type
389
+ super("#{type.inspect} is not a schema we know about.")
390
+ end
391
+ end
392
+
373
393
  module Name
374
394
  def self.extract_namespace(name, namespace)
375
395
  parts = name.split('.')
@@ -0,0 +1,83 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Avro
18
+ class SchemaNormalization
19
+ def self.to_parsing_form(schema)
20
+ new.to_parsing_form(schema)
21
+ end
22
+
23
+ def initialize
24
+ @processed_names = []
25
+ end
26
+
27
+ def to_parsing_form(schema)
28
+ MultiJson.dump(normalize_schema(schema))
29
+ end
30
+
31
+ private
32
+
33
+ def normalize_schema(schema)
34
+ type = schema.type_sym.to_s
35
+
36
+ if Schema::NAMED_TYPES.include?(type)
37
+ if @processed_names.include?(schema.name)
38
+ return schema.name
39
+ else
40
+ @processed_names << schema.name
41
+ end
42
+ end
43
+
44
+ case type
45
+ when *Schema::PRIMITIVE_TYPES
46
+ type
47
+ when "record"
48
+ fields = schema.fields.map {|field| normalize_field(field) }
49
+
50
+ normalize_named_type(schema, fields: fields)
51
+ when "enum"
52
+ normalize_named_type(schema, symbols: schema.symbols)
53
+ when "fixed"
54
+ normalize_named_type(schema, size: schema.size)
55
+ when "array"
56
+ { type: type, items: normalize_schema(schema.items) }
57
+ when "map"
58
+ { type: type, values: normalize_schema(schema.values) }
59
+ when "union"
60
+ if schema.schemas.nil?
61
+ []
62
+ else
63
+ schema.schemas.map {|s| normalize_schema(s) }
64
+ end
65
+ else
66
+ raise "unknown type #{type}"
67
+ end
68
+ end
69
+
70
+ def normalize_field(field)
71
+ {
72
+ name: field.name,
73
+ type: normalize_schema(field.type)
74
+ }
75
+ end
76
+
77
+ def normalize_named_type(schema, attributes = {})
78
+ name = Name.make_fullname(schema.name, schema.namespace)
79
+
80
+ { name: name, type: schema.type_sym.to_s }.merge(attributes)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,87 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+ require 'strscan'
20
+
21
+ class CaseFinder
22
+ PATH = File.expand_path("../../../../share/test/data/schema-tests.txt", __FILE__)
23
+
24
+ Case = Struct.new(:id, :input, :canonical, :fingerprint)
25
+
26
+ def self.cases
27
+ new.cases
28
+ end
29
+
30
+ def initialize
31
+ @scanner = StringScanner.new(File.read(PATH))
32
+ @cases = []
33
+ end
34
+
35
+ def cases
36
+ until @scanner.eos?
37
+ test_case = scan_case
38
+ @cases << test_case if test_case
39
+ end
40
+
41
+ @cases
42
+ end
43
+
44
+ private
45
+
46
+ def scan_case
47
+ if id = @scanner.scan(/\/\/ \d+\n/)
48
+ while @scanner.skip(/\/\/ .*\n/); end
49
+
50
+ input = scan_input
51
+ canonical = scan_canonical
52
+ fingerprint = scan_fingerprint
53
+
54
+ Case.new(id, input, canonical, fingerprint)
55
+ else
56
+ @scanner.skip(/.*\n/)
57
+ nil
58
+ end
59
+ end
60
+
61
+ def scan_item(name)
62
+ if @scanner.scan(/<<#{name}\n/)
63
+ lines = []
64
+ while line = @scanner.scan(/.+\n/)
65
+ break if line.chomp == name
66
+ lines << line
67
+ end
68
+ lines.join
69
+ elsif @scanner.scan(/<<#{name} /)
70
+ input = @scanner.scan(/.+$/)
71
+ @scanner.skip(/\n/)
72
+ input
73
+ end
74
+ end
75
+
76
+ def scan_input
77
+ scan_item("INPUT")
78
+ end
79
+
80
+ def scan_canonical
81
+ scan_item("canonical")
82
+ end
83
+
84
+ def scan_fingerprint
85
+ scan_item("fingerprint")
86
+ end
87
+ end
@@ -167,6 +167,19 @@ JSON
167
167
  assert_equal records, ['a' * 10_000]
168
168
  end
169
169
 
170
+ def test_snappy
171
+ Avro::DataFile.open('data.avr', 'w', '"string"', :snappy) do |writer|
172
+ writer << 'a' * 10_000
173
+ end
174
+ assert(File.size('data.avr') < 600)
175
+
176
+ records = []
177
+ Avro::DataFile.open('data.avr') do |reader|
178
+ reader.each {|record| records << record }
179
+ end
180
+ assert_equal records, ['a' * 10_000]
181
+ end
182
+
170
183
  def test_append_to_deflated_file
171
184
  schema = Avro::Schema.parse('"string"')
172
185
  writer = Avro::IO::DatumWriter.new(schema)
@@ -185,4 +198,17 @@ JSON
185
198
  end
186
199
  assert_equal records, ['a' * 10_000, 'b' * 10_000]
187
200
  end
201
+
202
+ def test_custom_meta
203
+ meta = { 'x.greeting' => 'yo' }
204
+
205
+ schema = Avro::Schema.parse('"string"')
206
+ writer = Avro::IO::DatumWriter.new(schema)
207
+ file = Avro::DataFile::Writer.new(File.open('data.avr', 'wb'), writer, schema, nil, meta)
208
+ file.close
209
+
210
+ Avro::DataFile.open('data.avr') do |reader|
211
+ assert_equal 'yo', reader.meta['x.greeting']
212
+ end
213
+ end
188
214
  end
@@ -0,0 +1,37 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'test_help'
18
+
19
+ class TestFingerprints < Test::Unit::TestCase
20
+ def test_md5_fingerprint
21
+ schema = Avro::Schema.parse <<-SCHEMA
22
+ { "type": "int" }
23
+ SCHEMA
24
+
25
+ assert_equal 318112854175969537208795771590915775282,
26
+ schema.md5_fingerprint
27
+ end
28
+
29
+ def test_sha256_fingerprint
30
+ schema = Avro::Schema.parse <<-SCHEMA
31
+ { "type": "int" }
32
+ SCHEMA
33
+
34
+ assert_equal 28572620203319713300323544804233350633246234624932075150020181448463213378117,
35
+ schema.sha256_fingerprint
36
+ end
37
+ end
@@ -21,45 +21,55 @@ class TestIO < Test::Unit::TestCase
21
21
  Schema = Avro::Schema
22
22
 
23
23
  def test_null
24
+ check('"null"')
24
25
  check_default('"null"', "null", nil)
25
26
  end
26
27
 
27
28
  def test_boolean
29
+ check('"boolean"')
28
30
  check_default('"boolean"', "true", true)
29
31
  check_default('"boolean"', "false", false)
30
32
  end
31
33
 
32
34
  def test_string
35
+ check('"string"')
33
36
  check_default('"string"', '"foo"', "foo")
34
37
  end
35
38
 
36
39
  def test_bytes
40
+ check('"bytes"')
37
41
  check_default('"bytes"', '"foo"', "foo")
38
42
  end
39
43
 
40
44
  def test_int
45
+ check('"int"')
41
46
  check_default('"int"', "5", 5)
42
47
  end
43
48
 
44
49
  def test_long
50
+ check('"long"')
45
51
  check_default('"long"', "9", 9)
46
52
  end
47
53
 
48
54
  def test_float
55
+ check('"float"')
49
56
  check_default('"float"', "1.2", 1.2)
50
57
  end
51
58
 
52
59
  def test_double
60
+ check('"double"')
53
61
  check_default('"double"', "1.2", 1.2)
54
62
  end
55
63
 
56
64
  def test_array
57
65
  array_schema = '{"type": "array", "items": "long"}'
66
+ check(array_schema)
58
67
  check_default(array_schema, "[1]", [1])
59
68
  end
60
69
 
61
70
  def test_map
62
71
  map_schema = '{"type": "map", "values": "long"}'
72
+ check(map_schema)
63
73
  check_default(map_schema, '{"a": 1}', {"a" => 1})
64
74
  end
65
75
 
@@ -70,6 +80,7 @@ class TestIO < Test::Unit::TestCase
70
80
  "fields": [{"name": "f",
71
81
  "type": "long"}]}
72
82
  EOS
83
+ check(record_schema)
73
84
  check_default(record_schema, '{"f": 11}', {"f" => 11})
74
85
  end
75
86
 
@@ -80,11 +91,13 @@ EOS
80
91
  "fields": [{"name": "message",
81
92
  "type": "string"}]}
82
93
  EOS
94
+ check(error_schema)
83
95
  check_default(error_schema, '{"message": "boom"}', {"message" => "boom"})
84
96
  end
85
97
 
86
98
  def test_enum
87
99
  enum_schema = '{"type": "enum", "name": "Test","symbols": ["A", "B"]}'
100
+ check(enum_schema)
88
101
  check_default(enum_schema, '"B"', "B")
89
102
  end
90
103
 
@@ -129,6 +142,7 @@ EOS
129
142
 
130
143
  def test_fixed
131
144
  fixed_schema = '{"type": "fixed", "name": "Test", "size": 1}'
145
+ check(fixed_schema)
132
146
  check_default(fixed_schema, '"a"', "a")
133
147
  end
134
148
 
@@ -196,6 +210,51 @@ EOS
196
210
  end
197
211
  end
198
212
 
213
+ def test_utf8_string_encoding
214
+ [
215
+ "\xC3".force_encoding('ISO-8859-1'),
216
+ "\xC3\x83".force_encoding('UTF-8')
217
+ ].each do |value|
218
+ output = ''.force_encoding('BINARY')
219
+ encoder = Avro::IO::BinaryEncoder.new(StringIO.new(output))
220
+ datum_writer = Avro::IO::DatumWriter.new(Avro::Schema.parse('"string"'))
221
+ datum_writer.write(value, encoder)
222
+
223
+ assert_equal "\x04\xc3\x83".force_encoding('BINARY'), output
224
+ end
225
+ end
226
+
227
+ def test_bytes_encoding
228
+ [
229
+ "\xC3\x83".force_encoding('BINARY'),
230
+ "\xC3\x83".force_encoding('ISO-8859-1'),
231
+ "\xC3\x83".force_encoding('UTF-8')
232
+ ].each do |value|
233
+ output = ''.force_encoding('BINARY')
234
+ encoder = Avro::IO::BinaryEncoder.new(StringIO.new(output))
235
+ datum_writer = Avro::IO::DatumWriter.new(Avro::Schema.parse('"bytes"'))
236
+ datum_writer.write(value, encoder)
237
+
238
+ assert_equal "\x04\xc3\x83".force_encoding('BINARY'), output
239
+ end
240
+ end
241
+
242
+ def test_fixed_encoding
243
+ [
244
+ "\xC3\x83".force_encoding('BINARY'),
245
+ "\xC3\x83".force_encoding('ISO-8859-1'),
246
+ "\xC3\x83".force_encoding('UTF-8')
247
+ ].each do |value|
248
+ output = ''.force_encoding('BINARY')
249
+ encoder = Avro::IO::BinaryEncoder.new(StringIO.new(output))
250
+ schema = '{"type": "fixed", "name": "TwoBytes", "size": 2}'
251
+ datum_writer = Avro::IO::DatumWriter.new(Avro::Schema.parse(schema))
252
+ datum_writer.write(value, encoder)
253
+
254
+ assert_equal "\xc3\x83".force_encoding('BINARY'), output
255
+ end
256
+ end
257
+
199
258
  def test_skip_long
200
259
  for value_to_skip, hex_encoding in BINARY_INT_ENCODINGS
201
260
  value_to_read = 6253
@@ -284,7 +343,6 @@ EOS
284
343
  private
285
344
 
286
345
  def check_default(schema_json, default_json, default_value)
287
- check(schema_json)
288
346
  actual_schema = '{"type": "record", "name": "Foo", "fields": []}'
289
347
  actual = Avro::Schema.parse(actual_schema)
290
348
 
@@ -131,4 +131,16 @@ class TestSchema < Test::Unit::TestCase
131
131
  ]
132
132
  }
133
133
  end
134
+
135
+ def test_unknown_named_type
136
+ error = assert_raise Avro::UnknownSchemaError do
137
+ Avro::Schema.parse <<-SCHEMA
138
+ {"type": "record", "name": "my.name.space.Record", "fields": [
139
+ {"name": "reference", "type": "MissingType"}
140
+ ]}
141
+ SCHEMA
142
+ end
143
+
144
+ assert_equal '"MissingType" is not a schema we know about.', error.message
145
+ end
134
146
  end
@@ -0,0 +1,171 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'test_help'
19
+ require 'case_finder'
20
+
21
+ class TestSchemaNormalization < Test::Unit::TestCase
22
+ def test_primitives
23
+ %w[null boolean string bytes int long float double].each do |type|
24
+ schema = Avro::Schema.parse(<<-JSON)
25
+ { "type": "#{type}" }
26
+ JSON
27
+
28
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
29
+
30
+ assert_equal %("#{type}"), canonical_form
31
+ end
32
+ end
33
+
34
+ def test_records
35
+ schema = Avro::Schema.parse(<<-JSON)
36
+ {
37
+ "type": "record",
38
+ "name": "test",
39
+ "namespace": "random",
40
+ "doc": "some record",
41
+ "fields": [
42
+ { "name": "height", "type": "int", "doc": "the height" }
43
+ ]
44
+ }
45
+ JSON
46
+
47
+ expected_type = <<-JSON.strip
48
+ {"name":"random.test","type":"record","fields":[{"name":"height","type":"int"}]}
49
+ JSON
50
+
51
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
52
+
53
+ assert_equal expected_type, canonical_form
54
+ end
55
+
56
+ def test_recursive_records
57
+ schema = Avro::Schema.parse(<<-JSON)
58
+ {
59
+ "type": "record",
60
+ "name": "item",
61
+ "fields": [
62
+ { "name": "next", "type": "item" }
63
+ ]
64
+ }
65
+ JSON
66
+
67
+ expected_type = <<-JSON.strip
68
+ {"name":"item","type":"record","fields":[{"name":"next","type":"item"}]}
69
+ JSON
70
+
71
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
72
+
73
+ assert_equal expected_type, canonical_form
74
+ end
75
+
76
+ def test_enums
77
+ schema = Avro::Schema.parse(<<-JSON)
78
+ {
79
+ "type": "enum",
80
+ "name": "suit",
81
+ "namespace": "cards",
82
+ "doc": "the different suits of cards",
83
+ "symbols": ["club", "hearts", "diamond", "spades"]
84
+ }
85
+ JSON
86
+
87
+ expected_type = <<-JSON.strip
88
+ {"name":"cards.suit","type":"enum","symbols":["club","hearts","diamond","spades"]}
89
+ JSON
90
+
91
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
92
+
93
+ assert_equal expected_type, canonical_form
94
+ end
95
+
96
+ def test_fixed
97
+ schema = Avro::Schema.parse(<<-JSON)
98
+ {
99
+ "type": "fixed",
100
+ "name": "id",
101
+ "namespace": "db",
102
+ "size": 64
103
+ }
104
+ JSON
105
+
106
+ expected_type = <<-JSON.strip
107
+ {"name":"db.id","type":"fixed","size":64}
108
+ JSON
109
+
110
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
111
+
112
+ assert_equal expected_type, canonical_form
113
+ end
114
+
115
+ def test_arrays
116
+ schema = Avro::Schema.parse(<<-JSON)
117
+ {
118
+ "type": "array",
119
+ "doc": "the items",
120
+ "items": "int"
121
+ }
122
+ JSON
123
+
124
+ expected_type = <<-JSON.strip
125
+ {"type":"array","items":"int"}
126
+ JSON
127
+
128
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
129
+
130
+ assert_equal expected_type, canonical_form
131
+ end
132
+
133
+ def test_maps
134
+ schema = Avro::Schema.parse(<<-JSON)
135
+ {
136
+ "type": "map",
137
+ "doc": "the items",
138
+ "values": "int"
139
+ }
140
+ JSON
141
+
142
+ expected_type = <<-JSON.strip
143
+ {"type":"map","values":"int"}
144
+ JSON
145
+
146
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
147
+
148
+ assert_equal expected_type, canonical_form
149
+ end
150
+
151
+ def test_unions
152
+ schema = Avro::Schema.parse(<<-JSON)
153
+ ["int", "string"]
154
+ JSON
155
+
156
+ expected_type = <<-JSON.strip
157
+ ["int","string"]
158
+ JSON
159
+
160
+ canonical_form = Avro::SchemaNormalization.to_parsing_form(schema)
161
+
162
+ assert_equal expected_type, canonical_form
163
+ end
164
+
165
+ def test_shared_dataset
166
+ CaseFinder.cases.each do |test_case|
167
+ schema = Avro::Schema.parse(test_case.input)
168
+ assert_equal test_case.canonical, Avro::SchemaNormalization.to_parsing_form(schema)
169
+ end
170
+ end
171
+ end
metadata CHANGED
@@ -1,53 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: avro
3
- version: !ruby/object:Gem::Version
4
- hash: 5
5
- prerelease:
6
- segments:
7
- - 1
8
- - 7
9
- - 7
10
- version: 1.7.7
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.8.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Apache Software Foundation
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2014-07-18 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
- none: false
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 3
27
- segments:
28
- - 0
29
- version: "0"
11
+ date: 2016-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
30
14
  name: multi_json
31
- prerelease: false
32
- requirement: *id001
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
33
20
  type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
34
27
  description: Avro is a data serialization and RPC format
35
- email: avro-dev@hadoop.apache.org
28
+ email: dev@avro.apache.org
36
29
  executables: []
37
-
38
30
  extensions: []
39
-
40
- extra_rdoc_files:
31
+ extra_rdoc_files:
41
32
  - CHANGELOG
33
+ - LICENSE
42
34
  - lib/avro.rb
43
35
  - lib/avro/data_file.rb
44
36
  - lib/avro/io.rb
45
37
  - lib/avro/ipc.rb
46
38
  - lib/avro/protocol.rb
47
39
  - lib/avro/schema.rb
48
- files:
40
+ - lib/avro/schema_normalization.rb
41
+ files:
49
42
  - CHANGELOG
43
+ - LICENSE
50
44
  - Manifest
45
+ - NOTICE
51
46
  - Rakefile
52
47
  - avro.gemspec
53
48
  - interop/test_interop.rb
@@ -57,58 +52,55 @@ files:
57
52
  - lib/avro/ipc.rb
58
53
  - lib/avro/protocol.rb
59
54
  - lib/avro/schema.rb
55
+ - lib/avro/schema_normalization.rb
56
+ - test/case_finder.rb
60
57
  - test/random_data.rb
61
58
  - test/sample_ipc_client.rb
62
59
  - test/sample_ipc_http_client.rb
63
60
  - test/sample_ipc_http_server.rb
64
61
  - test/sample_ipc_server.rb
65
62
  - test/test_datafile.rb
63
+ - test/test_fingerprints.rb
66
64
  - test/test_help.rb
67
65
  - test/test_io.rb
68
66
  - test/test_protocol.rb
67
+ - test/test_schema.rb
68
+ - test/test_schema_normalization.rb
69
69
  - test/test_socket_transport.rb
70
70
  - test/tool.rb
71
- - test/test_schema.rb
72
- homepage: http://hadoop.apache.org/avro/
73
- licenses: []
74
-
71
+ homepage: http://avro.apache.org/
72
+ licenses:
73
+ - Apache License 2.0 (Apache-2.0)
74
+ metadata: {}
75
75
  post_install_message:
76
- rdoc_options:
77
- - --line-numbers
78
- - --title
76
+ rdoc_options:
77
+ - "--line-numbers"
78
+ - "--title"
79
79
  - Avro
80
- require_paths:
80
+ require_paths:
81
81
  - lib
82
- required_ruby_version: !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
85
84
  - - ">="
86
- - !ruby/object:Gem::Version
87
- hash: 3
88
- segments:
89
- - 0
90
- version: "0"
91
- required_rubygems_version: !ruby/object:Gem::Requirement
92
- none: false
93
- requirements:
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
94
89
  - - ">="
95
- - !ruby/object:Gem::Version
96
- hash: 11
97
- segments:
98
- - 1
99
- - 2
100
- version: "1.2"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.2'
101
92
  requirements: []
102
-
103
93
  rubyforge_project: avro
104
- rubygems_version: 1.8.15
94
+ rubygems_version: 2.2.2
105
95
  signing_key:
106
- specification_version: 3
96
+ specification_version: 4
107
97
  summary: Apache Avro for Ruby
108
- test_files:
98
+ test_files:
109
99
  - test/test_datafile.rb
100
+ - test/test_fingerprints.rb
110
101
  - test/test_help.rb
102
+ - test/test_io.rb
111
103
  - test/test_protocol.rb
112
- - test/test_socket_transport.rb
113
104
  - test/test_schema.rb
114
- - test/test_io.rb
105
+ - test/test_schema_normalization.rb
106
+ - test/test_socket_transport.rb