avromatic 2.2.1 → 2.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +8 -15
  4. data/Appraisals +16 -22
  5. data/CHANGELOG.md +16 -0
  6. data/README.md +1 -1
  7. data/avromatic.gemspec +4 -4
  8. data/gemfiles/{rails5_0.gemfile → avro1_10_rails5_2.gemfile} +3 -3
  9. data/gemfiles/{rails5_1.gemfile → avro1_10_rails6_0.gemfile} +3 -3
  10. data/gemfiles/{rails5_2.gemfile → avro1_8_rails5_2.gemfile} +0 -0
  11. data/gemfiles/{avro_patches_rails5_0.gemfile → avro1_9_rails5_2.gemfile} +3 -3
  12. data/gemfiles/{rails6_0.gemfile → avro1_9_rails6_0.gemfile} +1 -1
  13. data/gemfiles/avro_patches_rails5_2.gemfile +1 -1
  14. data/lib/avromatic.rb +1 -3
  15. data/lib/avromatic/io/datum_reader.rb +1 -1
  16. data/lib/avromatic/model/attributes.rb +6 -6
  17. data/lib/avromatic/model/configurable.rb +24 -0
  18. data/lib/avromatic/model/nested_models.rb +13 -2
  19. data/lib/avromatic/model/raw_serialization.rb +12 -9
  20. data/lib/avromatic/model/types/abstract_timestamp_type.rb +1 -1
  21. data/lib/avromatic/model/types/abstract_type.rb +10 -1
  22. data/lib/avromatic/model/types/array_type.rb +6 -2
  23. data/lib/avromatic/model/types/boolean_type.rb +5 -1
  24. data/lib/avromatic/model/types/custom_type.rb +5 -1
  25. data/lib/avromatic/model/types/date_type.rb +5 -1
  26. data/lib/avromatic/model/types/enum_type.rb +5 -1
  27. data/lib/avromatic/model/types/fixed_type.rb +5 -1
  28. data/lib/avromatic/model/types/float_type.rb +5 -1
  29. data/lib/avromatic/model/types/integer_type.rb +5 -1
  30. data/lib/avromatic/model/types/map_type.rb +7 -2
  31. data/lib/avromatic/model/types/null_type.rb +5 -1
  32. data/lib/avromatic/model/types/record_type.rb +5 -1
  33. data/lib/avromatic/model/types/string_type.rb +6 -2
  34. data/lib/avromatic/model/types/timestamp_micros_type.rb +4 -1
  35. data/lib/avromatic/model/types/timestamp_millis_type.rb +4 -1
  36. data/lib/avromatic/model/types/union_type.rb +6 -2
  37. data/lib/avromatic/model_registry.rb +2 -1
  38. data/lib/avromatic/rspec.rb +6 -1
  39. data/lib/avromatic/version.rb +1 -1
  40. metadata +48 -49
  41. data/gemfiles/avro_patches_rails5_1.gemfile +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2506f67a4583f29252bd64effa9a5891e09d7ae6a6de458bdb5546592fd151f6
4
- data.tar.gz: a32641d0bd7ca448bdc35226dcb795791c1c0c8aab3ea9770bc950e85b32a832
3
+ metadata.gz: 5038f6f83ba2ca87bc8cd16a96aae5528397ca5cf9ef01d955861459ae68391a
4
+ data.tar.gz: 83f5e8bb53086297882f77108480976292a2ca97b40dcb3da5a23c579a7c1edd
5
5
  SHA512:
6
- metadata.gz: 427096144ac8c8d9544ea460a96eb93813fa977089b80c2616ad17e21784928b448bdb1a5d38aba0c4dde892e1caf3b331e444196ecc937c88bbbbc23eb14572
7
- data.tar.gz: 3a220e5ad23058c054b43e872a3bb81ab1018fc4ef40714a723b31cd93ae560518fac6ab9475993503369d8a8950991f283e2fc113c09bc3c66cf40ecf6d9cb5
6
+ metadata.gz: 5d5f8501fc5e050db26475ea1205a1c08f864d6fae8272e54c4a04df4fb22bf634868dadde7eade371a6b22f5438423f84a6405808286b1c687fb7acb26859c3
7
+ data.tar.gz: 7025885a25ab59923d8efc08e494a51f3c6bc57f0e72eedc84c00b9b46c1ef1df085d99ba9135d6997a8370f3fb1497690a714ca067896faad1a2e9a25f0e970
@@ -1 +1 @@
1
- 2.5.1
1
+ 2.5.8
@@ -1,23 +1,16 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.6.3
4
- - 2.5.5
5
- - 2.4.6
3
+ - 2.5.8
4
+ - 2.6.6
5
+ - 2.7.1
6
6
  before_script:
7
7
  - bundle exec rubocop
8
8
  gemfile:
9
- - gemfiles/rails5_0.gemfile
10
- - gemfiles/rails5_1.gemfile
11
- - gemfiles/rails5_2.gemfile
12
- - gemfiles/rails6_0.gemfile
13
- - gemfiles/avro_patches_rails5_0.gemfile
14
- - gemfiles/avro_patches_rails5_1.gemfile
9
+ - gemfiles/avro1_8_rails5_2.gemfile
10
+ - gemfiles/avro1_9_rails5_2.gemfile
11
+ - gemfiles/avro1_10_rails5_2.gemfile
12
+ - gemfiles/avro1_9_rails6_0.gemfile
13
+ - gemfiles/avro1_10_rails6_0.gemfile
15
14
  - gemfiles/avro_patches_rails5_2.gemfile
16
15
  - gemfiles/avro_patches_rails6_0.gemfile
17
16
  script: bundle exec rspec
18
- matrix:
19
- exclude:
20
- - rvm: 2.4.6
21
- gemfile: gemfiles/rails6_0.gemfile
22
- - rvm: 2.4.6
23
- gemfile: gemfiles/avro_patches_rails6_0.gemfile
data/Appraisals CHANGED
@@ -1,43 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'rails5_0' do
3
+ appraise 'avro1_8-rails5_2' do
4
4
  gem 'avro', '1.8.2'
5
- gem 'activesupport', '~> 5.0.6'
6
- gem 'activemodel', '~> 5.0.6'
5
+ gem 'activesupport', '~> 5.2.0'
6
+ gem 'activemodel', '~> 5.2.0'
7
7
  end
8
8
 
9
- appraise 'rails5_1' do
10
- gem 'avro', '1.8.2'
11
- gem 'activesupport', '~> 5.1.4'
12
- gem 'activemodel', '~> 5.1.4'
9
+ appraise 'avro1_9-rails5_2' do
10
+ gem 'avro', '1.9.2'
11
+ gem 'activesupport', '~> 5.2.0'
12
+ gem 'activemodel', '~> 5.2.0'
13
13
  end
14
14
 
15
- appraise 'rails5_2' do
16
- gem 'avro', '1.8.2'
15
+ appraise 'avro1_10-rails5_2' do
16
+ gem 'avro', '~> 1.10.0'
17
17
  gem 'activesupport', '~> 5.2.0'
18
18
  gem 'activemodel', '~> 5.2.0'
19
19
  end
20
20
 
21
- appraise 'rails6_0' do
22
- gem 'avro', '1.9.0'
21
+ appraise 'avro1_9-rails6_0' do
22
+ gem 'avro', '1.9.2'
23
23
  gem 'activesupport', '~> 6.0.0'
24
24
  gem 'activemodel', '~> 6.0.0'
25
25
  end
26
26
 
27
- appraise 'avro-patches-rails5_0' do
28
- gem 'avro-patches'
29
- gem 'activesupport', '~> 5.0.6'
30
- gem 'activemodel', '~> 5.0.6'
31
- end
32
-
33
- appraise 'avro-patches-rails5_1' do
34
- gem 'avro-patches', '>= 0.4.1'
35
- gem 'activesupport', '~> 5.1.4'
36
- gem 'activemodel', '~> 5.1.4'
27
+ appraise 'avro1_10-rails6_0' do
28
+ gem 'avro', '~> 1.10.0'
29
+ gem 'activesupport', '~> 6.0.0'
30
+ gem 'activemodel', '~> 6.0.0'
37
31
  end
38
32
 
39
33
  appraise 'avro-patches-rails5_2' do
40
- gem 'avro-patches', '>= 0.4.1'
34
+ gem 'avro-patches', '>= 0.4.1', '< 1.0'
41
35
  gem 'activesupport', '~> 5.2.0'
42
36
  gem 'activemodel', '~> 5.2.0'
43
37
  end
@@ -1,5 +1,21 @@
1
1
  # avromatic changelog
2
2
 
3
+ ## v2.2.6
4
+ - Optimize memory usage when serializing models.
5
+
6
+ ## v2.2.5
7
+ - Optimize memory usage when serializing, deserializing and instantiating models.
8
+
9
+ ## v2.2.4
10
+ - Compatibility with Avro v1.10.x.
11
+
12
+ ## v2.2.3
13
+ - Fix bug where method `#referenced_model_classes` was declared as private instead of public.
14
+
15
+ ## v2.2.2
16
+ - Fix missing models in the model registry when in development by loading the nested models of eager loaded models.
17
+ - Fake schema registry support for stubbing URLs with usernames and passwords.
18
+
3
19
  ## v2.2.1
4
20
  - Avoid allocating default empty hash in `Avromatic::IO::DatumReader.read_data`
5
21
 
data/README.md CHANGED
@@ -142,7 +142,7 @@ instance.eql?(MyModel.new(id: 123, name: 'Tesla Model 3', enabled: true)) # => t
142
142
  instance.hash # => -1279155042741869898
143
143
 
144
144
  # Retrieve a hash of the model's attributes via to_h, to_hash or attributes
145
- instance .to_h # => {:id=>123, :name=>"Tesla Model 3", :enabled=>true}
145
+ instance.to_h # => {:id=>123, :name=>"Tesla Model 3", :enabled=>true}
146
146
  ```
147
147
 
148
148
  Or an `Avro::Schema` object can be specified directly:
@@ -24,20 +24,20 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_runtime_dependency 'activemodel', '>= 5.0', '< 6.1'
26
26
  spec.add_runtime_dependency 'activesupport', '>= 5.0', '< 6.1'
27
- spec.add_runtime_dependency 'avro', '>= 1.7.7', '< 1.10'
27
+ spec.add_runtime_dependency 'avro', '>= 1.7.7', '< 1.11'
28
28
  spec.add_runtime_dependency 'avro_schema_registry-client', '>= 0.3.0'
29
29
  spec.add_runtime_dependency 'avro_turf'
30
30
  spec.add_runtime_dependency 'ice_nine'
31
31
 
32
+ spec.add_development_dependency 'appraisal'
32
33
  spec.add_development_dependency 'avro-builder', '>= 0.12.0'
33
34
  spec.add_development_dependency 'bundler', '>= 1.11'
35
+ spec.add_development_dependency 'overcommit', '0.35.0'
34
36
  spec.add_development_dependency 'rake', '~> 10.0'
35
37
  spec.add_development_dependency 'rspec', '~> 3.0'
38
+ spec.add_development_dependency 'salsify_rubocop', '~> 0.52.1.1'
36
39
  spec.add_development_dependency 'simplecov'
37
40
  spec.add_development_dependency 'webmock'
38
41
  # For AvroSchemaRegistry::FakeServer
39
- spec.add_development_dependency 'appraisal'
40
- spec.add_development_dependency 'overcommit', '0.35.0'
41
- spec.add_development_dependency 'salsify_rubocop', '~> 0.52.1.1'
42
42
  spec.add_development_dependency 'sinatra'
43
43
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "avro", "1.8.2"
6
- gem "activesupport", "~> 5.0.6"
7
- gem "activemodel", "~> 5.0.6"
5
+ gem "avro", "~> 1.10.0"
6
+ gem "activesupport", "~> 5.2.0"
7
+ gem "activemodel", "~> 5.2.0"
8
8
 
9
9
  gemspec path: "../"
@@ -2,8 +2,8 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "avro", "1.8.2"
6
- gem "activesupport", "~> 5.1.4"
7
- gem "activemodel", "~> 5.1.4"
5
+ gem "avro", "~> 1.10.0"
6
+ gem "activesupport", "~> 6.0.0"
7
+ gem "activemodel", "~> 6.0.0"
8
8
 
9
9
  gemspec path: "../"
@@ -2,8 +2,8 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "avro-patches"
6
- gem "activesupport", "~> 5.0.6"
7
- gem "activemodel", "~> 5.0.6"
5
+ gem "avro", "1.9.2"
6
+ gem "activesupport", "~> 5.2.0"
7
+ gem "activemodel", "~> 5.2.0"
8
8
 
9
9
  gemspec path: "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "avro", "1.9.0"
5
+ gem "avro", "1.9.2"
6
6
  gem "activesupport", "~> 6.0.0"
7
7
  gem "activemodel", "~> 6.0.0"
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "avro-patches", ">= 0.4.1"
5
+ gem "avro-patches", ">= 0.4.1", "< 1.0"
6
6
  gem "activesupport", "~> 5.2.0"
7
7
  gem "activemodel", "~> 5.2.0"
8
8
 
@@ -85,9 +85,7 @@ module Avromatic
85
85
  end
86
86
 
87
87
  def self.eager_load_models!
88
- (@eager_load_model_names || []).each do |model_name|
89
- nested_models.ensure_registered_model(model_name.constantize)
90
- end
88
+ @eager_load_model_names&.each { |model_name| model_name.constantize.register! }
91
89
  end
92
90
  private_class_method :eager_load_models!
93
91
  end
@@ -25,7 +25,7 @@ module Avromatic
25
25
  optional = readers_schema.schemas.first.type_sym == :null
26
26
  union_info = if readers_schema.schemas.size == 2 && optional
27
27
  # Avromatic does not treat the union of null and 1 other type as a union
28
- {}
28
+ nil
29
29
  elsif optional
30
30
  # Avromatic does not treat the null of an optional field as part of the union
31
31
  { UNION_MEMBER_INDEX => rs_index - 1 }
@@ -74,23 +74,23 @@ module Avromatic
74
74
  def initialize(data = {})
75
75
  super()
76
76
 
77
- valid_keys = []
77
+ num_valid_keys = 0
78
78
  attribute_definitions.each do |attribute_name, attribute_definition|
79
79
  if data.include?(attribute_name)
80
- valid_keys << attribute_name
80
+ num_valid_keys += 1
81
81
  value = data.fetch(attribute_name)
82
82
  send(attribute_definition.setter_name, value)
83
83
  elsif data.include?(attribute_definition.name_string)
84
- valid_keys << attribute_name
84
+ num_valid_keys += 1
85
85
  value = data[attribute_definition.name_string]
86
86
  send(attribute_definition.setter_name, value)
87
- elsif !attributes.include?(attribute_name)
87
+ elsif !_attributes.include?(attribute_name)
88
88
  send(attribute_definition.setter_name, attribute_definition.default)
89
89
  end
90
90
  end
91
91
 
92
- unless Avromatic.allow_unknown_attributes || valid_keys.size == data.size
93
- unknown_attributes = (data.keys.map(&:to_s) - valid_keys.map(&:to_s)).sort
92
+ unless Avromatic.allow_unknown_attributes || num_valid_keys == data.size
93
+ unknown_attributes = (data.keys.map(&:to_s) - _attributes.keys.map(&:to_s)).sort
94
94
  allowed_attributes = attribute_definitions.keys.map(&:to_s).sort
95
95
  message = "Unexpected arguments for #{self.class.name}#initialize: #{unknown_attributes.join(', ')}. " \
96
96
  "Only the following arguments are allowed: #{allowed_attributes.join(', ')}. Provided arguments: #{data.inspect}"
@@ -8,6 +8,17 @@ module Avromatic
8
8
  module Configurable
9
9
  extend ActiveSupport::Concern
10
10
 
11
+ # Wraps a reference to a field so we can access both the string and symbolized versions of the name
12
+ # without repeated memory allocations.
13
+ class FieldReference
14
+ attr_reader :name, :name_sym
15
+
16
+ def initialize(name)
17
+ @name = -name
18
+ @name_sym = name.to_sym
19
+ end
20
+ end
21
+
11
22
  module ClassMethods
12
23
  attr_accessor :config
13
24
  delegate :avro_schema, :value_avro_schema, :key_avro_schema, to: :config
@@ -20,6 +31,18 @@ module Avromatic
20
31
  @key_avro_field_names ||= key_avro_schema.fields.map(&:name).map(&:to_sym).freeze
21
32
  end
22
33
 
34
+ def value_avro_field_references
35
+ @value_avro_field_references ||= value_avro_schema.fields.map do |field|
36
+ Avromatic::Model::Configurable::FieldReference.new(field.name)
37
+ end.freeze
38
+ end
39
+
40
+ def key_avro_field_references
41
+ @key_avro_field_references ||= key_avro_schema.fields.map do |field|
42
+ Avromatic::Model::Configurable::FieldReference.new(field.name)
43
+ end.freeze
44
+ end
45
+
23
46
  def value_avro_fields_by_name
24
47
  @value_avro_fields_by_name ||= mapped_by_name(value_avro_schema)
25
48
  end
@@ -43,6 +66,7 @@ module Avromatic
43
66
 
44
67
  delegate :avro_schema, :value_avro_schema, :key_avro_schema,
45
68
  :value_avro_field_names, :key_avro_field_names,
69
+ :value_avro_field_references, :key_avro_field_references,
46
70
  to: :class
47
71
  end
48
72
  end
@@ -12,10 +12,21 @@ module Avromatic
12
12
  module ClassMethods
13
13
  # Register this model if it can be used as a nested model.
14
14
  def register!
15
- if key_avro_schema.nil? && value_avro_schema.type_sym == :record
16
- nested_models.register(self)
15
+ return unless key_avro_schema.nil? && value_avro_schema.type_sym == :record
16
+
17
+ roots = [self]
18
+ until roots.empty?
19
+ model = roots.shift
20
+ next if nested_models.registered?(model)
21
+
22
+ nested_models.register(model)
23
+ roots.concat(model.referenced_model_classes)
17
24
  end
18
25
  end
26
+
27
+ def referenced_model_classes
28
+ attribute_definitions.values.flat_map { |definition| definition.type.referenced_model_classes }.freeze
29
+ end
19
30
  end
20
31
  end
21
32
  end
@@ -29,34 +29,37 @@ module Avromatic
29
29
 
30
30
  def value_attributes_for_avro(validate: true)
31
31
  if self.class.config.mutable
32
- avro_hash(value_avro_field_names, validate: validate)
32
+ avro_hash(value_avro_field_references, validate: validate)
33
33
  else
34
- @value_attributes_for_avro ||= avro_hash(value_avro_field_names, validate: validate)
34
+ @value_attributes_for_avro ||= avro_hash(value_avro_field_references, validate: validate)
35
35
  end
36
36
  end
37
37
 
38
38
  def key_attributes_for_avro(validate: true)
39
- avro_hash(key_avro_field_names, validate: validate)
39
+ avro_hash(key_avro_field_references, validate: validate)
40
40
  end
41
41
 
42
42
  def avro_value_datum(validate: true)
43
43
  if self.class.config.mutable
44
- avro_hash(value_avro_field_names, strict: true, validate: validate)
44
+ avro_hash(value_avro_field_references, strict: true, validate: validate)
45
45
  else
46
- @avro_datum ||= avro_hash(value_avro_field_names, strict: true, validate: validate)
46
+ @avro_datum ||= avro_hash(value_avro_field_references, strict: true, validate: validate)
47
47
  end
48
48
  end
49
49
 
50
50
  def avro_key_datum(validate: true)
51
- avro_hash(key_avro_field_names, strict: true, validate: validate)
51
+ avro_hash(key_avro_field_references, strict: true, validate: validate)
52
52
  end
53
53
 
54
54
  private
55
55
 
56
- def avro_hash(fields, strict: false, validate:)
56
+ def avro_hash(field_references, strict: false, validate:)
57
57
  avro_validate! if validate
58
- attributes.slice(*fields).each_with_object(Hash.new) do |(key, value), result|
59
- result[key.to_s] = attribute_definitions[key].serialize(value, strict: strict)
58
+ field_references.each_with_object(Hash.new) do |field_reference, result|
59
+ next unless _attributes.include?(field_reference.name_sym)
60
+
61
+ value = _attributes[field_reference.name_sym]
62
+ result[field_reference.name] = attribute_definitions[field_reference.name_sym].serialize(value, strict)
60
63
  end
61
64
  end
62
65
 
@@ -38,7 +38,7 @@ module Avromatic
38
38
  value.is_a?(::Time) && value.class != ActiveSupport::TimeWithZone && truncated?(value)
39
39
  end
40
40
 
41
- def serialize(value, **)
41
+ def serialize(value, _strict)
42
42
  value
43
43
  end
44
44
 
@@ -4,6 +4,9 @@ module Avromatic
4
4
  module Model
5
5
  module Types
6
6
  class AbstractType
7
+ EMPTY_ARRAY = [].freeze
8
+ private_constant :EMPTY_ARRAY
9
+
7
10
  def value_classes
8
11
  raise "#{__method__} must be overridden by #{self.class.name}"
9
12
  end
@@ -28,7 +31,13 @@ module Avromatic
28
31
  raise "#{__method__} must be overridden by #{self.class.name}"
29
32
  end
30
33
 
31
- def serialize(_value, **)
34
+ # Note we use positional args rather than keyword args to reduce
35
+ # memory allocations
36
+ def serialize(_value, _strict)
37
+ raise "#{__method__} must be overridden by #{self.class.name}"
38
+ end
39
+
40
+ def referenced_model_classes
32
41
  raise "#{__method__} must be overridden by #{self.class.name}"
33
42
  end
34
43
  end
@@ -40,13 +40,17 @@ module Avromatic
40
40
  value.nil? || (value.is_a?(::Array) && value.all? { |element| value_type.coerced?(element) })
41
41
  end
42
42
 
43
- def serialize(value, strict:)
43
+ def serialize(value, strict)
44
44
  if value.nil?
45
45
  value
46
46
  else
47
- value.map { |element| value_type.serialize(element, strict: strict) }
47
+ value.map { |element| value_type.serialize(element, strict) }
48
48
  end
49
49
  end
50
+
51
+ def referenced_model_classes
52
+ value_type.referenced_model_classes
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -30,9 +30,13 @@ module Avromatic
30
30
 
31
31
  alias_method :coerced?, :coercible?
32
32
 
33
- def serialize(value, **)
33
+ def serialize(value, _strict)
34
34
  value
35
35
  end
36
+
37
+ def referenced_model_classes
38
+ EMPTY_ARRAY
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -55,9 +55,13 @@ module Avromatic
55
55
  false
56
56
  end
57
57
 
58
- def serialize(value, **)
58
+ def serialize(value, _strict)
59
59
  @serializer.call(value)
60
60
  end
61
+
62
+ def referenced_model_classes
63
+ default_type.referenced_model_classes
64
+ end
61
65
  end
62
66
  end
63
67
  end
@@ -32,9 +32,13 @@ module Avromatic
32
32
 
33
33
  alias_method :coerced?, :coercible?
34
34
 
35
- def serialize(value, **)
35
+ def serialize(value, _strict)
36
36
  value
37
37
  end
38
+
39
+ def referenced_model_classes
40
+ EMPTY_ARRAY
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -47,9 +47,13 @@ module Avromatic
47
47
  (input.is_a?(::Symbol) && allowed_values.include?(input.to_s))
48
48
  end
49
49
 
50
- def serialize(value, **)
50
+ def serialize(value, _strict)
51
51
  value
52
52
  end
53
+
54
+ def referenced_model_classes
55
+ EMPTY_ARRAY
56
+ end
53
57
  end
54
58
  end
55
59
  end
@@ -36,9 +36,13 @@ module Avromatic
36
36
 
37
37
  alias_method :coerced?, :coercible?
38
38
 
39
- def serialize(value, **)
39
+ def serialize(value, _strict)
40
40
  value
41
41
  end
42
+
43
+ def referenced_model_classes
44
+ EMPTY_ARRAY
45
+ end
42
46
  end
43
47
  end
44
48
  end
@@ -39,9 +39,13 @@ module Avromatic
39
39
  input.nil? || input.is_a?(::Float)
40
40
  end
41
41
 
42
- def serialize(value, **)
42
+ def serialize(value, _strict)
43
43
  value
44
44
  end
45
+
46
+ def referenced_model_classes
47
+ EMPTY_ARRAY
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -30,9 +30,13 @@ module Avromatic
30
30
 
31
31
  alias_method :coerced?, :coercible?
32
32
 
33
- def serialize(value, **)
33
+ def serialize(value, _strict)
34
34
  value
35
35
  end
36
+
37
+ def referenced_model_classes
38
+ EMPTY_ARRAY
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -59,15 +59,20 @@ module Avromatic
59
59
  end
60
60
  end
61
61
 
62
- def serialize(value, strict:)
62
+ def serialize(value, strict)
63
63
  if value.nil?
64
64
  value
65
65
  else
66
66
  value.each_with_object({}) do |(element_key, element_value), result|
67
- result[key_type.serialize(element_key, strict: strict)] = value_type.serialize(element_value, strict: strict)
67
+ result[key_type.serialize(element_key, strict)] = value_type.serialize(element_value, strict)
68
68
  end
69
69
  end
70
70
  end
71
+
72
+ def referenced_model_classes
73
+ # According to Avro's spec, keys can only be strings, so we can safely disregard #key_type here.
74
+ value_type.referenced_model_classes
75
+ end
71
76
  end
72
77
  end
73
78
  end
@@ -30,9 +30,13 @@ module Avromatic
30
30
 
31
31
  alias_method :coerced?, :coercible?
32
32
 
33
- def serialize(_value, **)
33
+ def serialize(_value, _strict)
34
34
  nil
35
35
  end
36
+
37
+ def referenced_model_classes
38
+ EMPTY_ARRAY
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -39,7 +39,7 @@ module Avromatic
39
39
  value.nil? || value.is_a?(record_class)
40
40
  end
41
41
 
42
- def serialize(value, strict:)
42
+ def serialize(value, strict)
43
43
  if value.nil?
44
44
  value
45
45
  elsif !strict && Avromatic.use_custom_datum_writer && Avromatic.use_encoding_providers? && !record_class.config.mutable
@@ -51,6 +51,10 @@ module Avromatic
51
51
  strict ? value.avro_value_datum(validate: false) : value.value_attributes_for_avro(validate: false)
52
52
  end
53
53
  end
54
+
55
+ def referenced_model_classes
56
+ [record_class].freeze
57
+ end
54
58
  end
55
59
  end
56
60
  end
@@ -5,7 +5,7 @@ require 'avromatic/model/types/abstract_type'
5
5
  module Avromatic
6
6
  module Model
7
7
  module Types
8
- class StringType
8
+ class StringType < AbstractType
9
9
  VALUE_CLASSES = [::String].freeze
10
10
  INPUT_CLASSES = [::String, ::Symbol].freeze
11
11
 
@@ -39,9 +39,13 @@ module Avromatic
39
39
  value.nil? || value.is_a?(::String)
40
40
  end
41
41
 
42
- def serialize(value, **)
42
+ def serialize(value, _strict)
43
43
  value
44
44
  end
45
+
46
+ def referenced_model_classes
47
+ EMPTY_ARRAY
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -13,6 +13,10 @@ module Avromatic
13
13
  'timestamp-micros'
14
14
  end
15
15
 
16
+ def referenced_model_classes
17
+ EMPTY_ARRAY
18
+ end
19
+
16
20
  private
17
21
 
18
22
  def truncated?(value)
@@ -25,7 +29,6 @@ module Avromatic
25
29
  # of time zone.
26
30
  ::Time.at(input.to_i, input.usec)
27
31
  end
28
-
29
32
  end
30
33
  end
31
34
  end
@@ -13,6 +13,10 @@ module Avromatic
13
13
  'timestamp-millis'
14
14
  end
15
15
 
16
+ def referenced_model_classes
17
+ EMPTY_ARRAY
18
+ end
19
+
16
20
  private
17
21
 
18
22
  def truncated?(value)
@@ -25,7 +29,6 @@ module Avromatic
25
29
  # of time zone.
26
30
  ::Time.at(input.to_i, input.usec / 1000 * 1000)
27
31
  end
28
-
29
32
  end
30
33
  end
31
34
  end
@@ -51,7 +51,7 @@ module Avromatic
51
51
  end
52
52
  end
53
53
 
54
- def serialize(value, strict:)
54
+ def serialize(value, strict)
55
55
  # Avromatic does not treat the null of an optional field as part of the union
56
56
  return nil if value.nil?
57
57
 
@@ -60,13 +60,17 @@ module Avromatic
60
60
  raise ArgumentError.new("Expected #{value.inspect} to be one of #{value_classes.map(&:name)}")
61
61
  end
62
62
 
63
- hash = member_types[member_index].serialize(value, strict: strict)
63
+ hash = member_types[member_index].serialize(value, strict)
64
64
  if !strict && Avromatic.use_custom_datum_writer && value.is_a?(Avromatic::Model::Attributes)
65
65
  hash[Avromatic::IO::UNION_MEMBER_INDEX] = member_index
66
66
  end
67
67
  hash
68
68
  end
69
69
 
70
+ def referenced_model_classes
71
+ member_types.flat_map(&:referenced_model_classes).tap(&:uniq!).freeze
72
+ end
73
+
70
74
  private
71
75
 
72
76
  def find_index(value)
@@ -29,7 +29,8 @@ module Avromatic
29
29
  @hash[name] = model
30
30
  end
31
31
 
32
- def registered?(fullname)
32
+ def registered?(fullname_or_model)
33
+ fullname = fullname_or_model.is_a?(String) ? fullname_or_model : model_fullname(fullname_or_model)
33
34
  @hash.key?(fullname)
34
35
  end
35
36
 
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
3
4
  require 'webmock/rspec'
4
5
  require 'avro_schema_registry/test/fake_server'
5
6
 
6
7
  RSpec.configure do |config|
7
8
  config.before(:each) do
8
- WebMock.stub_request(:any, /^#{Avromatic.registry_url}/).to_rack(AvroSchemaRegistry::FakeServer)
9
+ # Strip the username/password from the URL so WebMock can match the URL
10
+ registry_uri = URI(Avromatic.registry_url)
11
+ registry_uri.userinfo = ''
12
+
13
+ WebMock.stub_request(:any, /^#{registry_uri}/).to_rack(AvroSchemaRegistry::FakeServer)
9
14
  AvroSchemaRegistry::FakeServer.clear
10
15
  Avromatic.build_messaging!
11
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Avromatic
4
- VERSION = '2.2.1'
4
+ VERSION = '2.2.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avromatic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salsify Engineering
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-08 00:00:00.000000000 Z
11
+ date: 2020-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -59,7 +59,7 @@ dependencies:
59
59
  version: 1.7.7
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
- version: '1.10'
62
+ version: '1.11'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -69,7 +69,7 @@ dependencies:
69
69
  version: 1.7.7
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '1.10'
72
+ version: '1.11'
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: avro_schema_registry-client
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -112,6 +112,20 @@ dependencies:
112
112
  - - ">="
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
+ - !ruby/object:Gem::Dependency
116
+ name: appraisal
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
115
129
  - !ruby/object:Gem::Dependency
116
130
  name: avro-builder
117
131
  requirement: !ruby/object:Gem::Requirement
@@ -140,6 +154,20 @@ dependencies:
140
154
  - - ">="
141
155
  - !ruby/object:Gem::Version
142
156
  version: '1.11'
157
+ - !ruby/object:Gem::Dependency
158
+ name: overcommit
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '='
162
+ - !ruby/object:Gem::Version
163
+ version: 0.35.0
164
+ type: :development
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - '='
169
+ - !ruby/object:Gem::Version
170
+ version: 0.35.0
143
171
  - !ruby/object:Gem::Dependency
144
172
  name: rake
145
173
  requirement: !ruby/object:Gem::Requirement
@@ -169,21 +197,21 @@ dependencies:
169
197
  - !ruby/object:Gem::Version
170
198
  version: '3.0'
171
199
  - !ruby/object:Gem::Dependency
172
- name: simplecov
200
+ name: salsify_rubocop
173
201
  requirement: !ruby/object:Gem::Requirement
174
202
  requirements:
175
- - - ">="
203
+ - - "~>"
176
204
  - !ruby/object:Gem::Version
177
- version: '0'
205
+ version: 0.52.1.1
178
206
  type: :development
179
207
  prerelease: false
180
208
  version_requirements: !ruby/object:Gem::Requirement
181
209
  requirements:
182
- - - ">="
210
+ - - "~>"
183
211
  - !ruby/object:Gem::Version
184
- version: '0'
212
+ version: 0.52.1.1
185
213
  - !ruby/object:Gem::Dependency
186
- name: webmock
214
+ name: simplecov
187
215
  requirement: !ruby/object:Gem::Requirement
188
216
  requirements:
189
217
  - - ">="
@@ -197,7 +225,7 @@ dependencies:
197
225
  - !ruby/object:Gem::Version
198
226
  version: '0'
199
227
  - !ruby/object:Gem::Dependency
200
- name: appraisal
228
+ name: webmock
201
229
  requirement: !ruby/object:Gem::Requirement
202
230
  requirements:
203
231
  - - ">="
@@ -210,34 +238,6 @@ dependencies:
210
238
  - - ">="
211
239
  - !ruby/object:Gem::Version
212
240
  version: '0'
213
- - !ruby/object:Gem::Dependency
214
- name: overcommit
215
- requirement: !ruby/object:Gem::Requirement
216
- requirements:
217
- - - '='
218
- - !ruby/object:Gem::Version
219
- version: 0.35.0
220
- type: :development
221
- prerelease: false
222
- version_requirements: !ruby/object:Gem::Requirement
223
- requirements:
224
- - - '='
225
- - !ruby/object:Gem::Version
226
- version: 0.35.0
227
- - !ruby/object:Gem::Dependency
228
- name: salsify_rubocop
229
- requirement: !ruby/object:Gem::Requirement
230
- requirements:
231
- - - "~>"
232
- - !ruby/object:Gem::Version
233
- version: 0.52.1.1
234
- type: :development
235
- prerelease: false
236
- version_requirements: !ruby/object:Gem::Requirement
237
- requirements:
238
- - - "~>"
239
- - !ruby/object:Gem::Version
240
- version: 0.52.1.1
241
241
  - !ruby/object:Gem::Dependency
242
242
  name: sinatra
243
243
  requirement: !ruby/object:Gem::Requirement
@@ -276,14 +276,13 @@ files:
276
276
  - bin/console
277
277
  - bin/setup
278
278
  - gemfiles/.bundle/config
279
- - gemfiles/avro_patches_rails5_0.gemfile
280
- - gemfiles/avro_patches_rails5_1.gemfile
279
+ - gemfiles/avro1_10_rails5_2.gemfile
280
+ - gemfiles/avro1_10_rails6_0.gemfile
281
+ - gemfiles/avro1_8_rails5_2.gemfile
282
+ - gemfiles/avro1_9_rails5_2.gemfile
283
+ - gemfiles/avro1_9_rails6_0.gemfile
281
284
  - gemfiles/avro_patches_rails5_2.gemfile
282
285
  - gemfiles/avro_patches_rails6_0.gemfile
283
- - gemfiles/rails5_0.gemfile
284
- - gemfiles/rails5_1.gemfile
285
- - gemfiles/rails5_2.gemfile
286
- - gemfiles/rails6_0.gemfile
287
286
  - lib/avromatic.rb
288
287
  - lib/avromatic/io.rb
289
288
  - lib/avromatic/io/datum_reader.rb
@@ -335,7 +334,7 @@ homepage: https://github.com/salsify/avromatic.git
335
334
  licenses:
336
335
  - MIT
337
336
  metadata: {}
338
- post_install_message:
337
+ post_install_message:
339
338
  rdoc_options: []
340
339
  require_paths:
341
340
  - lib
@@ -350,8 +349,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
350
349
  - !ruby/object:Gem::Version
351
350
  version: '0'
352
351
  requirements: []
353
- rubygems_version: 3.0.6
354
- signing_key:
352
+ rubygems_version: 3.0.8
353
+ signing_key:
355
354
  specification_version: 4
356
355
  summary: Generate Ruby models from Avro schemas
357
356
  test_files: []
@@ -1,9 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "avro-patches", ">= 0.4.1"
6
- gem "activesupport", "~> 5.1.4"
7
- gem "activemodel", "~> 5.1.4"
8
-
9
- gemspec path: "../"