avromatic 2.2.6 → 2.4.0
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +85 -0
- data/.rubocop.yml +3 -0
- data/Appraisals +18 -0
- data/CHANGELOG.md +10 -0
- data/README.md +2 -2
- data/avromatic.gemspec +3 -2
- data/bin/console +4 -3
- data/gemfiles/avro1_10_rails6_1.gemfile +9 -0
- data/gemfiles/avro1_9_rails6_1.gemfile +9 -0
- data/gemfiles/avro_patches_rails6_1.gemfile +9 -0
- data/lib/avromatic.rb +0 -5
- data/lib/avromatic/io.rb +1 -7
- data/lib/avromatic/io/datum_reader.rb +18 -68
- data/lib/avromatic/io/datum_writer.rb +5 -11
- data/lib/avromatic/io/union_datum.rb +25 -0
- data/lib/avromatic/messaging.rb +4 -2
- data/lib/avromatic/model/attributes.rb +22 -3
- data/lib/avromatic/model/configurable.rb +6 -2
- data/lib/avromatic/model/configuration.rb +5 -0
- data/lib/avromatic/model/field_helper.rb +5 -1
- data/lib/avromatic/model/messaging_serialization.rb +2 -1
- data/lib/avromatic/model/raw_serialization.rb +65 -25
- data/lib/avromatic/model/types/record_type.rb +3 -6
- data/lib/avromatic/model/types/union_type.rb +10 -7
- data/lib/avromatic/model/validation.rb +2 -2
- data/lib/avromatic/version.rb +1 -1
- metadata +25 -9
- data/.travis.yml +0 -16
- data/lib/avromatic/patches.rb +0 -18
- data/lib/avromatic/patches/schema_validator_patch.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7401c0e72992925f02234f5d3d2ab8e762a36bc62aa25c631569d6f4d9918d2
|
|
4
|
+
data.tar.gz: f2121b2a62bf60893ea0eb143ed83a142ea069d07839fb8121d0618483b469d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42be85747686fca4ec66d6e178f7e5aab6d9e9ab88cd4d107ed1c5de8a83017f083a510889ced33a2eb284f45865b3c32b3a9edad200011aed5b17c284f3a593
|
|
7
|
+
data.tar.gz: be13122bca8693d33e20d1317ae5cd88d8c1c975c08d94ed522d0330d70f202bc43d79d7f2941032bc7540ad83b2d647d3c7d29bb5b72c03a560dfedb85e62f7
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
jobs:
|
|
3
|
+
lint:
|
|
4
|
+
docker:
|
|
5
|
+
- image: salsify/ruby_ci:2.5.8
|
|
6
|
+
working_directory: ~/avromatic
|
|
7
|
+
steps:
|
|
8
|
+
- checkout
|
|
9
|
+
- restore_cache:
|
|
10
|
+
keys:
|
|
11
|
+
- v2-gems-ruby-2.5.8-{{ checksum "avromatic.gemspec" }}-{{ checksum "Gemfile" }}
|
|
12
|
+
- v2-gems-ruby-2.5.8-
|
|
13
|
+
- run:
|
|
14
|
+
name: Install Gems
|
|
15
|
+
command: |
|
|
16
|
+
if ! bundle check --path=vendor/bundle; then
|
|
17
|
+
bundle install --path=vendor/bundle --jobs=4 --retry=3
|
|
18
|
+
bundle clean
|
|
19
|
+
fi
|
|
20
|
+
- save_cache:
|
|
21
|
+
key: v2-gems-ruby-2.5.8-{{ checksum "avromatic.gemspec" }}-{{ checksum "Gemfile" }}
|
|
22
|
+
paths:
|
|
23
|
+
- "vendor/bundle"
|
|
24
|
+
- "gemfiles/vendor/bundle"
|
|
25
|
+
- run:
|
|
26
|
+
name: Run Rubocop
|
|
27
|
+
command: bundle exec rubocop
|
|
28
|
+
test:
|
|
29
|
+
parameters:
|
|
30
|
+
gemfile:
|
|
31
|
+
type: string
|
|
32
|
+
ruby-version:
|
|
33
|
+
type: string
|
|
34
|
+
docker:
|
|
35
|
+
- image: salsify/ruby_ci:<< parameters.ruby-version >>
|
|
36
|
+
environment:
|
|
37
|
+
CIRCLE_TEST_REPORTS: "test-results"
|
|
38
|
+
BUNDLE_GEMFILE: << parameters.gemfile >>
|
|
39
|
+
working_directory: ~/avromatic
|
|
40
|
+
steps:
|
|
41
|
+
- checkout
|
|
42
|
+
- restore_cache:
|
|
43
|
+
keys:
|
|
44
|
+
- v2-gems-ruby-<< parameters.ruby-version >>-{{ checksum "avromatic.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
|
|
45
|
+
- v2-gems-ruby-<< parameters.ruby-version >>-
|
|
46
|
+
- run:
|
|
47
|
+
name: Install Gems
|
|
48
|
+
command: |
|
|
49
|
+
if ! bundle check --path=vendor/bundle; then
|
|
50
|
+
bundle install --path=vendor/bundle --jobs=4 --retry=3
|
|
51
|
+
bundle clean
|
|
52
|
+
fi
|
|
53
|
+
- save_cache:
|
|
54
|
+
key: v2-gems-ruby-<< parameters.ruby-version >>-{{ checksum "avromatic.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
|
|
55
|
+
paths:
|
|
56
|
+
- "vendor/bundle"
|
|
57
|
+
- "gemfiles/vendor/bundle"
|
|
58
|
+
- run:
|
|
59
|
+
name: Run Tests
|
|
60
|
+
command: |
|
|
61
|
+
bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec/junit.xml --format progress spec
|
|
62
|
+
- store_test_results:
|
|
63
|
+
path: "test-results"
|
|
64
|
+
workflows:
|
|
65
|
+
build:
|
|
66
|
+
jobs:
|
|
67
|
+
- lint
|
|
68
|
+
- test:
|
|
69
|
+
matrix:
|
|
70
|
+
parameters:
|
|
71
|
+
gemfile:
|
|
72
|
+
- "gemfiles/avro1_8_rails5_2.gemfile"
|
|
73
|
+
- "gemfiles/avro1_9_rails5_2.gemfile"
|
|
74
|
+
- "gemfiles/avro1_10_rails5_2.gemfile"
|
|
75
|
+
- "gemfiles/avro1_9_rails6_0.gemfile"
|
|
76
|
+
- "gemfiles/avro1_10_rails6_0.gemfile"
|
|
77
|
+
- "gemfiles/avro_patches_rails5_2.gemfile"
|
|
78
|
+
- "gemfiles/avro_patches_rails6_0.gemfile"
|
|
79
|
+
- "gemfiles/avro1_10_rails6_1.gemfile"
|
|
80
|
+
- "gemfiles/avro1_9_rails6_1.gemfile"
|
|
81
|
+
- "gemfiles/avro_patches_rails6_1.gemfile"
|
|
82
|
+
ruby-version:
|
|
83
|
+
- "2.5.8"
|
|
84
|
+
- "2.6.6"
|
|
85
|
+
- "2.7.1"
|
data/.rubocop.yml
CHANGED
data/Appraisals
CHANGED
|
@@ -41,3 +41,21 @@ appraise 'avro-patches-rails6_0' do
|
|
|
41
41
|
gem 'activesupport', '~> 6.0.0'
|
|
42
42
|
gem 'activemodel', '~> 6.0.0'
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
appraise 'avro1_9-rails6_1' do
|
|
46
|
+
gem 'avro', '1.9.2'
|
|
47
|
+
gem 'activesupport', '~> 6.1.0'
|
|
48
|
+
gem 'activemodel', '~> 6.1.0'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
appraise 'avro1_10-rails6_1' do
|
|
52
|
+
gem 'avro', '~> 1.10.0'
|
|
53
|
+
gem 'activesupport', '~> 6.1.0'
|
|
54
|
+
gem 'activemodel', '~> 6.1.0'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
appraise 'avro-patches-rails6_1' do
|
|
58
|
+
gem 'avro-patches', '>= 1.0.0'
|
|
59
|
+
gem 'activesupport', '~> 6.1.0'
|
|
60
|
+
gem 'activemodel', '~> 6.1.0'
|
|
61
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# avromatic changelog
|
|
2
2
|
|
|
3
|
+
## v2.4.0
|
|
4
|
+
- Ignore the `validate` argument and always validate during serialization. This
|
|
5
|
+
argument will be removed in Avromatic 3.0.
|
|
6
|
+
- Optimize model validation during serialization.
|
|
7
|
+
- Don't cache immutable model validation results or serialized Avro attributes if a model has mutable children.
|
|
8
|
+
|
|
9
|
+
## v2.3.0
|
|
10
|
+
- Add support for Rails 6.1.
|
|
11
|
+
- Optimize nested model serialization.
|
|
12
|
+
|
|
3
13
|
## v2.2.6
|
|
4
14
|
- Optimize memory usage when serializing models.
|
|
5
15
|
|
data/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Avromatic
|
|
2
2
|
|
|
3
|
-
[][circleci]
|
|
4
4
|
[](https://badge.fury.io/rb/avromatic)
|
|
5
5
|
|
|
6
|
-
[
|
|
6
|
+
[circleci]: https://circleci.com/gh/salsify/avromatic
|
|
7
7
|
|
|
8
8
|
`Avromatic` generates Ruby models from [Avro](http://avro.apache.org/) schemas
|
|
9
9
|
and provides utilities to encode and decode them.
|
data/avromatic.gemspec
CHANGED
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
|
|
23
23
|
spec.required_ruby_version = '>= 2.4'
|
|
24
24
|
|
|
25
|
-
spec.add_runtime_dependency 'activemodel', '>= 5.0', '< 6.
|
|
26
|
-
spec.add_runtime_dependency 'activesupport', '>= 5.0', '< 6.
|
|
25
|
+
spec.add_runtime_dependency 'activemodel', '>= 5.0', '< 6.2'
|
|
26
|
+
spec.add_runtime_dependency 'activesupport', '>= 5.0', '< 6.2'
|
|
27
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'
|
|
@@ -35,6 +35,7 @@ Gem::Specification.new do |spec|
|
|
|
35
35
|
spec.add_development_dependency 'overcommit', '0.35.0'
|
|
36
36
|
spec.add_development_dependency 'rake', '~> 10.0'
|
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
38
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
|
38
39
|
spec.add_development_dependency 'salsify_rubocop', '~> 0.52.1.1'
|
|
39
40
|
spec.add_development_dependency 'simplecov'
|
|
40
41
|
spec.add_development_dependency 'webmock'
|
data/bin/console
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'avromatic'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +11,5 @@ require "avromatic"
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
require
|
|
14
|
+
require 'irb'
|
|
14
15
|
IRB.start
|
data/lib/avromatic.rb
CHANGED
|
@@ -8,7 +8,6 @@ require 'avromatic/model'
|
|
|
8
8
|
require 'avromatic/model_registry'
|
|
9
9
|
require 'avromatic/messaging'
|
|
10
10
|
require 'active_support/core_ext/string/inflections'
|
|
11
|
-
require 'avromatic/patches'
|
|
12
11
|
|
|
13
12
|
module Avromatic
|
|
14
13
|
class << self
|
|
@@ -33,10 +32,6 @@ module Avromatic
|
|
|
33
32
|
eager_load_models!
|
|
34
33
|
end
|
|
35
34
|
|
|
36
|
-
def self.use_encoding_providers?
|
|
37
|
-
use_custom_datum_writer && defined?(Avromatic::Patches::SchemaValidatorPatch)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
35
|
def self.build_schema_registry
|
|
41
36
|
raise 'Avromatic must be configured with a registry_url' unless registry_url
|
|
42
37
|
if use_schema_fingerprint_lookup
|
data/lib/avromatic/io.rb
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module Avromatic
|
|
4
|
-
module IO
|
|
5
|
-
UNION_MEMBER_INDEX = '__avromatic_member_index'
|
|
6
|
-
ENCODING_PROVIDER = '__avromatic_encoding_provider'
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
3
|
require 'avromatic/io/datum_reader'
|
|
11
4
|
require 'avromatic/io/datum_writer'
|
|
5
|
+
require 'avromatic/io/union_datum'
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rubocop:disable Style/WhenThen
|
|
4
3
|
module Avromatic
|
|
5
4
|
module IO
|
|
6
5
|
# Subclass DatumReader to include additional information about the union
|
|
@@ -8,81 +7,32 @@ module Avromatic
|
|
|
8
7
|
# branch 'salsify-master' with the tag 'v1.9.0.3'
|
|
9
8
|
class DatumReader < Avro::IO::DatumReader
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def read_data(writers_schema, readers_schema, decoder, initial_record = nil)
|
|
14
|
-
# schema matching
|
|
15
|
-
unless self.class.match_schemas(writers_schema, readers_schema)
|
|
16
|
-
raise Avro::IO::SchemaMatchException.new(writers_schema, readers_schema)
|
|
17
|
-
end
|
|
18
|
-
|
|
10
|
+
def read_data(writers_schema, readers_schema, decoder)
|
|
19
11
|
# schema resolution: reader's schema is a union, writer's schema is not
|
|
20
|
-
|
|
21
|
-
rs_index = readers_schema.schemas.find_index do |s|
|
|
22
|
-
self.class.match_schemas(writers_schema, s)
|
|
23
|
-
end
|
|
12
|
+
return super unless writers_schema.type_sym != :union && readers_schema.type_sym == :union
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Avromatic does not treat the union of null and 1 other type as a union
|
|
28
|
-
nil
|
|
29
|
-
elsif optional
|
|
30
|
-
# Avromatic does not treat the null of an optional field as part of the union
|
|
31
|
-
{ UNION_MEMBER_INDEX => rs_index - 1 }
|
|
32
|
-
else
|
|
33
|
-
{ UNION_MEMBER_INDEX => rs_index }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
return read_data(writers_schema, readers_schema.schemas[rs_index], decoder, union_info) if rs_index
|
|
37
|
-
raise Avro::IO::SchemaMatchException.new(writers_schema, readers_schema)
|
|
14
|
+
rs_index = readers_schema.schemas.find_index do |s|
|
|
15
|
+
self.class.match_schemas(writers_schema, s)
|
|
38
16
|
end
|
|
39
17
|
|
|
40
|
-
|
|
41
|
-
datum = case writers_schema.type_sym
|
|
42
|
-
when :null; decoder.read_null
|
|
43
|
-
when :boolean; decoder.read_boolean
|
|
44
|
-
when :string; decoder.read_string
|
|
45
|
-
when :int; decoder.read_int
|
|
46
|
-
when :long; decoder.read_long
|
|
47
|
-
when :float; decoder.read_float
|
|
48
|
-
when :double; decoder.read_double
|
|
49
|
-
when :bytes; decoder.read_bytes
|
|
50
|
-
when :fixed; read_fixed(writers_schema, readers_schema, decoder)
|
|
51
|
-
when :enum; read_enum(writers_schema, readers_schema, decoder)
|
|
52
|
-
when :array; read_array(writers_schema, readers_schema, decoder)
|
|
53
|
-
when :map; read_map(writers_schema, readers_schema, decoder)
|
|
54
|
-
when :union; read_union(writers_schema, readers_schema, decoder)
|
|
55
|
-
when :record, :error, :request; read_record(writers_schema, readers_schema, decoder, initial_record || {})
|
|
56
|
-
else
|
|
57
|
-
raise Avro::AvroError.new("Cannot read unknown schema type: #{writers_schema.type}")
|
|
58
|
-
end
|
|
18
|
+
raise Avro::IO::SchemaMatchException.new(writers_schema, readers_schema) unless rs_index
|
|
59
19
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if readers_schema.respond_to?(:logical_type)
|
|
63
|
-
readers_schema.type_adapter.decode(datum)
|
|
64
|
-
else
|
|
65
|
-
datum
|
|
66
|
-
end
|
|
67
|
-
end
|
|
20
|
+
datum = read_data(writers_schema, readers_schema.schemas[rs_index], decoder)
|
|
21
|
+
optional = readers_schema.schemas.first.type_sym == :null
|
|
68
22
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
end
|
|
23
|
+
if readers_schema.schemas.size == 2 && optional
|
|
24
|
+
# Avromatic does not treat the union of null and 1 other type as a union
|
|
25
|
+
datum
|
|
26
|
+
elsif datum.nil?
|
|
27
|
+
# Avromatic does not treat the null of an optional field as part of the union
|
|
28
|
+
nil
|
|
29
|
+
else
|
|
30
|
+
# Avromatic does not treat the null of an optional field as part of the union so
|
|
31
|
+
# adjust the member index accordingly
|
|
32
|
+
member_index = optional ? rs_index - 1 : rs_index
|
|
33
|
+
Avromatic::IO::UnionDatum.new(member_index, datum)
|
|
81
34
|
end
|
|
82
|
-
|
|
83
|
-
read_record
|
|
84
35
|
end
|
|
85
36
|
end
|
|
86
37
|
end
|
|
87
38
|
end
|
|
88
|
-
# rubocop:enable Style/WhenThen
|
|
@@ -7,10 +7,11 @@ module Avromatic
|
|
|
7
7
|
class DatumWriter < Avro::IO::DatumWriter
|
|
8
8
|
def write_union(writers_schema, datum, encoder)
|
|
9
9
|
optional = writers_schema.schemas.first.type_sym == :null
|
|
10
|
-
if datum.is_a?(
|
|
11
|
-
index_of_schema = datum
|
|
10
|
+
if datum.is_a?(Avromatic::IO::UnionDatum)
|
|
11
|
+
index_of_schema = datum.member_index
|
|
12
12
|
# Avromatic does not treat the null of an optional field as part of the union
|
|
13
13
|
index_of_schema += 1 if optional
|
|
14
|
+
datum = datum.datum
|
|
14
15
|
elsif optional && writers_schema.schemas.size == 2
|
|
15
16
|
# Optimize for the common case of a union that's just an optional field
|
|
16
17
|
index_of_schema = datum.nil? ? 0 : 1
|
|
@@ -19,21 +20,14 @@ module Avromatic
|
|
|
19
20
|
Avro::Schema.validate(schema, datum)
|
|
20
21
|
end
|
|
21
22
|
end
|
|
23
|
+
|
|
22
24
|
unless index_of_schema
|
|
23
25
|
raise Avro::IO::AvroTypeError.new(writers_schema, datum)
|
|
24
26
|
end
|
|
27
|
+
|
|
25
28
|
encoder.write_long(index_of_schema)
|
|
26
29
|
write_data(writers_schema.schemas[index_of_schema], datum, encoder)
|
|
27
30
|
end
|
|
28
|
-
|
|
29
|
-
def write_record(writers_schema, datum, encoder)
|
|
30
|
-
if datum.is_a?(Hash) && datum.key?(Avromatic::IO::ENCODING_PROVIDER)
|
|
31
|
-
# This is only used for recursive serialization so validation has already been done
|
|
32
|
-
encoder.write(datum[Avromatic::IO::ENCODING_PROVIDER].avro_raw_value(validate: false))
|
|
33
|
-
else
|
|
34
|
-
super
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
31
|
end
|
|
38
32
|
end
|
|
39
33
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Avromatic
|
|
4
|
+
module IO
|
|
5
|
+
class UnionDatum
|
|
6
|
+
attr_reader :member_index, :datum
|
|
7
|
+
|
|
8
|
+
def initialize(member_index, datum)
|
|
9
|
+
@member_index = member_index
|
|
10
|
+
@datum = datum
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def ==(other)
|
|
14
|
+
other.is_a?(Avromatic::IO::UnionDatum) &&
|
|
15
|
+
member_index == other.member_index &&
|
|
16
|
+
datum == other.datum
|
|
17
|
+
end
|
|
18
|
+
alias_method :eql?, :==
|
|
19
|
+
|
|
20
|
+
def hash
|
|
21
|
+
31 * datum.hash + member_index
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/avromatic/messaging.rb
CHANGED
|
@@ -29,7 +29,8 @@ module Avromatic
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# The following line differs from the parent class to use a custom DatumReader
|
|
32
|
-
|
|
32
|
+
reader_class = Avromatic.use_custom_datum_reader ? Avromatic::IO::DatumReader : Avro::IO::DatumReader
|
|
33
|
+
reader = reader_class.new(writers_schema, readers_schema)
|
|
33
34
|
reader.read(decoder)
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -50,7 +51,8 @@ module Avromatic
|
|
|
50
51
|
encoder.write([schema_id].pack('N'))
|
|
51
52
|
|
|
52
53
|
# The following line differs from the parent class to use a custom DatumWriter
|
|
53
|
-
|
|
54
|
+
writer_class = Avromatic.use_custom_datum_writer ? Avromatic::IO::DatumWriter : Avro::IO::DatumWriter
|
|
55
|
+
writer = writer_class.new(schema)
|
|
54
56
|
|
|
55
57
|
# The actual message comes last.
|
|
56
58
|
writer.write(message, encoder)
|
|
@@ -27,7 +27,10 @@ module Avromatic
|
|
|
27
27
|
def initialize(owner:, field:, type:)
|
|
28
28
|
@owner = owner
|
|
29
29
|
@field = field
|
|
30
|
+
@required = FieldHelper.required?(field)
|
|
31
|
+
@nullable = FieldHelper.nullable?(field)
|
|
30
32
|
@type = type
|
|
33
|
+
@values_immutable = type.referenced_model_classes.all?(&:recursively_immutable?)
|
|
31
34
|
@name = field.name.to_sym
|
|
32
35
|
@name_string = field.name.to_s.dup.freeze
|
|
33
36
|
@setter_name = "#{field.name}=".to_sym
|
|
@@ -40,8 +43,16 @@ module Avromatic
|
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
|
|
46
|
+
def nullable?
|
|
47
|
+
@nullable
|
|
48
|
+
end
|
|
49
|
+
|
|
43
50
|
def required?
|
|
44
|
-
|
|
51
|
+
@required
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def values_immutable?
|
|
55
|
+
@values_immutable
|
|
45
56
|
end
|
|
46
57
|
|
|
47
58
|
def coerce(input)
|
|
@@ -69,6 +80,8 @@ module Avromatic
|
|
|
69
80
|
included do
|
|
70
81
|
class_attribute :attribute_definitions, instance_writer: false
|
|
71
82
|
self.attribute_definitions = {}
|
|
83
|
+
|
|
84
|
+
delegate :recursively_immutable?, to: :class
|
|
72
85
|
end
|
|
73
86
|
|
|
74
87
|
def initialize(data = {})
|
|
@@ -130,6 +143,12 @@ module Avromatic
|
|
|
130
143
|
define_avro_attributes(avro_schema, generated_methods_module)
|
|
131
144
|
end
|
|
132
145
|
|
|
146
|
+
def recursively_immutable?
|
|
147
|
+
return @recursively_immutable if defined?(@recursively_immutable)
|
|
148
|
+
|
|
149
|
+
@recursively_immutable = immutable? && attribute_definitions.each_value.all?(&:values_immutable?)
|
|
150
|
+
end
|
|
151
|
+
|
|
133
152
|
private
|
|
134
153
|
|
|
135
154
|
def check_for_field_conflicts!
|
|
@@ -174,10 +193,10 @@ module Avromatic
|
|
|
174
193
|
generated_methods_module.send(:define_method, "#{field.name}?") { !!_attributes[symbolized_field_name] } if FieldHelper.boolean?(field)
|
|
175
194
|
|
|
176
195
|
generated_methods_module.send(:define_method, "#{field.name}=") do |value|
|
|
177
|
-
_attributes[symbolized_field_name] =
|
|
196
|
+
_attributes[symbolized_field_name] = attribute_definition.coerce(value)
|
|
178
197
|
end
|
|
179
198
|
|
|
180
|
-
unless
|
|
199
|
+
unless mutable? # rubocop:disable Style/Next
|
|
181
200
|
generated_methods_module.send(:private, "#{field.name}=")
|
|
182
201
|
generated_methods_module.send(:define_method, :clone) { self }
|
|
183
202
|
generated_methods_module.send(:define_method, :dup) { self }
|
|
@@ -19,9 +19,12 @@ module Avromatic
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
included do
|
|
23
|
+
class_attribute :config, instance_accessor: false, instance_predicate: false
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
module ClassMethods
|
|
23
|
-
|
|
24
|
-
delegate :avro_schema, :value_avro_schema, :key_avro_schema, to: :config
|
|
27
|
+
delegate :avro_schema, :value_avro_schema, :key_avro_schema, :mutable?, :immutable?, to: :config
|
|
25
28
|
|
|
26
29
|
def value_avro_field_names
|
|
27
30
|
@value_avro_field_names ||= value_avro_schema.fields.map(&:name).map(&:to_sym).freeze
|
|
@@ -67,6 +70,7 @@ module Avromatic
|
|
|
67
70
|
delegate :avro_schema, :value_avro_schema, :key_avro_schema,
|
|
68
71
|
:value_avro_field_names, :key_avro_field_names,
|
|
69
72
|
:value_avro_field_references, :key_avro_field_references,
|
|
73
|
+
:mutable?, :immutable?,
|
|
70
74
|
to: :class
|
|
71
75
|
end
|
|
72
76
|
end
|
|
@@ -8,6 +8,7 @@ module Avromatic
|
|
|
8
8
|
|
|
9
9
|
attr_reader :avro_schema, :key_avro_schema, :nested_models, :mutable,
|
|
10
10
|
:allow_optional_key_fields
|
|
11
|
+
alias_method :mutable?, :mutable
|
|
11
12
|
delegate :schema_store, to: Avromatic
|
|
12
13
|
|
|
13
14
|
# Either schema(_name) or value_schema(_name), but not both, must be
|
|
@@ -34,6 +35,10 @@ module Avromatic
|
|
|
34
35
|
|
|
35
36
|
alias_method :value_avro_schema, :avro_schema
|
|
36
37
|
|
|
38
|
+
def immutable?
|
|
39
|
+
!mutable?
|
|
40
|
+
end
|
|
41
|
+
|
|
37
42
|
private
|
|
38
43
|
|
|
39
44
|
def find_avro_schema(**options)
|
|
@@ -16,9 +16,13 @@ module Avromatic
|
|
|
16
16
|
!optional?(field)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
def nullable?(field)
|
|
20
|
+
optional?(field) || field.type.type_sym == :null
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def boolean?(field)
|
|
20
24
|
field.type.type_sym == :boolean ||
|
|
21
|
-
(
|
|
25
|
+
(optional?(field) && field.type.schemas.last.type_sym == :boolean)
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -48,7 +48,8 @@ module Avromatic
|
|
|
48
48
|
value_attributes = avro_messaging
|
|
49
49
|
.decode(message_value, schema_name: avro_schema.fullname)
|
|
50
50
|
|
|
51
|
-
value_attributes.merge!(key_attributes
|
|
51
|
+
value_attributes.merge!(key_attributes) if key_attributes
|
|
52
|
+
value_attributes
|
|
52
53
|
end
|
|
53
54
|
end
|
|
54
55
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support/deprecation'
|
|
4
|
+
|
|
3
5
|
module Avromatic
|
|
4
6
|
module Model
|
|
5
7
|
|
|
@@ -11,55 +13,93 @@ module Avromatic
|
|
|
11
13
|
module Encode
|
|
12
14
|
extend ActiveSupport::Concern
|
|
13
15
|
|
|
16
|
+
UNSPECIFIED = Object.new
|
|
17
|
+
|
|
14
18
|
delegate :datum_writer, :datum_reader, to: :class
|
|
15
19
|
private :datum_writer, :datum_reader
|
|
16
20
|
|
|
17
|
-
def avro_raw_value(validate:
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
def avro_raw_value(validate: UNSPECIFIED)
|
|
22
|
+
unless validate == UNSPECIFIED
|
|
23
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if self.class.recursively_immutable?
|
|
27
|
+
@avro_raw_value ||= avro_raw_encode(value_attributes_for_avro, :value)
|
|
20
28
|
else
|
|
21
|
-
|
|
29
|
+
avro_raw_encode(value_attributes_for_avro, :value)
|
|
22
30
|
end
|
|
23
31
|
end
|
|
24
32
|
|
|
25
|
-
def avro_raw_key(validate:
|
|
33
|
+
def avro_raw_key(validate: UNSPECIFIED)
|
|
34
|
+
unless validate == UNSPECIFIED
|
|
35
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
raise 'Model has no key schema' unless key_avro_schema
|
|
27
|
-
avro_raw_encode(key_attributes_for_avro
|
|
39
|
+
avro_raw_encode(key_attributes_for_avro, :key)
|
|
28
40
|
end
|
|
29
41
|
|
|
30
|
-
def value_attributes_for_avro(validate:
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
def value_attributes_for_avro(validate: UNSPECIFIED)
|
|
43
|
+
unless validate == UNSPECIFIED
|
|
44
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if self.class.recursively_immutable?
|
|
48
|
+
@value_attributes_for_avro ||= avro_hash(value_avro_field_references)
|
|
33
49
|
else
|
|
34
|
-
|
|
50
|
+
avro_hash(value_avro_field_references)
|
|
35
51
|
end
|
|
36
52
|
end
|
|
37
53
|
|
|
38
|
-
def key_attributes_for_avro(validate:
|
|
39
|
-
|
|
54
|
+
def key_attributes_for_avro(validate: UNSPECIFIED)
|
|
55
|
+
unless validate == UNSPECIFIED
|
|
56
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
avro_hash(key_avro_field_references)
|
|
40
60
|
end
|
|
41
61
|
|
|
42
|
-
def avro_value_datum(validate:
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
def avro_value_datum(validate: UNSPECIFIED)
|
|
63
|
+
unless validate == UNSPECIFIED
|
|
64
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if self.class.recursively_immutable?
|
|
68
|
+
@avro_value_datum ||= avro_hash(value_avro_field_references, strict: true)
|
|
45
69
|
else
|
|
46
|
-
|
|
70
|
+
avro_hash(value_avro_field_references, strict: true)
|
|
47
71
|
end
|
|
48
72
|
end
|
|
49
73
|
|
|
50
|
-
def avro_key_datum(validate:
|
|
51
|
-
|
|
74
|
+
def avro_key_datum(validate: UNSPECIFIED)
|
|
75
|
+
unless validate == UNSPECIFIED
|
|
76
|
+
ActiveSupport::Deprecation.warn("The 'validate' argument to #{__method__} is deprecated.")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
avro_hash(key_avro_field_references, strict: true)
|
|
52
80
|
end
|
|
53
81
|
|
|
54
82
|
private
|
|
55
83
|
|
|
56
|
-
def avro_hash(field_references, strict: false
|
|
57
|
-
avro_validate! if validate
|
|
84
|
+
def avro_hash(field_references, strict: false)
|
|
58
85
|
field_references.each_with_object(Hash.new) do |field_reference, result|
|
|
59
|
-
|
|
60
|
-
|
|
86
|
+
attribute_definition = self.class.attribute_definitions[field_reference.name_sym]
|
|
61
87
|
value = _attributes[field_reference.name_sym]
|
|
62
|
-
|
|
88
|
+
|
|
89
|
+
if value.nil? && !attribute_definition.nullable?
|
|
90
|
+
# We're missing a required attribute so perform an explicit validation to generate
|
|
91
|
+
# a more complete error message
|
|
92
|
+
avro_validate!
|
|
93
|
+
elsif _attributes.include?(field_reference.name_sym)
|
|
94
|
+
begin
|
|
95
|
+
result[field_reference.name] = attribute_definition.serialize(value, strict)
|
|
96
|
+
rescue Avromatic::Model::ValidationError
|
|
97
|
+
# Perform an explicit validation to generate a more complete error message
|
|
98
|
+
avro_validate!
|
|
99
|
+
# We should never get here but just in case...
|
|
100
|
+
raise
|
|
101
|
+
end
|
|
102
|
+
end
|
|
63
103
|
end
|
|
64
104
|
end
|
|
65
105
|
|
|
@@ -81,8 +121,8 @@ module Avromatic
|
|
|
81
121
|
def avro_raw_decode(key: nil, value:, key_schema: nil, value_schema: nil)
|
|
82
122
|
key_attributes = key && decode_avro_datum(key, key_schema, :key)
|
|
83
123
|
value_attributes = decode_avro_datum(value, value_schema, :value)
|
|
84
|
-
|
|
85
|
-
new(value_attributes
|
|
124
|
+
value_attributes.merge!(key_attributes) if key_attributes
|
|
125
|
+
new(value_attributes)
|
|
86
126
|
end
|
|
87
127
|
|
|
88
128
|
private
|
|
@@ -42,13 +42,10 @@ module Avromatic
|
|
|
42
42
|
def serialize(value, strict)
|
|
43
43
|
if value.nil?
|
|
44
44
|
value
|
|
45
|
-
elsif
|
|
46
|
-
|
|
47
|
-
# hash but then we'd have no place to stash the union member index...
|
|
48
|
-
{ Avromatic::IO::ENCODING_PROVIDER => value }
|
|
45
|
+
elsif strict
|
|
46
|
+
value.avro_value_datum
|
|
49
47
|
else
|
|
50
|
-
|
|
51
|
-
strict ? value.avro_value_datum(validate: false) : value.value_attributes_for_avro(validate: false)
|
|
48
|
+
value.value_attributes_for_avro
|
|
52
49
|
end
|
|
53
50
|
end
|
|
54
51
|
|
|
@@ -7,7 +7,6 @@ module Avromatic
|
|
|
7
7
|
module Model
|
|
8
8
|
module Types
|
|
9
9
|
class UnionType < AbstractType
|
|
10
|
-
MEMBER_INDEX = ::Avromatic::IO::DatumReader::UNION_MEMBER_INDEX
|
|
11
10
|
attr_reader :member_types, :value_classes, :input_classes
|
|
12
11
|
|
|
13
12
|
def initialize(member_types:)
|
|
@@ -24,8 +23,8 @@ module Avromatic
|
|
|
24
23
|
return input if coerced?(input)
|
|
25
24
|
|
|
26
25
|
result = nil
|
|
27
|
-
if input.is_a?(
|
|
28
|
-
result = member_types[input.
|
|
26
|
+
if input.is_a?(Avromatic::IO::UnionDatum)
|
|
27
|
+
result = member_types[input.member_index].coerce(input.datum)
|
|
29
28
|
else
|
|
30
29
|
member_types.find do |member_type|
|
|
31
30
|
result = safe_coerce(member_type, input)
|
|
@@ -40,12 +39,16 @@ module Avromatic
|
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
def coerced?(value)
|
|
42
|
+
return false if value.is_a?(Avromatic::IO::UnionDatum)
|
|
43
|
+
|
|
43
44
|
value.nil? || member_types.any? do |member_type|
|
|
44
45
|
member_type.coerced?(value)
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def coercible?(input)
|
|
50
|
+
return true if value.is_a?(Avromatic::IO::UnionDatum)
|
|
51
|
+
|
|
49
52
|
coerced?(input) || member_types.any? do |member_type|
|
|
50
53
|
member_type.coercible?(input)
|
|
51
54
|
end
|
|
@@ -60,11 +63,11 @@ module Avromatic
|
|
|
60
63
|
raise ArgumentError.new("Expected #{value.inspect} to be one of #{value_classes.map(&:name)}")
|
|
61
64
|
end
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
if !strict && Avromatic.use_custom_datum_writer
|
|
65
|
-
|
|
66
|
+
serialized_value = member_types[member_index].serialize(value, strict)
|
|
67
|
+
if !strict && Avromatic.use_custom_datum_writer
|
|
68
|
+
serialized_value = Avromatic::IO::UnionDatum.new(member_index, serialized_value)
|
|
66
69
|
end
|
|
67
|
-
|
|
70
|
+
serialized_value
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
def referenced_model_classes
|
data/lib/avromatic/version.rb
CHANGED
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.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Salsify Engineering
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
version: '5.0'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '6.
|
|
22
|
+
version: '6.2'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +29,7 @@ dependencies:
|
|
|
29
29
|
version: '5.0'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '6.
|
|
32
|
+
version: '6.2'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: activesupport
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
version: '5.0'
|
|
40
40
|
- - "<"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '6.
|
|
42
|
+
version: '6.2'
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -49,7 +49,7 @@ dependencies:
|
|
|
49
49
|
version: '5.0'
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: '6.
|
|
52
|
+
version: '6.2'
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: avro
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -196,6 +196,20 @@ dependencies:
|
|
|
196
196
|
- - "~>"
|
|
197
197
|
- !ruby/object:Gem::Version
|
|
198
198
|
version: '3.0'
|
|
199
|
+
- !ruby/object:Gem::Dependency
|
|
200
|
+
name: rspec_junit_formatter
|
|
201
|
+
requirement: !ruby/object:Gem::Requirement
|
|
202
|
+
requirements:
|
|
203
|
+
- - ">="
|
|
204
|
+
- !ruby/object:Gem::Version
|
|
205
|
+
version: '0'
|
|
206
|
+
type: :development
|
|
207
|
+
prerelease: false
|
|
208
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
209
|
+
requirements:
|
|
210
|
+
- - ">="
|
|
211
|
+
- !ruby/object:Gem::Version
|
|
212
|
+
version: '0'
|
|
199
213
|
- !ruby/object:Gem::Dependency
|
|
200
214
|
name: salsify_rubocop
|
|
201
215
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -259,13 +273,13 @@ executables: []
|
|
|
259
273
|
extensions: []
|
|
260
274
|
extra_rdoc_files: []
|
|
261
275
|
files:
|
|
276
|
+
- ".circleci/config.yml"
|
|
262
277
|
- ".gitignore"
|
|
263
278
|
- ".overcommit.yml"
|
|
264
279
|
- ".rspec"
|
|
265
280
|
- ".rubocop.yml"
|
|
266
281
|
- ".ruby-gemset"
|
|
267
282
|
- ".ruby-version"
|
|
268
|
-
- ".travis.yml"
|
|
269
283
|
- Appraisals
|
|
270
284
|
- CHANGELOG.md
|
|
271
285
|
- Gemfile
|
|
@@ -278,15 +292,19 @@ files:
|
|
|
278
292
|
- gemfiles/.bundle/config
|
|
279
293
|
- gemfiles/avro1_10_rails5_2.gemfile
|
|
280
294
|
- gemfiles/avro1_10_rails6_0.gemfile
|
|
295
|
+
- gemfiles/avro1_10_rails6_1.gemfile
|
|
281
296
|
- gemfiles/avro1_8_rails5_2.gemfile
|
|
282
297
|
- gemfiles/avro1_9_rails5_2.gemfile
|
|
283
298
|
- gemfiles/avro1_9_rails6_0.gemfile
|
|
299
|
+
- gemfiles/avro1_9_rails6_1.gemfile
|
|
284
300
|
- gemfiles/avro_patches_rails5_2.gemfile
|
|
285
301
|
- gemfiles/avro_patches_rails6_0.gemfile
|
|
302
|
+
- gemfiles/avro_patches_rails6_1.gemfile
|
|
286
303
|
- lib/avromatic.rb
|
|
287
304
|
- lib/avromatic/io.rb
|
|
288
305
|
- lib/avromatic/io/datum_reader.rb
|
|
289
306
|
- lib/avromatic/io/datum_writer.rb
|
|
307
|
+
- lib/avromatic/io/union_datum.rb
|
|
290
308
|
- lib/avromatic/messaging.rb
|
|
291
309
|
- lib/avromatic/model.rb
|
|
292
310
|
- lib/avromatic/model/attributes.rb
|
|
@@ -324,8 +342,6 @@ files:
|
|
|
324
342
|
- lib/avromatic/model/validation_error.rb
|
|
325
343
|
- lib/avromatic/model/value_object.rb
|
|
326
344
|
- lib/avromatic/model_registry.rb
|
|
327
|
-
- lib/avromatic/patches.rb
|
|
328
|
-
- lib/avromatic/patches/schema_validator_patch.rb
|
|
329
345
|
- lib/avromatic/railtie.rb
|
|
330
346
|
- lib/avromatic/rspec.rb
|
|
331
347
|
- lib/avromatic/version.rb
|
data/.travis.yml
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
rvm:
|
|
3
|
-
- 2.5.8
|
|
4
|
-
- 2.6.6
|
|
5
|
-
- 2.7.1
|
|
6
|
-
before_script:
|
|
7
|
-
- bundle exec rubocop
|
|
8
|
-
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
|
|
14
|
-
- gemfiles/avro_patches_rails5_2.gemfile
|
|
15
|
-
- gemfiles/avro_patches_rails6_0.gemfile
|
|
16
|
-
script: bundle exec rspec
|
data/lib/avromatic/patches.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
loaded_avro_patches = begin
|
|
4
|
-
require 'avro-patches'
|
|
5
|
-
true
|
|
6
|
-
rescue LoadError
|
|
7
|
-
false
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
if loaded_avro_patches
|
|
11
|
-
require 'avromatic/patches/schema_validator_patch'
|
|
12
|
-
avro_patches_version = Gem::Version.new(AvroPatches::VERSION)
|
|
13
|
-
if avro_patches_version < Gem::Version.new('0.4.0')
|
|
14
|
-
Avro::SchemaValidator.singleton_class.prepend(Avromatic::Patches::SchemaValidatorPatch)
|
|
15
|
-
else
|
|
16
|
-
Avro::SchemaValidator.singleton_class.prepend(Avromatic::Patches::SchemaValidatorPatchV040)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Avromatic
|
|
4
|
-
module Patches
|
|
5
|
-
module SchemaValidatorPatch
|
|
6
|
-
# This method replaces validate_recursive in AvroPatches::LogicalTypes::SchemaValidatorPatch
|
|
7
|
-
# to enable validating datums that contain an encoding provider.
|
|
8
|
-
def validate_recursive(expected_schema, logical_datum, path, result, encoded = false)
|
|
9
|
-
datum = resolve_datum(expected_schema, logical_datum, encoded)
|
|
10
|
-
case expected_schema.type_sym
|
|
11
|
-
when :record, :error, :request
|
|
12
|
-
if datum.is_a?(Hash) && datum.key?(Avromatic::IO::ENCODING_PROVIDER)
|
|
13
|
-
return if expected_schema.sha256_resolution_fingerprint ==
|
|
14
|
-
datum[Avromatic::IO::ENCODING_PROVIDER].value_avro_schema.sha256_resolution_fingerprint
|
|
15
|
-
raise Avro::SchemaValidator::ValidationError
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
super(expected_schema, logical_datum, path, result, encoded)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
module SchemaValidatorPatchV040
|
|
23
|
-
# This method replaces validate_recursive in AvroPatches::LogicalTypes::SchemaValidatorPatch
|
|
24
|
-
# to enable validating datums that contain an encoding provider.
|
|
25
|
-
def validate_recursive(expected_schema, logical_datum, path, result, options = {})
|
|
26
|
-
datum = resolve_datum(expected_schema, logical_datum, options[:encoded])
|
|
27
|
-
case expected_schema.type_sym
|
|
28
|
-
when :record, :error, :request
|
|
29
|
-
if datum.is_a?(Hash) && datum.key?(Avromatic::IO::ENCODING_PROVIDER)
|
|
30
|
-
return if expected_schema.sha256_resolution_fingerprint ==
|
|
31
|
-
datum[Avromatic::IO::ENCODING_PROVIDER].value_avro_schema.sha256_resolution_fingerprint
|
|
32
|
-
raise Avro::SchemaValidator::ValidationError
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
super(expected_schema, logical_datum, path, result, options)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|