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

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

Constructor Details

#initializeBackend

Sets up a few things, such as the filters.



73
74
# File 'lib/ctioga2/data/backends/backend.rb', line 73

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"


90
91
92
93
# 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_backendsObject

Returns a hash containing the description of all available backends



97
98
99
# File 'lib/ctioga2/data/backends/backend.rb', line 97

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



129
130
131
# File 'lib/ctioga2/data/backends/backend.rb', line 129

def dataset(set)
  return query_dataset(set)
end

#descriptionObject

Returns the BackendDescription associated with this Backend.



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

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.



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

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

Returns:

  • (Boolean)


118
119
120
# File 'lib/ctioga2/data/backends/backend.rb', line 118

def has_set?(set)
  return false
end

#set_param_from_string(param, string) ⇒ Object

Directly set a named parameter



220
221
222
# 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_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.



212
213
214
# File 'lib/ctioga2/data/backends/backend.rb', line 212

def sets_available
  return []
end