Class: OData::Service

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

Overview

The main service class, also known as a Context

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Service) initialize(service_uri, options = {})

Creates a new instance of the Service class

Options Hash (options):

  • :username (String)

    for http basic auth

  • :password (String)

    for http basic auth

  • :verify_ssl (Object)

    false if no verification, otherwise mode (OpenSSL::SSL::VERIFY_PEER is default)

  • :rest_options (Hash)

    a hash of rest-client options that will be passed to all RestClient::Resource.new calls

  • :additional_params (Hash)

    a hash of query string params that will be passed on all calls

  • :eager_partial (Boolean, true)

    true if queries should consume partial feeds until the feed is complete, false if explicit calls to next must be performed



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

def initialize(service_uri, options = {})
  @uri = service_uri.gsub!(/\/?$/, '')
  set_options! options
  default_instance_vars!
  set_namespaces
  build_collections_and_classes
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(name, *args)

Handles the dynamic AddTo<EntityName> methods as well as the collections on the service



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/ruby_odata/service.rb', line 24

def method_missing(name, *args)
  # Queries
  if @collections.include?(name.to_s)
    @query = build_collection_query_object(name,@additional_params, *args)
    return @query
  # Adds
  elsif name.to_s =~ /^AddTo(.*)/
    type = $1
    if @collections.include?(type)
      @save_operations << Operation.new("Add", $1, args[0])
    else
      super
    end
  elsif @function_imports.include?(name.to_s)
    execute_import_function(name.to_s, args)
  else
    super
  end
end

Instance Attribute Details

- (Object) class_metadata (readonly)

Returns the value of attribute class_metadata



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def 
  @class_metadata
end

- (Object) classes (readonly)

Returns the value of attribute classes



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def classes
  @classes
end

- (Object) collections (readonly)

Returns the value of attribute collections



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def collections
  @collections
end

- (Object) edmx (readonly)

Returns the value of attribute edmx



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def edmx
  @edmx
end

- (Object) function_imports (readonly)

Returns the value of attribute function_imports



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def function_imports
  @function_imports
end

- (Object) options (readonly)

Returns the value of attribute options



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def options
  @options
end

- (Object) response (readonly)

Returns the value of attribute response



4
5
6
# File 'lib/ruby_odata/service.rb', line 4

def response
  @response
end

Instance Method Details

Adds a child object to a parent object's collection

Raises:

  • (NotSupportedError)

    if the parent isn't a tracked entity

  • (ArgumentError)

    if the nav_prop isn't a valid navigation property

  • (NotSupportedError)

    if the child isn't a tracked entity



163
164
165
166
167
168
169
# File 'lib/ruby_odata/service.rb', line 163

def add_link(parent, nav_prop, child)
  raise NotSupportedError, "You cannot add a link on an entity that isn't tracked (#{parent.class})" if parent.send(:__metadata).nil?
  raise ArgumentError, "'#{nav_prop}' is not a valid navigation property for #{parent.class}" unless parent.respond_to?(nav_prop.to_sym)
  raise ArgumentError, "'#{nav_prop}' is not a valid navigation property for #{parent.class}" unless @class_metadata[parent.class.to_s][nav_prop].nav_prop
  raise NotSupportedError, "You cannot add a link on a child entity that isn't tracked (#{child.class})" if child.send(:__metadata).nil?
  @save_operations << Operation.new("AddLink", nav_prop, parent, child)
end

- (Object) delete_object(obj)

Queues an object for deletion. To actually remove it from the server, you must call save_changes as well.

Raises:



49
50
51
52
53
54
55
56
# File 'lib/ruby_odata/service.rb', line 49

def delete_object(obj)
  type = obj.class.to_s
  if obj.respond_to?(:__metadata) && !obj.send(:__metadata).nil?
    @save_operations << Operation.new("Delete", type, obj)
  else
    raise OData::NotSupportedError.new "You cannot delete a non-tracked entity"
  end
end

- (Object) execute

Performs query operations (Read) against the server. Typically this returns an array of record instances, except in the case of count queries

Raises:

  • (ServiceError)

    if there is an error when talking to the service



98
99
100
101
102
103
104
105
106
# File 'lib/ruby_odata/service.rb', line 98

def execute
  begin
    @response = RestClient::Resource.new(build_query_uri, @rest_options).get
  rescue Exception => e
    handle_exception(e)
  end
  return Integer(@response) if @response =~ /^\d+$/
  handle_collection_result(@response)
end

- (Object) load_property(obj, nav_prop)

Lazy loads a navigation property on a model

Raises:

  • (NotSupportedError)

    if the obj isn't a tracked entity

  • (ArgumentError)

    if the nav_prop isn't a valid navigation property



146
147
148
149
150
151
152
153
# File 'lib/ruby_odata/service.rb', line 146

def load_property(obj, nav_prop)
  raise NotSupportedError, "You cannot load a property on an entity that isn't tracked" if obj.send(:__metadata).nil?
  raise ArgumentError, "'#{nav_prop}' is not a valid navigation property" unless obj.respond_to?(nav_prop.to_sym)
  raise ArgumentError, "'#{nav_prop}' is not a valid navigation property" unless @class_metadata[obj.class.to_s][nav_prop].nav_prop
  results = RestClient::Resource.new(build_load_property_uri(obj, nav_prop), @rest_options).get
  prop_results = build_classes_from_result(results)
  obj.send "#{nav_prop}=", (singular?(nav_prop) ? prop_results.first : prop_results)
end

- (Object) next

Retrieves the next resultset of a partial result (if any). Does not honor the :eager_partial option.



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

def next
  return if not partial?
  handle_partial
end

- (Boolean) partial?

Does the most recent collection returned represent a partial collection? Will aways be false if a query hasn't executed, even if the query would have a partial



135
136
137
# File 'lib/ruby_odata/service.rb', line 135

def partial?
  @has_partial
end

- (Boolean) respond_to?(method)

Overridden to identify methods handled by method_missing



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ruby_odata/service.rb', line 109

def respond_to?(method)
  if @collections.include?(method.to_s)
    return true
  # Adds
  elsif method.to_s =~ /^AddTo(.*)/
    type = $1
    if @collections.include?(type)
      return true
    else
      super
    end
  # Function Imports
  elsif @function_imports.include?(method.to_s)
    return true
  else
    super
  end
end

- (Object) save_changes

Performs save operations (Create/Update/Delete) against the server



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ruby_odata/service.rb', line 73

def save_changes
  return nil if @save_operations.empty?

  result = nil

  begin
    if @save_operations.length == 1
      result = single_save(@save_operations[0])
    else
      result = batch_save(@save_operations)
    end

    # TODO: We should probably perform a check here
    # to make sure everything worked before clearing it out
    @save_operations.clear

    return result
  rescue Exception => e
    handle_exception(e)
  end
end

- (Object) update_object(obj)

Queues an object for update. To actually update it on the server, you must call save_changes as well.

Raises:



63
64
65
66
67
68
69
70
# File 'lib/ruby_odata/service.rb', line 63

def update_object(obj)
  type = obj.class.to_s
  if obj.respond_to?(:__metadata) && !obj.send(:__metadata).nil?
    @save_operations << Operation.new("Update", type, obj)
  else
    raise OData::NotSupportedError.new "You cannot update a non-tracked entity"
  end
end