Class: Tap::Controllers::Schema

Inherits:
Tap::Controller show all
Defined in:
lib/tap/controllers/schema.rb

Overview

::controller

Instance Attribute Summary

Attributes inherited from Tap::Controller

#action, #request, #response, #server

Instance Method Summary collapse

Methods inherited from Tap::Controller

#app, call, #call, #empty_binding, inherited, #initialize, name, #persistence, #redirect, #render, #render_erb, #root, #route, #session, set, #uri

Constructor Details

This class inherits a constructor from Tap::Controller

Instance Method Details

#add(id) ⇒ Object

Adds nodes or joins to the schema. Parameters:

nodes[]

An array of nodes to add to the schema. Each entry is split using Shellwords to yield an argv; the argv initializes the node. The index of each new node is added to targets[].

sources[]

An array of source node indicies used to create a join.

targets[]

An array of target node indicies used to create a join (note the indicies of new nodes are added to targets).

Add creates and pushes new nodes onto schema as specified in nodes, then creates joins between the sources and targets. The join class is inferred by Utils.infer_join; if no join can be inferred the join class is effectively nil, and consistent with that, the node output for sources and the node input for targets is set to nil.

Notes

The nomenclature for source and target is relative to the join, and may seem backwards for the node (ex: ‘sources[]=0&targets=1’ makes a join like ‘0:1’)



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
# File 'lib/tap/controllers/schema.rb', line 59

def add(id)
  unless request.post?
    raise Tap::ServerError, "add must be performed with post"
  end
    
  round = (request['round'] || 0).to_i
  outputs = (request['outputs[]'] || []).collect {|index| index.to_i }
  inputs = (request['inputs[]'] || []).collect {|index| index.to_i }
  nodes = request['nodes[]'] || []
    
  load_schema(id) do |schema|
    nodes.each do |arg|
      next unless arg && !arg.empty?

      outputs << schema.nodes.length
      schema.nodes << Tap::Support::Node.new(Shellwords.shellwords(arg), round)
    end

    if inputs.empty? || outputs.empty?
      inputs.each {|index| schema[index].output = nil }
      outputs.each {|index| schema[index].input = round }
    else
  
      # temporary
      if inputs.length > 1 && outputs.length > 1
        raise "multi-way join specified"
      end
  
      schema.set(Tap::Support::Join, inputs, outputs)
    end
  end
    
  redirect("/schema/display/#{id}")
end

#display(id) ⇒ Object

Loads the schema indicated by id and renders ‘schema.erb’ with the default layout.



18
19
20
21
22
23
24
# File 'lib/tap/controllers/schema.rb', line 18

def display(id)
  schema = load_schema(id)
  render 'schema.erb', :locals => {
    :id => id, 
    :schema => schema
  }, :layout => true
end

#indexObject

Initializes a new schema and redirects to display.



11
12
13
14
# File 'lib/tap/controllers/schema.rb', line 11

def index
  id = initialize_schema
  redirect("/schema/display/#{id}")
end

#preview(id) ⇒ Object



173
174
175
176
# File 'lib/tap/controllers/schema.rb', line 173

def preview(id)
  response.headers['Content-Type'] = 'text/plain'
  render('preview.erb', :locals => {:id => id, :schema => schema})
end

#remove(id) ⇒ Object

Removes nodes or joins from the schema. Parameters:

sources[]

An array of source node indicies to remove.

targets[]

An array of target node indicies to remove.

Normally remove sets the node.output for each source to nil and the node.input for each target to nil. However, if a node is indicated in both sources and targets AND it has no join input/output, then it will be removed.

Notes

The nomenclature for source and target is relative to the join, and may seem backwards for the node (ex: for the sequence ‘0:1:2’, ‘targets[]=1’ breaks the join ‘0:1’ while ‘sources[]=1’ breaks the join ‘1:2’.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/tap/controllers/schema.rb', line 110

def remove(id)
  unless request.post?
    raise Tap::ServerError, "remove must be performed with post"
  end
    
  round = (request['round'] || 0).to_i
  outputs = (request['outputs[]'] || []).collect {|index| index.to_i }
  inputs = (request['inputs[]'] || []).collect {|index| index.to_i }
    
  load_schema(id) do |schema|
    # Remove joins.  Removed indicies are popped to ensure
    # that if a join was removed the node will not be.
    outputs.delete_if do |index|
      next unless node = schema.nodes[index]
      if node.input_join
        node.input = round
        true
      else
        false
      end
    end

    inputs.delete_if do |index|
      next unless node = schema.nodes[index]
      if node.output_join
        node.output = nil
        true
      else
        false
      end
    end
    
    # Remove nodes. Setting a node to nil causes it's removal during 
    # compact; orphaned joins are removed during compact as well.
    (inputs & outputs).each do |index|
      schema.nodes[index] = nil
    end
  end
    
  redirect("/schema/display/#{id}")
end

#run(id) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/tap/controllers/schema.rb', line 178

def run(id)
  unless request.post?
    raise Tap::ServerError, "run must be performed with post"
  end
    
  # it would be nice to someday put all this on a separate thread...
  schema = load_schema(id)
  tasks = server.env.tasks
  schema.build(app) do |(key, *args)|
    if const = tasks.search(key) 
      const.constantize.parse(args, app) do |help|
        raise "help not implemented"
        #redirect("/app/help/#{key}")
      end
    else
      raise ArgumentError, "unknown task: #{key}"
    end
  end
    
  Thread.new { app.run }
  redirect("/app/tail")
end

#save(id) ⇒ Object



164
165
166
167
168
169
170
171
# File 'lib/tap/controllers/schema.rb', line 164

def save(id)
  unless request.post?
    raise Tap::ServerError, "submit must be performed with post"
  end
    
  dump_schema(id, schema)
  redirect("/schema/display/#{id}")
end

#submit(id) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/tap/controllers/schema.rb', line 152

def submit(id)
  case request['action']
  when 'save'    then save(id)
  when 'preview' then preview(id)
  when 'echo'    then echo
  when 'run'
    dump_schema(id, schema)
    run(id)
  else raise Tap::ServerError, "unknown action: #{request['action']}"
  end
end

#update(id) ⇒ Object

Updates the specified schema with the request parameters. Update forwards the request to the action (‘add’ or ‘remove’) specified in the action parameter.



29
30
31
32
33
34
35
36
# File 'lib/tap/controllers/schema.rb', line 29

def update(id)
  case request['action']
  when 'add'    then add(id)
  when 'remove' then remove(id)
  when 'echo'   then echo
  else raise Tap::ServerError, "unknown action: #{request['action']}"
  end
end