Skip to content

Commit

Permalink
Add some additional capabilities to namespace resolution (#42)
Browse files Browse the repository at this point in the history
* Add some additional capabilities to namespace resolution

* Fix some lint, thanks rubocop

* PR Feedback

* Remove unused variable

* Update readme and pull apart changelog entries
  • Loading branch information
rlburkes authored Oct 17, 2017
1 parent 7c2c522 commit 9b0826f
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# avro-builder changelog

## v0.16.0
- Add support for providing an explicit `namespace` on `extend`.
- Default lookup to current namespace before falling back on global search.

## v0.15.0
- Add support for declaring types as abstract.

Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,40 @@ record using `extends <record_name>`. This adds all of the fields from
the referenced record to the current record. The current record may override
fields in the record that it extends.

```
record :original do
required :first, :string
required :second, :int
end
record :extended do
extends :original
optional :first, :string
end
```

Additionally you can provide a `namespace` to `extends` if necessary to remove ambiguity.

```
namespace 'com.newbie'
record :original, namespace: 'com.og' do
required :first, :string
required :second, :int
end
record :original do
required :first, :string
required :second, :int
end
record :extended do
extends :original, namespace: 'com.og'
optional :first, :string
end
```


## Schema Store

The `Avro::Builder::SchemaStore` can be used to load DSL files and return cached
Expand Down
10 changes: 9 additions & 1 deletion lib/avro/builder/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ def create_named_type(name, avro_type_name, options = {}, &block)
end

def eval_file(name)
file_path = find_file(name)
file_path = if namespace
begin
find_file([namespace, name].join('.'))
rescue FileNotFoundError
find_file(name)
end
else
find_file(name)
end
instance_eval(File.read(file_path), file_path)
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/avro/builder/file_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def read_file(name)
File.read(find_file(name))
end

FileNotFoundError = Class.new(StandardError)

def find_file(name)
# Ensure that the file_name that is searched for begins with a slash (/)
# and ends with a .rb extension. Additionally, if the name contains
Expand All @@ -31,7 +33,7 @@ def find_file(name)
end
end.uniq
raise "Multiple matches: #{matches}" if matches.size > 1
raise "File not found #{file_name}" if matches.empty?
raise FileNotFoundError.new("File not found #{file_name}") if matches.empty?

matches.first
end
Expand Down
4 changes: 2 additions & 2 deletions lib/avro/builder/types/record_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ def optional(name, avro_type_or_name, options = {}, &block)

# Adds fields from the record with the specified name to the current
# record.
def extends(name)
fields.merge!(cache.lookup_named_type(name, namespace).duplicated_fields)
def extends(name, options = {})
fields.merge!(cache.lookup_named_type(name, options.delete(:namespace) || namespace).duplicated_fields)
end

def to_h(reference_state = SchemaSerializerReferenceState.new)
Expand Down
2 changes: 1 addition & 1 deletion lib/avro/builder/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Avro
module Builder
VERSION = '0.15.0'.freeze
VERSION = '0.16.0'.freeze
end
end
2 changes: 1 addition & 1 deletion spec/avro/builder/schema_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
end

it "raises a file not found exception" do
expect { schema }.to raise_error(RuntimeError)
expect { schema }.to raise_error(::Avro::Builder::FileHandler::FileNotFoundError)
end
end

Expand Down
42 changes: 42 additions & 0 deletions spec/avro/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,48 @@
it { is_expected.to be_json_eql(expected.to_json) }
end

context "extends from explicit namespace" do
subject(:schema_json) do
described_class.build do
namespace 'test.namespace'

record :original, namespace: 'test.extended' do
required :foo, :string
required :bar, :string
end

record :original do
required :bop, :string
required :baz, :string
end

record :extended do
extends :original, namespace: 'test.extended'
end
end
end

let(:expected) do
{
name: :extended,
namespace: 'test.namespace',
type: :record,
fields: [
{
name: :foo,
type: :string
},
{
name: :bar,
type: :string
}
]
}
end

it { is_expected.to be_json_eql(expected.to_json) }
end

context "recursive example" do
# this is an example from the Avro specification
subject(:schema_json) do
Expand Down

0 comments on commit 9b0826f

Please sign in to comment.