Class: CTioga2::Data::Backends::Backend

Inherits:
Object
  • Object
show all
Extended by:
BackendDescriptionExtend
Includes:
Log
Defined in:
lib/ctioga2/data/backends/backend.rb

Overview

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:

  • provide a consistent method for creating themselves, with as much information as necessary, including options and default parameters. Actually, their initialize function should take no value but on the other side, the BackendDescription associated with it should make it easy to set all the parameters necessary to get one set of data.

  • provide a way to fill an OptionParser with their own parameters

  • provide a way to retrieve the data via named ‘sets’ (either 2D or 3D data, depending on the subclass)

  • provide a way to obtain all meta-informations on one dataset, such as the date, the meaning of the columns (if any), and so on.

  • provide a way to know which named sets are available, or at least a subset (or nothing if we don’t know a thing).

  • wether the actual reading of the data is done at initialization time or at query time is left to the implementor ;-) !

todo adapt to the new structure.

todo add back filters (with time)

todo add a Cache ?

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BackendDescriptionExtend

base_description, create_factory, describe, factory_class, factory_description, factory_description_hash, factory_description_list, has_factory?, inherit_parameters, param, param_accessor, param_reader, param_writer, register_class, set_description

Methods included from Log

debug, error, fatal, #format_exception, #identify, info, init_logger, logger, set_level, #spawn, warn

Constructor Details

#initializeBackend

Sets up a few things, such as the filters.



76
77
# File 'lib/ctioga2/data/backends/backend.rb', line 76

def initialize
end

Class Method Details

.describe(name, longname, desc, register = true) ⇒ Object

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"


93
94
95
96
# File 'lib/ctioga2/data/backends/backend.rb', line 93

def Backend.describe(name, longname, desc, register = true)
  d = BackendDescription.new(self, name, longname, desc, register)
  set_description(d)
end

.list_backendsObject

Returns a hash containing the description of all available backends



100
101
102
# File 'lib/ctioga2/data/backends/backend.rb', line 100

def Backend.list_backends
  return factory_description_hash
end

Instance Method Details

#dataset(set) ⇒ Object

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



132
133
134
# File 'lib/ctioga2/data/backends/backend.rb', line 132

def dataset(set)
  return query_dataset(set)
end

#descriptionObject

Returns the BackendDescription associated with this Backend.



80
81
82
# File 'lib/ctioga2/data/backends/backend.rb', line 80

def description
  return self.class.description
end

#expand_sets(spec) ⇒ Object

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.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/ctioga2/data/backends/backend.rb', line 160

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) ⇒ Boolean Also known as: set?

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

Returns:

  • (Boolean)


121
122
123
# File 'lib/ctioga2/data/backends/backend.rb', line 121

def has_set?(set)
  return false
end

#set_param_from_string(param, string) ⇒ Object

Directly set a named parameter



223
224
225
# File 'lib/ctioga2/data/backends/backend.rb', line 223

def set_param_from_string(param, string)
  description.param_hash[param].set_from_string(self, string)
end

#sets_availableObject

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.



215
216
217
# File 'lib/ctioga2/data/backends/backend.rb', line 215

def sets_available
  return []
end