class CTioga2::Data::Backends::Backend

This class provides the infrastructure for accessing data sets. It shouldn't be used directly, but rather subclassed and reimplemented. The aim of this class is to provide any software which is interested to retrive data from some source with a consistent way to do so, independent the kind of source accessed.

todo update documentation.

Subclasses should:

todo adapt to the new structure.

todo add back filters (with time)

todo add a Cache ?

Public Class Methods

describe(name, longname, desc, register = true) click to toggle source

Creates a description object with the given texts and associates it with the class. It is necessary to have this statement before any parameter declaration. If you don't set any description, you will not be able to benefit from the plugin system. To be used in Backend subclasses, simply this way:

describe "biniou", "Biniou backend", "A backend to deal with Binious"
# File lib/ctioga2/data/backends/backend.rb, line 90
def Backend.describe(name, longname, desc, register = true)
  d = BackendDescription.new(self, name, longname, desc, register)
  set_description(d)
end
list_backends() click to toggle source

Returns a hash containing the description of all available backends

# File lib/ctioga2/data/backends/backend.rb, line 97
def Backend.list_backends
  return factory_description_hash
end
new() click to toggle source

Sets up a few things, such as the filters.

# File lib/ctioga2/data/backends/backend.rb, line 73
def initialize
end

Public Instance Methods

dataset(set) click to toggle source

Public interface to query DataSet from a Backend. Children must redefine query_dataset rather than this function. This function also applies filters and does othe kinds of transformations

# File lib/ctioga2/data/backends/backend.rb, line 129
def dataset(set)
  return query_dataset(set)
end
description() click to toggle source

Returns the BackendDescription associated with this Backend.

# File lib/ctioga2/data/backends/backend.rb, line 77
def description
  return self.class.description
end
expand_sets(spec) click to toggle source

When converting a user input into a set, a program should always use this function, unless it has really good reasons for that.

The default implementation is to expand 2##4 to 2, 3, 4. Can be useful even for mathematical stuff.

Another thing is recognised and expanded: #<2<i*2>,5> runs the code i*2 with the values from 2 to 5 and returns the result. The code in the middle is a Ruby block, and therefore should be valid !

A third expansion is now available: #<a = 2<a * sin(x)>10> will expand into 2*sin(x) , 3*sin(x) … 10*sin(x) it is different than the previous in the sense that the code in the middle is not a Ruby code, but a mere string, which means there won't be compilation problems.

Unless your backend can't accomodate for that, all redefinitions of this function should check for their specific signatures first and call this function if they fail. This way, they will profit from improvements in this code while keeping old stuff working.

# File lib/ctioga2/data/backends/backend.rb, line 157
def expand_sets(spec)
  if m = /(\d+)##(\d+)/.match(spec)
    debug { "Using expansion rule #1" }
    a = m[1].to_i
    b = m[2].to_i
    ret = []
    a.upto(b) do |i|
      ret << m.pre_match + i.to_s + m.post_match
    end
    return ret
  elsif m = /\#<(\d+)<(.*?)>(\d+)>/.match(spec)
    debug { "Using expansion rule #2" }
    from = m[1].to_i
    to = m[3].to_i
    debug { "Ruby code used for expansion: {|i| #{m[2]} }" }
    code = eval "proc {|i| #{m[2]} }"
    ret = []
    from.upto(to) do |i|
      ret << m.pre_match + code.call(i).to_s + m.post_match
    end
    return ret
  elsif m = /\#<\s*(\w+)\s*=\s*(\d+)\s*<(.*?)>\s*(\d+)\s*>/.match(spec)
    debug { "Using expansion rule #3" }
    var = m[1]
    from = m[2].to_i
    to = m[4].to_i
    # Then we replace all occurences of the variable
    literal = '"' + m[3].gsub(/\b#{var}\b/, '#{' + var + '}') + '"'
    debug { "Ruby code used for expansion: {|#{var}| #{literal} }" }
    code = eval "proc {|#{var}| #{literal} }"
    ret = []
    from.upto(to) do |i|
      ret << m.pre_match + code.call(i).to_s + m.post_match
    end
    return ret
  end
  # Fallback
  return [spec]
rescue  Exception => ex
  # In case something went wrong in the eval.
  warn { "An error occured during expansion of '#{spec}': #{ex.message}" }
  debug { "Error backtrace: #{ex.backtrace.join "\n"}" }
  warn {
    "Ignoring, but you're nearly garanteed something will "+
    "fail later on"
  }
  return [spec]
end
has_set?(set) click to toggle source

Returns true if the backend can provide data for the given set.

# File lib/ctioga2/data/backends/backend.rb, line 118
def has_set?(set)
  return false
end
Also aliased as: set?
set?(set)
Alias for: has_set?
set_param_from_string(param, string) click to toggle source

Directly set a named parameter

# File lib/ctioga2/data/backends/backend.rb, line 220
def set_param_from_string(param, string)
  description.param_hash[param].set_from_string(self, string)
end
sets_available() click to toggle source

Some backends have a pretty good idea of the sets available for use. Some really don't. You can choose to reimplement this function if you can provide a useful list of sets for your backend. This list doesn't need to be exhaustive (and is most unlikely to be). It can also return something that would need further expansion using expand_sets.

# File lib/ctioga2/data/backends/backend.rb, line 212
def sets_available
  return []
end

Protected Instance Methods

get_cached_entry(name, exclude = [], supp_info = {}, &code) click to toggle source

Gets a cached entry or generate it and cache it. See Cache#cache for more details. The cache's meta_data is constructed as following:

  • the current state of the backend is taken

  • keys inside exclude are removed.

  • supp_info is added

todo get the implementation back again.

# File lib/ctioga2/data/backends/backend.rb, line 245
def get_cached_entry(name, exclude = [], supp_info = {}, &code)
  raise YetUnimplemented
  state = save_state
  for k in exclude
    state.delete(k)
  end
  state.merge!(supp_info)
  return @cache.get_cache(name, state, &code)
end
query_dataset(set) click to toggle source

Returns a DataSet object for the given set. Must be reimplemented by children. The public interface is dataset.

It is strongly recommended to use Dataset.dataset_from_spec to create the Dataset return values in reimplementations.

# File lib/ctioga2/data/backends/backend.rb, line 232
def query_dataset(set)
  raise "query_dataset must be redefined by children !"
end