avromatic 2.2.1 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: "../"