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



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

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



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

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:



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

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)


104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/odata/service.rb', line 104

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,
                       service_name: name,
                       container: container_name)
end

#associationsHash<OData::Association>

Returns the associations defined by the service

Returns:



61
62
63
64
65
66
67
68
# File 'lib/odata/service.rb', line 61

def associations
  @associations ||= Hash[.xpath('//Association').collect do |association_definition|
    [
        association_definition.attributes['Name'].value,
        build_association(association_definition)
    ]
  end]
end

#complex_typesObject

Returns a list of ComplexTypes used by the service



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

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



45
46
47
48
49
50
51
52
# File 'lib/odata/service.rb', line 45

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



40
41
42
# File 'lib/odata/service.rb', line 40

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)


122
123
124
125
126
127
128
129
130
131
# File 'lib/odata/service.rb', line 122

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)


147
148
149
150
151
# File 'lib/odata/service.rb', line 147

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)


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

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



158
159
160
# File 'lib/odata/service.rb', line 158

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



175
176
177
178
179
# File 'lib/odata/service.rb', line 175

def get_summary_property_name(entity_name)
  .xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationSummary']").first.attributes['Name'].value
rescue NoMethodError
  nil
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



166
167
168
169
# File 'lib/odata/service.rb', line 166

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

#inspectObject

Returns a more compact inspection of the service object



96
97
98
# File 'lib/odata/service.rb', line 96

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

#nameString

Returns user supplied name for service, or its URL

Returns:

  • (String)


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

def name
  @name ||= options[:name] || service_url
end

#namespaceObject

Returns the namespace defined on the service’s schema



91
92
93
# File 'lib/odata/service.rb', line 91

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

Returns a hash for finding an association through an entity type’s defined NavigationProperty elements.

Returns:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/odata/service.rb', line 73

def navigation_properties
  @navigation_properties ||= Hash[.xpath('//EntityType').collect do |entity_type_def|
    entity_type_name = entity_type_def.attributes['Name'].value
    [
        entity_type_name,
        Hash[entity_type_def.xpath('./NavigationProperty').collect do |nav_property_def|
          relationship_name = nav_property_def.attributes['Relationship'].value
          relationship_name.gsub!(/^#{namespace}\./, '')
          [
              nav_property_def.attributes['Name'].value,
              associations[relationship_name]
          ]
        end]
    ]
  end]
end

#primary_key_for(entity_name) ⇒ String

Get the primary key for the supplied Entity.

Parameters:

  • entity_name (to_s)

Returns:

  • (String)


185
186
187
# File 'lib/odata/service.rb', line 185

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

#properties_for_complex_type(type_name) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Parameters:

  • type_name (to_s)

Returns:

  • (Hash)

Raises:

  • (ArgumentError)


210
211
212
213
214
215
216
217
218
219
# File 'lib/odata/service.rb', line 210

def properties_for_complex_type(type_name)
  type_definition = .xpath("//ComplexType[@Name='#{type_name}']").first
  raise ArgumentError, "Unknown ComplexType: #{type_name}" if type_definition.nil?
  properties_to_return = {}
  type_definition.xpath('./Property').each do |property_xml|
    property_name, property = process_property_from_xml(property_xml)
    properties_to_return[property_name] = property
  end
  properties_to_return
end

#properties_for_entity(entity_name) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

Parameters:

  • entity_name (to_s)

Returns:

  • (Hash)

Raises:

  • (ArgumentError)


194
195
196
197
198
199
200
201
202
203
# File 'lib/odata/service.rb', line 194

def properties_for_entity(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 = process_property_from_xml(property_xml)
    properties_to_return[property_name] = property
  end
  properties_to_return
end