avromatic 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25174d8c67bde4e8a9d7a53dc357ed72db2e1faa08bbf8945d1f93dd69c46942
4
- data.tar.gz: b0b2fce3ddb92a463fade05c2cb29cdadd60037357432c99ece5f892d3b54f45
3
+ metadata.gz: 281093ac30d6f1f5bf7fa5949466ce74b2223968db553e15e473e09c81fc574d
4
+ data.tar.gz: 0a89d649b7b86d8a1cc55dba25af9dfdab2f7789f2c4daa996b0dab6ba7fd210
5
5
  SHA512:
6
- metadata.gz: 6566f793b850761a3d7dc2fa88b403c20ab8402e57d062322843038b473c7daf98b5e2484107063dbc2e9014919fabe1b5ac2e140c8e78f81a552356cbf8c5a2
7
- data.tar.gz: 25071f9751683a41bb23fc7932e8570b663c87e903a4ad5d953da863e92c47f0e464355278ec712af41490b7abdc6ac6f11f004472ef3b802e274c8ddf83f503
6
+ metadata.gz: e13e24a119085b1bf8e6f31d83cda3a8d99092026006601a48d21c29516eefb511d1cccaa3080f346bb91b91397433787638b13ee8e2980286b8c06cf0300d07
7
+ data.tar.gz: 8151877e50ab9e2ca498ea52f990c3fce6e5a87a31972c09cea6bbe1c5654265f52e2a7c5dd577d934b0fdd1b8adf7eee1123481333714c4dedef42afd5d83e4
@@ -1,6 +1,11 @@
1
1
  # avromatic changelog
2
2
 
3
- ## v2.0.0 (unreleased)
3
+ ## v2.0.1
4
+ - Allow generated model attribute accessors to be overridden. This was a regression in Avromatic 2.0.0.
5
+ - Ensure that timestamp-millis are coerced when the number of microseconds is divisible by 1,000 but the
6
+ number of nanoseconds is not divisible by 1,000,000.
7
+
8
+ ## v2.0.0
4
9
  - Remove [virtus](https://github.com/solnic/virtus) dependency resulting in a 3x performance improvement in model instantation and 1.4x - 2.0x performance improvement in Avro serialization and Avromatic code simplification.
5
10
  - Raise `Avromatic::Model::CoercionError` when attribute values can't be coerced to the target type in model constructors and attribute setters. Previously coercion errors weren't detected until Avro serialization or an explicit call to `valid?`.
6
11
  - Prevent model instances from being constructed with unknown attributes. Previously unknown attributes were ignored.
data/README.md CHANGED
@@ -8,8 +8,8 @@
8
8
  `Avromatic` generates Ruby models from [Avro](http://avro.apache.org/) schemas
9
9
  and provides utilities to encode and decode them.
10
10
 
11
- **This README reflects unreleased changes in Avromatic 2.0. Please see the
12
- [1-0-stable](https://github.com/salsify/avromatic/blob/1-0-stable/README.md) branch for the latest stable release.**
11
+ **This README reflects Avromatic 2.0. Please see the
12
+ [1-0-stable](https://github.com/salsify/avromatic/blob/1-0-stable/README.md) branch for Avromatic 1.0.**
13
13
 
14
14
  ## Installation
15
15
 
@@ -21,7 +21,7 @@ module Avromatic
21
21
  end
22
22
 
23
23
  class AttributeDefinition
24
- attr_reader :name, :type, :field, :default, :owner
24
+ attr_reader :name, :setter_name, :type, :field, :default, :owner
25
25
  delegate :serialize, to: :type
26
26
 
27
27
  def initialize(owner:, field:, type:)
@@ -29,6 +29,7 @@ module Avromatic
29
29
  @field = field
30
30
  @type = type
31
31
  @name = field.name.to_sym
32
+ @setter_name = "#{field.name}=".to_sym
32
33
  @default = if field.default == :no_default
33
34
  nil
34
35
  elsif field.default.duplicable?
@@ -77,13 +78,13 @@ module Avromatic
77
78
  if data.include?(attribute_name)
78
79
  valid_keys << attribute_name
79
80
  value = data.fetch(attribute_name)
80
- _attributes[attribute_name] = attribute_definition.coerce(value)
81
+ send(attribute_definition.setter_name, value)
81
82
  elsif data.include?(attribute_name.to_s)
82
83
  valid_keys << attribute_name
83
84
  value = data[attribute_name.to_s]
84
- _attributes[attribute_name] = attribute_definition.coerce(value)
85
+ send(attribute_definition.setter_name, value)
85
86
  elsif !attributes.include?(attribute_name)
86
- _attributes[attribute_name] = attribute_definition.default
87
+ send(attribute_definition.setter_name, attribute_definition.default)
87
88
  end
88
89
  end
89
90
 
@@ -111,7 +112,7 @@ module Avromatic
111
112
  end
112
113
 
113
114
  module ClassMethods
114
- def add_avro_fields
115
+ def add_avro_fields(generated_methods_module)
115
116
  # models are registered in Avromatic.nested_models at this point to
116
117
  # ensure that they are available as fields for recursive models.
117
118
  register!
@@ -119,13 +120,13 @@ module Avromatic
119
120
  if key_avro_schema
120
121
  check_for_field_conflicts!
121
122
  begin
122
- define_avro_attributes(key_avro_schema,
123
+ define_avro_attributes(key_avro_schema, generated_methods_module,
123
124
  allow_optional: config.allow_optional_key_fields)
124
125
  rescue OptionalFieldError => ex
125
126
  raise "Optional field '#{ex.field.name}' not allowed in key schema."
126
127
  end
127
128
  end
128
- define_avro_attributes(avro_schema)
129
+ define_avro_attributes(avro_schema, generated_methods_module)
129
130
  end
130
131
 
131
132
  private
@@ -151,7 +152,7 @@ module Avromatic
151
152
  value_avro_fields_by_name[name].to_avro
152
153
  end
153
154
 
154
- def define_avro_attributes(schema, allow_optional: true)
155
+ def define_avro_attributes(schema, generated_methods_module, allow_optional: true)
155
156
  if schema.type_sym != :record
156
157
  raise "Unsupported schema type '#{schema.type_sym}', only 'record' schemas are supported."
157
158
  end
@@ -163,33 +164,25 @@ module Avromatic
163
164
  attribute_definition = AttributeDefinition.new(
164
165
  owner: self,
165
166
  field: field,
166
- type: create_type(field)
167
+ type: Avromatic::Model::Types::TypeFactory.create(schema: field.type, nested_models: nested_models)
167
168
  )
168
169
  attribute_definitions[symbolized_field_name] = attribute_definition
169
170
 
170
- define_method(field.name) { _attributes[symbolized_field_name] }
171
- define_method("#{field.name}?") { !!_attributes[symbolized_field_name] } if boolean?(field)
171
+ # Add all generated methods to a module so they can be overridden
172
+ generated_methods_module.send(:define_method, field.name) { _attributes[symbolized_field_name] }
173
+ generated_methods_module.send(:define_method, "#{field.name}?") { !!_attributes[symbolized_field_name] } if FieldHelper.boolean?(field)
172
174
 
173
- define_method("#{field.name}=") do |value|
175
+ generated_methods_module.send(:define_method, "#{field.name}=") do |value|
174
176
  _attributes[symbolized_field_name] = attribute_definitions[symbolized_field_name].coerce(value)
175
177
  end
176
178
 
177
179
  unless config.mutable # rubocop:disable Style/Next
178
- private("#{field.name}=")
179
- define_method(:clone) { self }
180
- define_method(:dup) { self }
180
+ generated_methods_module.send(:private, "#{field.name}=")
181
+ generated_methods_module.send(:define_method, :clone) { self }
182
+ generated_methods_module.send(:define_method, :dup) { self }
181
183
  end
182
184
  end
183
185
  end
184
-
185
- def boolean?(field)
186
- field.type.type_sym == :boolean ||
187
- (FieldHelper.optional?(field) && field.type.schemas.last.type_sym == :boolean)
188
- end
189
-
190
- def create_type(field)
191
- Avromatic::Model::Types::TypeFactory.create(schema: field.type, nested_models: nested_models)
192
- end
193
186
  end
194
187
 
195
188
  end
@@ -22,7 +22,7 @@ module Avromatic
22
22
  attr_reader :mod, :config
23
23
 
24
24
  # For options see Avromatic::Model.build
25
- def self.model(**options)
25
+ def self.model(**options, &block)
26
26
  Class.new do
27
27
  include Avromatic::Model::Builder.new(**options).mod
28
28
 
@@ -30,6 +30,8 @@ module Avromatic
30
30
  def self.name
31
31
  super || (@name ||= config.avro_schema.name.classify)
32
32
  end
33
+
34
+ class_eval(&block) if block
33
35
  end
34
36
  end
35
37
 
@@ -55,18 +57,14 @@ module Avromatic
55
57
  private
56
58
 
57
59
  def define_included_method
58
- with_builder do |builder|
59
- mod.define_singleton_method(:included) do |model_class|
60
- model_class.include(*builder.inclusions)
61
- model_class.config = builder.config
62
- model_class.add_avro_fields
63
- end
60
+ local_mod = mod
61
+ local_builder = self
62
+ mod.define_singleton_method(:included) do |model_class|
63
+ model_class.include(*local_builder.inclusions)
64
+ model_class.config = local_builder.config
65
+ model_class.add_avro_fields(local_mod)
64
66
  end
65
67
  end
66
-
67
- def with_builder
68
- yield(self)
69
- end
70
68
  end
71
69
  end
72
70
  end
@@ -15,6 +15,11 @@ module Avromatic
15
15
  def required?(field)
16
16
  !optional?(field)
17
17
  end
18
+
19
+ def boolean?(field)
20
+ field.type.type_sym == :boolean ||
21
+ (FieldHelper.optional?(field) && field.type.schemas.last.type_sym == :boolean)
22
+ end
18
23
  end
19
24
  end
20
25
  end
@@ -16,7 +16,7 @@ module Avromatic
16
16
  private
17
17
 
18
18
  def truncated?(value)
19
- value.nsec % 1000 == 0
19
+ value.nsec % 1_000 == 0
20
20
  end
21
21
 
22
22
  def coerce_time(input)
@@ -16,7 +16,7 @@ module Avromatic
16
16
  private
17
17
 
18
18
  def truncated?(value)
19
- value.usec % 1000 == 0
19
+ value.nsec % 1_000_000 == 0
20
20
  end
21
21
 
22
22
  def coerce_time(input)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Avromatic
4
- VERSION = '2.0.0'
4
+ VERSION = '2.0.1'
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.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salsify Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-22 00:00:00.000000000 Z
11
+ date: 2018-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel