rails_notebook 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +22 -0
- data/app/assets/javascripts/rails_notebook/application.js +13 -0
- data/app/assets/stylesheets/rails_notebook/application.css +15 -0
- data/app/controllers/rails_notebook/application_controller.rb +4 -0
- data/app/helpers/rails_notebook/application_helper.rb +4 -0
- data/app/views/layouts/rails_notebook/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/rails_notebook.rb +14 -0
- data/lib/rails_notebook/assets/d3.js +9553 -0
- data/lib/rails_notebook/assets/dagre-d3.js +17572 -0
- data/lib/rails_notebook/assets/jquery.jsonview.css +52 -0
- data/lib/rails_notebook/assets/jquery.jsonview.js +284 -0
- data/lib/rails_notebook/assets/jquery.qtip.min.css +2 -0
- data/lib/rails_notebook/assets/jquery.qtip.min.js +3 -0
- data/lib/rails_notebook/assets/jquery.tipsy.js +288 -0
- data/lib/rails_notebook/assets/kernel.css +7 -0
- data/lib/rails_notebook/assets/kernel.js +18 -0
- data/lib/rails_notebook/assets/kernel.json +1 -0
- data/lib/rails_notebook/assets/logo-32x32.png +0 -0
- data/lib/rails_notebook/assets/logo-64x64.png +0 -0
- data/lib/rails_notebook/assets/nv.d3.css +641 -0
- data/lib/rails_notebook/assets/nv.d3.js +13298 -0
- data/lib/rails_notebook/assets/rails_notebook.css +136 -0
- data/lib/rails_notebook/assets/rails_notebook.js +548 -0
- data/lib/rails_notebook/assets/tipsy.css +25 -0
- data/lib/rails_notebook/command.rb +104 -0
- data/lib/rails_notebook/engine.rb +9 -0
- data/lib/rails_notebook/profiler.rb +111 -0
- data/lib/rails_notebook/renderers.rb +121 -0
- data/lib/rails_notebook/route.rb +121 -0
- data/lib/rails_notebook/schemaTable.rb +27 -0
- data/lib/rails_notebook/serializers.rb +92 -0
- data/lib/rails_notebook/table.rb +28 -0
- data/lib/rails_notebook/version.rb +3 -0
- data/lib/tasks/rails_notebook_tasks.rake +8 -0
- metadata +196 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
|
2
|
+
.tipsy-inner { background-color: #000; color: #FFF; max-width: 600px; padding: 5px 8px 4px 8px; text-align: center; }
|
3
|
+
|
4
|
+
/* Rounded corners */
|
5
|
+
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
|
6
|
+
|
7
|
+
/* Uncomment for shadow */
|
8
|
+
/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
|
9
|
+
|
10
|
+
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
|
11
|
+
|
12
|
+
/* Rules to colour arrows */
|
13
|
+
.tipsy-arrow-n { border-bottom-color: #000; }
|
14
|
+
.tipsy-arrow-s { border-top-color: #000; }
|
15
|
+
.tipsy-arrow-e { border-left-color: #000; }
|
16
|
+
.tipsy-arrow-w { border-right-color: #000; }
|
17
|
+
|
18
|
+
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
|
19
|
+
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
20
|
+
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
21
|
+
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
22
|
+
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
23
|
+
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
24
|
+
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
|
25
|
+
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module RailsNotebook
|
5
|
+
|
6
|
+
class Command
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
ipython_dir = ENV['IPYTHONDIR'] || '~/.ipython'
|
10
|
+
@kernel_dir = File.join(File.expand_path(ipython_dir), 'kernels', 'rails_notebook')
|
11
|
+
@kernel_file = File.join(@kernel_dir, 'kernel.json')
|
12
|
+
puts @kernel_file
|
13
|
+
@iruby_path = File.expand_path $0
|
14
|
+
puts @iruby_path
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_kernel
|
18
|
+
require 'iruby/logger'
|
19
|
+
IRuby.logger = Rails.logger
|
20
|
+
|
21
|
+
connection_file = ENV['connection_file']
|
22
|
+
change_working_dir
|
23
|
+
|
24
|
+
IRuby::Kernel.new(connection_file).run
|
25
|
+
rescue Exception => e
|
26
|
+
IRuby.logger.fatal "Kernel died: #{e.message}\n#{e.backtrace.join("\n")}"
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_ipython
|
31
|
+
check_version
|
32
|
+
check_registered_kernel
|
33
|
+
change_working_dir
|
34
|
+
#create_static_symlink!
|
35
|
+
Kernel.exec('ipython', 'notebook')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
#================================= For Symlink
|
41
|
+
def create_static_symlink!
|
42
|
+
src, dst = static_path, File.join(profile_path, '/kernels/rails_notebook')
|
43
|
+
puts src
|
44
|
+
puts dst
|
45
|
+
FileUtils.rm_r dst
|
46
|
+
File.symlink src, dst
|
47
|
+
end
|
48
|
+
|
49
|
+
def profile_path
|
50
|
+
`ipython locate rails_notebook`.strip
|
51
|
+
#File.expand_path(".." , `ipython locate rails_notebook`.strip)
|
52
|
+
end
|
53
|
+
|
54
|
+
def static_path
|
55
|
+
File.join(File.dirname(__FILE__), "assets")
|
56
|
+
end
|
57
|
+
#================================= For Symlink
|
58
|
+
|
59
|
+
|
60
|
+
def change_working_dir
|
61
|
+
working_dir = File.join(Rails.root, "notebooks")
|
62
|
+
Dir.mkdir(working_dir) unless Dir.exist?(working_dir)
|
63
|
+
Dir.chdir(working_dir) if working_dir
|
64
|
+
end
|
65
|
+
|
66
|
+
def check_version
|
67
|
+
required = '3.0.0'
|
68
|
+
version = `ipython --version`.chomp
|
69
|
+
if version < required
|
70
|
+
STDERR.puts "Your IPython version #{version} is too old, at least #{required} is required"
|
71
|
+
exit 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def check_registered_kernel
|
76
|
+
if (kernel = registered_iruby_path)
|
77
|
+
STDERR.puts "#{@iruby_path} differs from registered path #{registered_iruby_path}.
|
78
|
+
This might not work. Run 'iruby register --force' to fix it." if @iruby_path != kernel
|
79
|
+
else
|
80
|
+
register_kernel
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def register_kernel
|
85
|
+
FileUtils.mkpath(@kernel_dir)
|
86
|
+
|
87
|
+
if RUBY_PLATFORM =~ /mswin(?!ce)|mingw|cygwin/
|
88
|
+
ruby_path, iruby_path = [RbConfig.ruby, @iruby_path].map { |path| path.gsub('/', '\\\\') }
|
89
|
+
File.write(@kernel_file, MultiJson.dump(argv: [ruby_path, iruby_path, 'rails_notebook_kernel', 'connection_file={connection_file}'],
|
90
|
+
display_name: "Rails #{Rails.application.class.to_s}", language: 'ruby'))
|
91
|
+
else
|
92
|
+
File.write(@kernel_file, MultiJson.dump(argv: [@iruby_path, 'rails_notebook_kernel', 'connection_file={connection_file}'],
|
93
|
+
display_name: "Rails #{Rails.application.class.to_s}", language: 'ruby'))
|
94
|
+
end
|
95
|
+
|
96
|
+
FileUtils.copy(Dir[File.join(__dir__, 'assets', '*')], @kernel_dir) rescue nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def registered_iruby_path
|
100
|
+
File.exist?(@kernel_file) && MultiJson.load(File.read(@kernel_file))['argv'].first
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#https://github.com/SamSaffron/flamegraph/
|
2
|
+
#Modified from Sam Saffron's original code for flamegraph
|
3
|
+
require "json"
|
4
|
+
require "stackprof"
|
5
|
+
|
6
|
+
module Profiler
|
7
|
+
def self.profile(filename=nil, opts = {})
|
8
|
+
backtraces = nil;
|
9
|
+
fidelity = opts[:fidelity] || 0.05
|
10
|
+
backtraces = StackProfSampler.collect( fidelity ) do yield end
|
11
|
+
Profiler::Profile.new( Profiler::generate_data( backtraces ) , fidelity )
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.generate_data( stacks )
|
15
|
+
table = []
|
16
|
+
prev = []
|
17
|
+
|
18
|
+
# a 2d array makes collapsing easy
|
19
|
+
stacks.each_with_index do |stack, pos|
|
20
|
+
next unless stack
|
21
|
+
col = []
|
22
|
+
|
23
|
+
stack.reverse.map{|r| r.to_s}.each_with_index do |frame, i|
|
24
|
+
if !prev[i].nil?
|
25
|
+
last_col = prev[i]
|
26
|
+
if last_col[0] == frame
|
27
|
+
last_col[1] += 1
|
28
|
+
col << nil
|
29
|
+
next
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
prev[i] = [frame, 1]
|
34
|
+
col << prev[i]
|
35
|
+
end
|
36
|
+
prev = prev[0..col.length-1].to_a
|
37
|
+
table << col
|
38
|
+
end
|
39
|
+
|
40
|
+
data = []
|
41
|
+
# a 1d array makes rendering easy
|
42
|
+
table.each_with_index do |col, col_num|
|
43
|
+
col.each_with_index do |row, row_num|
|
44
|
+
next unless row && row.length == 2
|
45
|
+
data << {
|
46
|
+
:x => col_num + 1,
|
47
|
+
:y => row_num + 1,
|
48
|
+
:width => row[1],
|
49
|
+
:frame => row[0]
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
data
|
54
|
+
end
|
55
|
+
|
56
|
+
class Profile
|
57
|
+
def initialize( data, _sampleTime )
|
58
|
+
@data = data
|
59
|
+
@sampleTime = _sampleTime
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class StackProfSampler
|
64
|
+
def self.collect(fidelity=0.5)
|
65
|
+
result = StackProf.run(mode: :wall,
|
66
|
+
raw: true,
|
67
|
+
aggregate: false,
|
68
|
+
interval: (fidelity * 1000).to_i) do
|
69
|
+
yield
|
70
|
+
end
|
71
|
+
|
72
|
+
stacks = []
|
73
|
+
stack = []
|
74
|
+
|
75
|
+
return [] unless result[:raw]
|
76
|
+
|
77
|
+
length = nil
|
78
|
+
result[:raw].each do |i|
|
79
|
+
if length.nil?
|
80
|
+
length = i
|
81
|
+
next
|
82
|
+
end
|
83
|
+
|
84
|
+
if length > 0
|
85
|
+
frame = result[:frames][i]
|
86
|
+
frame = "#{frame[:file]}:#{frame[:line]}:in `#{frame[:name]}'"
|
87
|
+
# puts frame
|
88
|
+
#if frame.to_s =~ /iruby/ && !( frame.to_s =~ /IRuby::/ )
|
89
|
+
s = frame.to_s
|
90
|
+
if !( s =~ /application.rb/ ) &&
|
91
|
+
!( s =~ /Rake::Application/) &&
|
92
|
+
!( s =~ /task.rb/) &&
|
93
|
+
!( s =~ /kernel.rb/) &&
|
94
|
+
!( s =~ /profiler.rb/)
|
95
|
+
stack << frame.to_s
|
96
|
+
end
|
97
|
+
length -= 1
|
98
|
+
next
|
99
|
+
end
|
100
|
+
|
101
|
+
i.times do
|
102
|
+
stacks << stack.reverse
|
103
|
+
end
|
104
|
+
|
105
|
+
stack = []
|
106
|
+
length = nil
|
107
|
+
end
|
108
|
+
stacks
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module RailsNotebook
|
4
|
+
|
5
|
+
module Renderers
|
6
|
+
|
7
|
+
def self.pretty_print_json( json )
|
8
|
+
<<-HTML
|
9
|
+
<div id="json-#{json.object_id}"></div>
|
10
|
+
<script>
|
11
|
+
require(["jquery", "/kernelspecs/rails_notebook/jquery.jsonview.js"], function ($, jsonview) {
|
12
|
+
$("#json-#{json.object_id}").JSONView( #{json} );
|
13
|
+
});
|
14
|
+
</script>
|
15
|
+
HTML
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.render_html( object , functionName )
|
19
|
+
<<-HTML
|
20
|
+
<div id="railsnb-#{object.object_id}"></div>
|
21
|
+
<script>
|
22
|
+
require(["/kernelspecs/rails_notebook/rails_notebook.js"] , function ( railsNB ) {
|
23
|
+
railsNB.#{functionName}( #{MultiJson.dump(object)} , document.getElementById( "railsnb-#{object.object_id}" ) );
|
24
|
+
});
|
25
|
+
</script>
|
26
|
+
HTML
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
IRuby::Display::Registry.type { String }
|
31
|
+
IRuby::Display::Registry.format("text/html") do |string|
|
32
|
+
begin JSON.parse( string )
|
33
|
+
Renderers.pretty_print_json( string )
|
34
|
+
rescue
|
35
|
+
string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
IRuby::Display::Registry.type { Rails.application }
|
40
|
+
IRuby::Display::Registry.format("text/html") do |obj|
|
41
|
+
Renderers.json_view( Serializers.serialize(obj) )
|
42
|
+
end
|
43
|
+
|
44
|
+
IRuby::Display::Registry.type { Profiler::Profile }
|
45
|
+
IRuby::Display::Registry.format("text/html") do |profiledData|
|
46
|
+
Renderers.render_html( profiledData, "renderFlamechart" )
|
47
|
+
end
|
48
|
+
|
49
|
+
IRuby::Display::Registry.type { ActionDispatch::Routing::RouteSet }
|
50
|
+
IRuby::Display::Registry.format("text/html") do |route_set|
|
51
|
+
all_routes = route_set.routes.to_a
|
52
|
+
all_routes.reject! { |route| route.verb.nil? || route.path.spec.to_s == '/assets' || ( route.path.spec.to_s =~ /^\/rails(.*)/ ) || route.path.spec.to_s =~ /^\/pages(.*)/ }
|
53
|
+
routeTree = RouteTree.new( RouteNode.new( "/" , nil, nil, nil, "" ) )
|
54
|
+
all_routes.group_by { |route| route.defaults[:controller] }.each_value do |group|
|
55
|
+
group.each do |r|
|
56
|
+
routeNode = RouteNode.new( (r.path.spec.to_s.sub '(.:format)','') ,
|
57
|
+
r.verb.inspect.gsub(/^.{2}|.{2}$/, "") ,
|
58
|
+
r.name.to_s , r.defaults[:action].to_s ,
|
59
|
+
(r.path.spec.to_s.sub '(.:format)','').split("/")[-1]
|
60
|
+
)
|
61
|
+
routeTree.insertNode( routeNode )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
#routeTree.printTree() # for debugging
|
65
|
+
Renderers.render_html( routeTree, "renderRoutes" )
|
66
|
+
end
|
67
|
+
|
68
|
+
IRuby::Display::Registry.type { ActiveRecord::Base.connection.tables }
|
69
|
+
IRuby::Display::Registry.format("text/html") do |obj|
|
70
|
+
tables = [] # List of Table objects
|
71
|
+
tableNames = [] # List of table names
|
72
|
+
obj.each do |table_name|
|
73
|
+
tableNames.push(table_name.singularize.foreign_key)
|
74
|
+
end # Populates table names
|
75
|
+
|
76
|
+
obj.each do |table_name| # Finding foreign keys and populating the array of Table objects
|
77
|
+
columnsTemp = []
|
78
|
+
arrowsTo = []
|
79
|
+
ActiveRecord::Base.connection.columns(table_name).each do |c|
|
80
|
+
columnTemp = []
|
81
|
+
if (tableNames.include? c.name)
|
82
|
+
arrowsTo.push(c.name[0..-4].pluralize.downcase) # [0..-4] chops off the _id suffix for foreign keys. .humanize renmoves existing underscores, which causes bugs.
|
83
|
+
columnTemp.push("* " + c.name)
|
84
|
+
columnTemp.push(c.type.to_s)
|
85
|
+
else
|
86
|
+
columnTemp.push("- " + c.name)
|
87
|
+
columnTemp.push(c.type.to_s)
|
88
|
+
end
|
89
|
+
columnsTemp.push(columnTemp)
|
90
|
+
end # end iterating through columns in tables
|
91
|
+
tables.push(Table.new(table_name , columnsTemp , arrowsTo ))
|
92
|
+
end # end iterating through tables
|
93
|
+
tables = tables.sort_by { |x| x.arrowsTo.length }
|
94
|
+
Renderers.render_html( tables, "renderSchema" ) # Parses the array of tables to Javascript for rendering
|
95
|
+
end
|
96
|
+
|
97
|
+
IRuby::Display::Registry.type { ActiveRecord::Relation}
|
98
|
+
IRuby::Display::Registry.format("text/html") do |obj|
|
99
|
+
columnNames = []
|
100
|
+
tableData = []
|
101
|
+
tableData.push(obj.name)
|
102
|
+
obj.columns.each do |column|
|
103
|
+
columnNames.push(column.name)
|
104
|
+
end
|
105
|
+
columnNames.each do |index|
|
106
|
+
tempValues = []
|
107
|
+
tempValues.push(index)
|
108
|
+
obj[0,10].each do |row| # Display only the first ten rows
|
109
|
+
tempValues.push(row[index])
|
110
|
+
end
|
111
|
+
tableData.push(tempValues)
|
112
|
+
end
|
113
|
+
Renderers.render_html( tableData, "renderTableData" )
|
114
|
+
end # DatabaseQueries
|
115
|
+
|
116
|
+
IRuby::Display::Registry.type { SchemaTable::ChartRenderer }
|
117
|
+
IRuby::Display::Registry.format("text/html") do |obj|
|
118
|
+
Renderers.render_html( obj.data , "renderBarChart" )
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
class RouteNode
|
2
|
+
|
3
|
+
def initialize( _uriPattern , _verb , _controller , _action, _nodeUri )
|
4
|
+
@uriPattern = _uriPattern
|
5
|
+
_verb ? @verbs = [_verb] : @verbs = []
|
6
|
+
@controller = _controller
|
7
|
+
_action ? @actions = [_action] : @actions = []
|
8
|
+
@countChildrenNodes = 0
|
9
|
+
@childrenNodes = []
|
10
|
+
@nodeUri = _nodeUri
|
11
|
+
@id = self.object_id
|
12
|
+
end
|
13
|
+
def updateParams( _verb , _controller , _action )
|
14
|
+
@verbs << _verb unless _verb.nil?
|
15
|
+
@controller = _controller
|
16
|
+
@actions << _action unless _action.nil?
|
17
|
+
end
|
18
|
+
def verbs
|
19
|
+
@verbs
|
20
|
+
end
|
21
|
+
def verb
|
22
|
+
@verbs.first
|
23
|
+
end
|
24
|
+
def controller
|
25
|
+
@controller
|
26
|
+
end
|
27
|
+
def actions
|
28
|
+
@actions
|
29
|
+
end
|
30
|
+
def action
|
31
|
+
@actions.first
|
32
|
+
end
|
33
|
+
def uriPattern
|
34
|
+
@uriPattern
|
35
|
+
end
|
36
|
+
def getChildren
|
37
|
+
@childrenNodes
|
38
|
+
end
|
39
|
+
def getCountChildrenNodes
|
40
|
+
@countChildrenNodes
|
41
|
+
end
|
42
|
+
|
43
|
+
def hasRoute( uri_mapping )
|
44
|
+
@childrenNodes.each do |childNode|
|
45
|
+
if childNode.uriPattern == uri_mapping
|
46
|
+
return childNode
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def insertChild( childNode )
|
53
|
+
@childrenNodes << childNode
|
54
|
+
end
|
55
|
+
|
56
|
+
def countChildrenNodes( count )
|
57
|
+
@childrenNodes.each do |child|
|
58
|
+
count = count + child.countChildrenNodes(0)
|
59
|
+
end
|
60
|
+
@countChildrenNodes = count
|
61
|
+
count += 1
|
62
|
+
return count
|
63
|
+
end
|
64
|
+
|
65
|
+
def printNode
|
66
|
+
puts "====================NODE===================="
|
67
|
+
puts @uriPattern
|
68
|
+
puts @verbs
|
69
|
+
puts @controller
|
70
|
+
puts @actions
|
71
|
+
puts "============================================"
|
72
|
+
@childrenNodes.each do |child|
|
73
|
+
child.printNode
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
class RouteTree
|
81
|
+
def initialize( _headNode )
|
82
|
+
@headNode = _headNode
|
83
|
+
end
|
84
|
+
|
85
|
+
def insertNode( _node )
|
86
|
+
#Get route mapping and iteratively either walk the tree or insert a node at the correct position
|
87
|
+
uri_mapping = ""
|
88
|
+
thisNode = @headNode #always insert from the headNode
|
89
|
+
|
90
|
+
_node.uriPattern.split("/").each do |uri|
|
91
|
+
uri_mapping += uri + "/"
|
92
|
+
if uri_mapping[0...-1] == _node.uriPattern || uri_mapping == _node.uriPattern # We are at node to insert or update
|
93
|
+
if thisNode.uriPattern == uri_mapping # Update the parameters to include details
|
94
|
+
thisNode.updateParams( _node.verb , _node.controller , _node.action )
|
95
|
+
elsif thisNode.hasRoute( uri_mapping )
|
96
|
+
thisNode.hasRoute( uri_mapping ).updateParams( _node.verb , _node.controller , _node.action )
|
97
|
+
else
|
98
|
+
child = RouteNode.new( uri_mapping , _node.verb , _node.controller , _node.action, uri )
|
99
|
+
thisNode.insertChild( child )
|
100
|
+
end
|
101
|
+
elsif thisNode.hasRoute( uri_mapping ) # node exists so walk the tree
|
102
|
+
thisNode = thisNode.hasRoute( uri_mapping )
|
103
|
+
elsif thisNode.uriPattern == uri_mapping # already there so do nothing
|
104
|
+
#thisNode.updateParams( _node.verb , _node.controller , _node.action )
|
105
|
+
else
|
106
|
+
child = RouteNode.new( uri_mapping , nil, nil , nil, uri )
|
107
|
+
thisNode.insertChild( child )
|
108
|
+
thisNode = child
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
def removeNode( _node )
|
113
|
+
puts "removing node"
|
114
|
+
end
|
115
|
+
def getRoot
|
116
|
+
@headNode
|
117
|
+
end
|
118
|
+
def printTree
|
119
|
+
@headNode.printNode
|
120
|
+
end
|
121
|
+
end
|