Skip to content

Commit

Permalink
Merge pull request #5 from sassafrastech/pr_metadata
Browse files Browse the repository at this point in the history
Features for customizing $metadata (and supporting tweaks)
  • Loading branch information
C14wh authored Oct 7, 2020
2 parents 65d614c + 0c28cfd commit e5d16f0
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# Ignore bundler config.
/.bundle

# Ignore local bundle installs.
/vendor/bundle/

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/o_data_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class ODataController < ApplicationController

skip_before_action :verify_authenticity_token, only: :options

# This action needs to register before the others.
# Clients may override the method if they want to do something with it.
before_action :refresh_schema
def refresh_schema; end

before_action :parse_url, only: :resource
before_action :set_request_format!, only: :resource
after_action :set_header
Expand Down
2 changes: 1 addition & 1 deletion app/views/o_data/metadata.xml.builder
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ xml.edmx(:Edmx, Version: "4.0", "xmlns:edmx" => "http://docs.oasis-open.org/odat

schema.entity_types.values.sort_by(&:qualified_name).each do |entity_type|
next if entity_type.name.include?('HABTM')
xml.tag!(:EntityType, Name: entity_type.name) do
xml.tag!(:EntityType, Name: entity_type.name, **entity_type.extra_tags) do
unless entity_type.key_property.blank?
xml.tag!(:Key) do
xml.tag!(:PropertyRef, Name: entity_type.key_property.name)
Expand Down
2 changes: 2 additions & 0 deletions lib/o_data/abstract_schema/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ class Base

attr_accessor :namespace
attr_accessor :entity_types
attr_accessor :entity_type_aliases

def initialize(namespace = "OData")
@namespace = namespace
@entity_types = {}
@entity_type_aliases = {}
end

def EntityType(*args)
Expand Down
3 changes: 2 additions & 1 deletion lib/o_data/abstract_schema/entity_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class EntityType
include Mixins::Schematize

attr_reader :key_property, :schema
attr_accessor :properties, :navigation_properties
attr_accessor :properties, :navigation_properties, :extra_tags

def self.name_for(object)
object.class.to_s.gsub('::', '')
Expand All @@ -20,6 +20,7 @@ def initialize(schema, name)
@properties = {}
@key_property = nil
@navigation_properties = {}
@extra_tags = {}
end

def key_property=(property)
Expand Down
3 changes: 3 additions & 0 deletions lib/o_data/abstract_schema/mixins/schematize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def plural_name
name.pluralize
end

def url_name
@url_name || plural_name
end
end
end
end
Expand Down
9 changes: 6 additions & 3 deletions lib/o_data/active_record_schema/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ def initialize(namespace = 'OData', options = {})
end

def find_entity_type(klass)
entity_types[EntityType.name_for(klass)]
name = EntityType.name_for(klass)
entity_types[name] || entity_type_aliases[name]
end

def add_entity_type(*args)
entity_type = EntityType.new(self, *args)
def add_entity_type(active_record, url_name: nil, **options)
entity_type = EntityType.new(self, active_record, url_name: url_name, **options)
@entity_types[entity_type.name] = entity_type
# Alias the entity for fast lookup via URL path.
@entity_type_aliases[url_name.singularize] = entity_type if url_name
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/o_data/active_record_schema/entity_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ def self.primary_key_for(active_record)
def initialize(schema, active_record, options = {})
options.reverse_merge!(reflect_on_associations: true,
name: self.class.name_for(active_record),
url_name: nil,
where: {})

super(schema, options[:name])

@url_name = options[:url_name]
@active_record = active_record.where(options[:where])

key_property_name = self.class.primary_key_for(@active_record).to_s
Expand Down
3 changes: 2 additions & 1 deletion lib/o_data/active_record_schema/property.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class Property < OData::AbstractSchema::Property
:timestamp => 'Edm.DateTimeOffset',
:float => 'Edm.Decimal',
:decimal => 'Edm.Decimal',
:integer => 'Edm.Int32',
:id => 'Edm.Guid',
:integer => 'Edm.Int64',
:string => 'Edm.String',
:text => 'Edm.String',
:time => 'Edm.TimeOfDay'
Expand Down
1 change: 1 addition & 0 deletions lib/o_data/core/segments/collection_segment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def self.parse!(query, str)
schema_object_name, key_values, keys = extract_schema_object_name_and_key_values_and_keys(str)
return nil if schema_object_name.blank?

# Note: Any aliased entity types need to be singularized because of this.
entity_type = query.data_services.find_entity_type(schema_object_name.singularize)
return nil if entity_type.blank?

Expand Down
6 changes: 5 additions & 1 deletion lib/o_data/core/segments/entity_type_segment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ def execute!(acc, options = nil)
end

def valid?(results)
results.present?
if countable?
results.is_a?(Array) || results.is_a?(ActiveRecord::Relation)
else
!results.nil?
end
end
end # EntityTypeSegment
end # Segments
Expand Down
2 changes: 1 addition & 1 deletion lib/o_data/edm/data_services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def find_entity_type(name)

def to_json
@entity_types.map do |entity|
{ name: entity.plural_name, kind: 'EntitySet', url: entity.plural_name }
{ name: entity.plural_name, kind: 'EntitySet', url: entity.url_name }
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/fixtures/files/metadata_after_hook.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
Expand All @@ -15,7 +15,7 @@
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="TestType" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
Expand Down
4 changes: 2 additions & 2 deletions spec/fixtures/files/metadata_basic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
Expand All @@ -15,7 +15,7 @@
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
Expand Down
31 changes: 31 additions & 0 deletions spec/fixtures/files/metadata_with_extra_tags.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="Test" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="ActiveBar">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
</EntityType>
<EntityType Name="ActiveFoo" BaseType="Test">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="false"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="UpdatedAt" Type="Edm.DateTimeOffset" Nullable="false"/>
</EntityType>
<EntityContainer Name="TestService">
<EntitySet Name="ActiveBars" EntityType="Test.ActiveBar">
</EntitySet>
<EntitySet Name="ActiveFoos" EntityType="Test.ActiveFoo">
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
50 changes: 49 additions & 1 deletion spec/requests/active_record_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def expect_output(expected)

it "renders with custom EntityTypes" do
schema.add_entity_type(ActiveFoo, name: "CustomFoo",
url_name: "CustomFooUrl",
reflect_on_associations: false)
schema.add_entity_type(ActiveBar, name: "CustomBar",
reflect_on_associations: false)
Expand All @@ -82,7 +83,7 @@ def expect_output(expected)
expect_output({
"@odata.context" => "http://www.example.com/odata/$metadata",
value: [
{ name: "CustomFoos", kind: "EntitySet", url: "CustomFoos" },
{ name: "CustomFoos", kind: "EntitySet", url: "CustomFooUrl" },
{ name: "CustomBars", kind: "EntitySet", url: "CustomBars" }
]
}.to_json)
Expand Down Expand Up @@ -114,6 +115,23 @@ def expect_output(expected)
expect_output(file_fixture("metadata_after_hook.xml").read)
end
end

context "with extra tags" do
let(:options) do
{
transformers: {
metadata: lambda do |schema|
schema.entity_types["ActiveFoo"].extra_tags = {BaseType: "Test"}
schema
end
}
}
end

it "renders as expected" do
expect_output(file_fixture("metadata_with_extra_tags.xml").read)
end
end
end

context "resource" do
Expand Down Expand Up @@ -199,6 +217,36 @@ def expect_output(expected)
]
}.to_json)
end

context "with aliased URLs" do
let(:path) { "#{root}/CustomFooUrl" }

it "renders as expected" do
schema.add_entity_type(ActiveFoo, url_name: "CustomFooUrl",
reflect_on_associations: false)
refresh_schema(schema)

expect_output({
"@odata.context" => "http://www.example.com/odata/$metadata#ActiveFoos",
value: [
{ Id: 1, Name: "test 1", CreatedAt: "2020-01-01T12:00:00Z", UpdatedAt: "2020-01-01T12:00:00Z" },
{ Id: 2, Name: "test 2", CreatedAt: "2020-01-01T12:00:00Z", UpdatedAt: "2020-01-01T12:00:00Z" },
]
}.to_json)
end
end
end

context "navigation" do
context "$count" do
let(:path) { "#{root}/ActiveFoos/$count" }
it { expect_output("2") }
end

context "$value" do
let(:path) { "#{root}/ActiveFoos(1)/Name/$value" }
it { expect_output("test 1") }
end
end
end
end
Expand Down

0 comments on commit e5d16f0

Please sign in to comment.