Class: OMF::Web::DataSourceProxy

Inherits:
Common::LObject show all
Defined in:
lib/omf-web/data_source_proxy.rb

Overview

This object maintains synchronization between a JS DataSource object in a web browser and the corresponding OmlTable in this server.

Constant Summary collapse

@@datasources =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Common::Loggable

#_logger, #debug, #error, #fatal, #info, init_log, logger, set_environment, #warn

Constructor Details

#initialize(name, data_source) ⇒ DataSourceProxy

Returns a new instance of DataSourceProxy.



158
159
160
161
# File 'lib/omf-web/data_source_proxy.rb', line 158

def initialize(name, data_source)
  @name = name
  @data_source = data_source
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



100
101
102
# File 'lib/omf-web/data_source_proxy.rb', line 100

def name
  @name
end

Class Method Details

.[](name) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/omf-web/data_source_proxy.rb', line 35

def self.[](name)
  name = name.to_sym
  unless dsp = OMF::Web::SessionStore[name, :dsp]
    if ds = @@datasources[name]
      dsp = OMF::Web::SessionStore[name, :dsp] = self.new(name, ds)
    else
      warn "Requesting unknown datasource '#{name}', only know about '#{@@datasources.keys.join(', ')}'."
    end
  end
  dsp
end

.for_source(ds_descr) ⇒ Object

Return proxies for ‘ds_name’. Note, there can be more then one proxy be needed for a datasource, such as a network which has one ds for the nodes and one for the links

@return: Array of proxies

TODO: This seems to hardcode networks.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/omf-web/data_source_proxy.rb', line 55

def self.for_source(ds_descr)
  #raise "FOO #{ds_descr.inspect}"
  unless ds_descr.is_a? Hash
    raise "Expected Hash, but got '#{ds_descr.class}::#{ds_descr.inspect}'"
  end
  unless ds_name = ds_descr[:name]
    raise "Missing 'name' attribute in datasource description. (#{ds_descr.inspect})"
  end
  ds_name = ds_name.to_sym
  ds = @@datasources[ds_name]
  unless ds
    # let's check for sub table, such as network/nodes
    main, sub = ds_descr[:name].split('/')
    if (sub)
      if ds_top = @@datasources[main.to_sym]
        ds = ds_top[sub.to_sym]
      end
    end
    unless ds
      raise "Unknown data source '#{ds_name}' (#{@@datasources.keys.inspect})"
    end
  end
  if ds.is_a? Hash
    proxies = ds.map do |name, ds|
      id = "#{ds_name}_#{name}".to_sym
      proxy = OMF::Web::SessionStore[id, :dsp] ||= self.new(id, ds)
    end
    return proxies
      
    # n_name = "#{ds_name}_nodes".to_sym
    # l_name = "#{ds_name}_links".to_sym
    # if (nodes = OMF::Web::SessionStore[n_name, :dsp])
      # # assume links exist as well
      # links = OMF::Web::SessionStore[l_name, :dsp]                
    # else
      # nodes = OMF::Web::SessionStore[n_name, :dsp] = self.new(n_name, ds[:nodes])
      # links = OMF::Web::SessionStore[l_name, :dsp] = self.new(l_name, ds[:links])
    # end
    # return [nodes, links]
  end
  
  proxy = OMF::Web::SessionStore[ds_name, :dsp] ||= self.new(ds_name, ds)
  return [proxy]
end

.register_datasource(data_source, opts = {}) ⇒ Object

Register a data source.

params data_source - Data source to register params opts:

name - Name to use instead of data source's native name


22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/omf-web/data_source_proxy.rb', line 22

def self.register_datasource(data_source, opts = {})
  name = (opts[:name] || data_source.name).to_sym
  if (@@datasources.key? name)
    raise "Repeated try to register data source '#{name}'"
  end
  if data_source.is_a? OMF::OML::OmlNetwork
    dsh = data_source.to_tables(opts)
    @@datasources[name] = dsh
  else
    @@datasources[name] = data_source
  end
end

Instance Method Details

#create_slice(col_name, col_value) ⇒ Object

Create a new data source which only contains a slice of the underlying data source



131
132
133
134
135
136
# File 'lib/omf-web/data_source_proxy.rb', line 131

def create_slice(col_name, col_value)
  ds = @data_source.create_sliced_table(col_name, col_value)
  dsp = self.class.new(ds.name, ds)
  def dsp.release; @data_source.release end
  dsp
end

#on_changed(offset, &block) ⇒ Object

Register callback to be informed of changes to the underlying data source. Call block when new rows are becoming available. Block needs ot return true if it wants to continue receiving updates.

offset: Number of records already downloaded



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/omf-web/data_source_proxy.rb', line 117

def on_changed(offset, &block)
  ds = @data_source
  rows = ds.rows[(offset - ds.offset) .. -1]
  if rows && rows.length > 0
    debug "on_changed: sending #{rows.length}"
    block.call rows, ds.offset
  end
  @data_source.on_row_added(block.object_id) do |row, offset|
    debug "on_changed: more data: #{row.inspect}"
    block.call [row], offset
  end
end

#on_update(req) ⇒ Object



106
107
108
109
# File 'lib/omf-web/data_source_proxy.rb', line 106

def on_update(req)
  res = {:events => @data_source.rows}
  [res.to_json, "text/json"]
end

#resetObject



102
103
104
# File 'lib/omf-web/data_source_proxy.rb', line 102

def reset()
  # TODO: Figure out partial sending 
end

#to_javascript(opts = {}) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/omf-web/data_source_proxy.rb', line 138

def to_javascript(opts = {})
  #puts "to_java>>>>> #{opts.inspect}"
  sid = Thread.current["sessionID"]
  opts = opts.dup
  opts[:name] = @name
  opts[:schema] = @data_source.schema
  opts[:update_url] = "/_update/#{@name}?sid=#{sid}"
  opts[:sid] = sid
  unless opts[:slice] # don't send any data if this is a sliced one
    opts[:rows] = @data_source.rows[0 .. 20]
    opts[:offset] = @data_source.offset
  end
  #puts "to_java2>>>>> #{opts.to_json.inspect}"
  
  %{
    OML.data_sources.register(#{opts.to_json});
  }
 
end