class PIM::Services::Loader
Public Class Methods
# File services.rb, line 388 def self.is_cached? object return (object.respond_to?(:cached?) and object.cached?) end
Default load method execute a request on the specified data module
# File services.rb, line 328 def self.load data_module, request, *loaders return request.empty_result if loaders.empty? # Check if loaders can handle the request result = load_from_next_loader(data_module, request, *loaders) # If no result was returned and the request has a redirect block, execute that block if result.nil? and request.redirect? result = request.redirect(data_module, *loaders) end # Depending on the request's return_type, we need to update the result if request.return_type == Hash # If result is an Array and no keys were requested, # it denotes the list of the actual keys to use. # In this case, create a new request with those keys # and try again! if PIM.is_array?(result) and not result.empty? and request.keys.empty? request = request.copy(keys: result) result = load(data_module, request, *loaders) end elsif request.return_type == Array # If result is a Hash, we expect the values of each Hash entry to be Arrays, # so simply combine all values if PIM.is_hash?(result) result = result.values.flatten.compact.uniq end end return result || request.empty_result end
Helper method to return the result using the next loader in the list
# File services.rb, line 367 def self.load_from_next_loader data_module, request, *loaders loader = loaders.shift return loader.load(data_module, request, *loaders) unless loader.nil? end
# File services.rb, line 372 def self.set_cached object, cached = true if cached class << object def cached? true end end else class << object def cached? false end end end end
Public Instance Methods
Implement in subclass
# File services.rb, line 500 def close end
Override in subclass
# File services.rb, line 463 def enabled? true end
Implement in subclass
# File services.rb, line 489 def get data_module, request return nil end
Helper method to create the base key for flat key-value loaders
# File services.rb, line 614 def get_base_key request base_keys = get_base_keys(request) return base_keys.join(':') end
Helper method to create the base keys for structured key-value loaders
# File services.rb, line 606 def get_base_keys request base_keys = [ request.request_name ] base_keys += request.parent unless request.parent.nil? return base_keys end
Helper method to retrieve the data-model definitions file from a data_module
# File services.rb, line 515 def get_data_model_definitions_file data_module, *file_extensions if PIM.has_module?(data_module) data_module.get_data_model_definitions_file(*file_extensions) else nil end end
Helper method for structured key-value repositories to get the result from a “repository”.
# File services.rb, line 526 def get_from_repository repository, request, cached: false, return_nil: false return nil if repository.nil? or repository.empty? or request.nil? # Get the base repository, if it exists base_keys = get_base_keys(request) base_keys.each do |base_key| repository = repository[base_key] return nil if repository.nil? or repository.empty? end # If no keys were specified in the request, # return the cached list of ALL keys, if it exists if request.keys.empty? result = repository[nil] elsif request.return_type == Hash result = {} request.keys.each do |key| # Only add 'nil' results if explicitly allowed. # E.g. for a caching loader, only return nil if previously added by 'put'. # Otherwise we would not check the next loaders! next unless (return_nil or repository.include?(key)) result[key] = repository[key] end end # Mark the result as "cached", if necessary Loader.set_cached(result, cached) return result end
Default implementation to get redirected result from next loader
# File services.rb, line 483 def get_redirect data_module, request, *loaders return load_from_next_loader(data_module, request, *loaders) end
Helper method to retrieve the service-name from a data_module
# File services.rb, line 505 def get_service_name data_module if PIM.has_module?(data_module) data_module.service_name else data_module end end
Actual load method executed on a Loader
instance. Note that the result is NOT update according to the request’s return type, i.e. the result could be an Array even though a Hash is expected!
# File services.rb, line 396 def load data_module, request, *loaders # Skip loader, if it is not enabled return load_from_next_loader(data_module, request, *loaders) unless enabled? # Handle redirect request, if necessary return get_redirect(data_module, request, *loaders) if request.redirect? # Get loader specific result result = get(data_module, request) if PIM.is_hash?(result) # Result is a Hash with entries per key, so determine the missing keys to load from the next loaders missing_keys = request.keys - result.keys elsif PIM.is_array?(result) # Result is an Array of keys, so no additional loading is necessary return result else # Nothing was found, so get the result from the next loader missing_keys = nil end # Get and merge the missing result from next loader if missing_keys.nil? or not missing_keys.empty? # Create a new request, if necessary if PIM.is_array?(missing_keys) and missing_keys.to_set != request.keys.to_set request = request.copy(keys: missing_keys) end missing_result = load_from_next_loader(data_module, request, *loaders) unless missing_result.nil? # Cache missing result put(data_module, request, missing_result) # Merge missing Hash result, if possible, otherwise directly use as result if PIM.is_hash?(missing_result) if result.nil? result = missing_result elsif PIM.is_hash?(result) result = result.merge(missing_result) end elsif PIM.is_array?(missing_result) # Directly use the missing result as result result = missing_result end end end return result end
Default implementation to load result from the next loader, unless no next loader should be used.
# File services.rb, line 470 def load_from_next_loader data_module, request, *loaders return nil unless use_next_loader?(data_module) Loader.load_from_next_loader(data_module, request, *loaders) end
Implement in subclass
# File services.rb, line 495 def put data_module, request, result end
Helper method for structured key-value repositories to put the result into a “repository”.
# File services.rb, line 568 def put_into_repository repository, request, result # Only put result into repository if it was not marked as "cached" already return if Loader.is_cached?(result) # Get or create the base repository base_keys = get_base_keys(request) base_keys.each do |base_key| repository[base_key] ||= {} repository = repository[base_key] end # If result is an Array, cache it using the 'ALL' key if PIM.is_array?(result) and request.actual_keys.empty? repository[nil] = result elsif PIM.is_hash?(result) and request.return_type == Hash # If no keys were specified in the actual request, # and the 'ALL' key was not cached yet, # then the result is supposed to include ALL values. # In this case, cache all keys using the 'ALL' key. if request.actual_keys.empty? and repository[nil].nil? repository[nil] = result.keys end # Add result to repository result.each_pair do |key, value| repository[key] = value end end end
Override in subclass
# File services.rb, line 477 def use_next_loader? data_module true end