rails_notebook 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|