Class: OData::Service

Inherits:
Object
  • Object
show all
Defined in:
lib/odata/service.rb

Overview

Encapsulates the basic details and functionality needed to interact with an OData service.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service_url, options = {}) ⇒ OData::Service

Opens the service based on the requested URL and adds the service to Registry

Parameters:

  • service_url (String)

    the URL to the desired OData service

  • options (Hash) (defaults to: {})

    options to pass to the service



17
18
19
20
21
22
# File 'lib/odata/service.rb', line 17

def initialize(service_url, options = {})
  @service_url = service_url
  @options = default_options.merge(options)
  OData::ServiceRegistry.add(self)
  self
end

Instance Attribute Details

#optionsObject (readonly)

Options to pass around



9
10
11
# File 'lib/odata/service.rb', line 9

def options
  @options
end

#service_urlObject (readonly)

The OData Service’s URL



6
7
8
# File 'lib/odata/service.rb', line 6

def service_url
  @service_url
end

Class Method Details

.open(service_url, options = {}) ⇒ OData::Service

Opens the service based on the requested URL and adds the service to Registry

Parameters:

  • service_url (String)

    the URL to the desired OData service

  • options (Hash) (defaults to: {})

    options to pass to the service

Returns:



30
31
32
# File 'lib/odata/service.rb', line 30

def self.open(service_url, options = {})
  Service.new(service_url, options)
end

Instance Method Details

#[](entity_set_name) ⇒ OData::EntitySet

Retrieves the EntitySet associated with a specific EntityType by name

Parameters:

  • entity_set_name (to_s)

    the name of the EntitySet desired

Returns:

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
# File 'lib/odata/service.rb', line 68

def [](entity_set_name)
  xpath_query = "//EntityContainer/EntitySet[@Name='#{entity_set_name}']"
  entity_set_node = .xpath(xpath_query).first
  raise ArgumentError, "Unknown Entity Set: #{entity_set_name}" if entity_set_node.nil?
  container_name = entity_set_node.parent.attributes['Name'].value
  entity_type_name = entity_set_node.attributes['EntityType'].value.gsub(/#{namespace}\./, '')
  OData::EntitySet.new(name: entity_set_name,
                       namespace: namespace,
                       type: entity_type_name.to_s,
                       container: container_name)
end

#complex_typesObject

Returns a list of ComplexTypes used by the service



50
51
52
# File 'lib/odata/service.rb', line 50

def complex_types
  @complex_types ||= .xpath('//ComplexType').collect {|entity| entity.attributes['Name'].value}
end

#entity_setsObject

Returns a hash of EntitySet names keyed to their respective EntityType name



40
41
42
43
44
45
46
47
# File 'lib/odata/service.rb', line 40

def entity_sets
  @entity_sets ||= Hash[.xpath('//EntityContainer/EntitySet').collect {|entity|
    [
      entity.attributes['EntityType'].value.gsub("#{namespace}.", ''),
      entity.attributes['Name'].value
    ]
  }]
end

#entity_typesObject

Returns a list of entities exposed by the service



35
36
37
# File 'lib/odata/service.rb', line 35

def entity_types
  @entity_types ||= .xpath('//EntityType').collect {|entity| entity.attributes['Name'].value}
end

#execute(url_chunk, additional_options = {}) ⇒ Typhoeus::Response

Execute a request against the service

Parameters:

  • url_chunk (to_s)

    string to append to service url

  • additional_options (Hash) (defaults to: {})

    options to pass to Typhoeus

Returns:

  • (Typhoeus::Response)


85
86
87
88
89
90
91
92
93
94
# File 'lib/odata/service.rb', line 85

def execute(url_chunk, additional_options = {})
  request = ::Typhoeus::Request.new(
      URI.escape("#{service_url}/#{url_chunk}"),
      options[:typhoeus].merge({
        method: :get
      }).merge(additional_options)
  )
  request.run
  request.response
end

#find_entities(results) ⇒ Nokogiri::XML::NodeSet

Find entity entries in a result set

Parameters:

  • results (Typhoeus::Response)

Returns:

  • (Nokogiri::XML::NodeSet)


110
111
112
113
114
# File 'lib/odata/service.rb', line 110

def find_entities(results)
  document = ::Nokogiri::XML(results.body)
  document.remove_namespaces!
  document.xpath('//entry')
end

#find_node(results, node_name) ⇒ Nokogiri::XML::Element

Find a specific node in the given result set

Parameters:

  • results (Typhoeus::Response)

Returns:

  • (Nokogiri::XML::Element)


100
101
102
103
104
# File 'lib/odata/service.rb', line 100

def find_node(results, node_name)
  document = ::Nokogiri::XML(results.body)
  document.remove_namespaces!
  document.xpath("//#{node_name}").first
end

#get_property_type(entity_name, property_name) ⇒ String

Get the property type for an entity from metadata.

Parameters:

  • entity_name (to_s)

    the name of the relevant entity

  • property_name (to_s)

    the property name needed

Returns:

  • (String)

    the name of the property’s type



121
122
123
# File 'lib/odata/service.rb', line 121

def get_property_type(entity_name, property_name)
  .xpath("//EntityType[@Name='#{entity_name}']/Property[@Name='#{property_name}']").first.attributes['Type'].value
end

#get_summary_property_name(entity_name) ⇒ String

Get the property used as the summary for an entity from metadata.

Parameters:

  • entity_name (to_s)

    the name of the relevant entity

Returns:

  • (String)

    the name of the property used as the entity summary



137
138
139
# File 'lib/odata/service.rb', line 137

def get_summary_property_name(entity_name)
  .xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationSummary']").first.attributes['Name'].value
end

#get_title_property_name(entity_name) ⇒ String

Get the property used as the title for an entity from metadata.

Parameters:

  • entity_name (to_s)

    the name of the relevant entity

Returns:

  • (String)

    the name of the property used as the entity title



129
130
131
# File 'lib/odata/service.rb', line 129

def get_title_property_name(entity_name)
  .xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationTitle']").first.attributes['Name'].value
end

#inspectObject

Returns a more compact inspection of the service object



60
61
62
# File 'lib/odata/service.rb', line 60

def inspect
  "#<#{self.class.name}:#{self.object_id} namespace='#{self.namespace}' service_url='#{self.service_url}'>"
end

#namespaceObject

Returns the namespace defined on the service’s schema



55
56
57
# File 'lib/odata/service.rb', line 55

def namespace
  @namespace ||= .xpath('//Schema').first.attributes['Namespace'].value
end

#primary_key_for(entity_name) ⇒ String

Get the primary key for the supplied Entity.

Parameters:

  • entity_name (to_s)

Returns:

  • (String)


145
146
147
# File 'lib/odata/service.rb', line 145

def primary_key_for(entity_name)
  .xpath("//EntityType[@Name='#{entity_name}']/Key/PropertyRef").first.attributes['Name'].value
end

#properties_for(entity_name) ⇒ Hash

Get the list of properties and their various options for the supplied Entity name.

Parameters:

  • entity_name (to_s)

Returns:

  • (Hash)

Raises:

  • (ArgumentError)


154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/odata/service.rb', line 154

def properties_for(entity_name)
  type_definition = .xpath("//EntityType[@Name='#{entity_name}']").first
  raise ArgumentError, "Unknown EntityType: #{entity_name}" if type_definition.nil?
  properties_to_return = {}
  type_definition.xpath('./Property').each do |property_xml|
    property_name = property_xml.attributes['Name'].value
    value_type = property_xml.attributes['Type'].value
    property_options = {}
    property_options[:allows_nil] = false if property_xml.attributes['Nullable'] == 'false'
    klass_name = value_type.gsub(/^Edm\./, '')
    properties_to_return[property_name] = get_property_class(klass_name).new(property_name, nil, property_options)
  end
  properties_to_return
end