rails_info 0.0.3 → 0.0.4

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.
@@ -61,3 +61,7 @@ code {
61
61
  //
62
62
  // Example:
63
63
  // @linkColor: #ff0000;
64
+
65
+ #log_rails_root {
66
+ width: auto;
67
+ }
@@ -13,7 +13,7 @@ class RailsInfo::Logs::Server::ActionPresenter < ::RailsInfo::Presenter
13
13
  html += content_tag(:div, class: 'tabs', id: "tabs-#{@index}") do
14
14
  raw(navigation) + raw(body)
15
15
  end
16
-
16
+
17
17
  html
18
18
  end
19
19
 
@@ -24,7 +24,7 @@ class RailsInfo::Logs::Server::ActionPresenter < ::RailsInfo::Presenter
24
24
  @tab_index = 0
25
25
 
26
26
  elements = ''
27
-
27
+
28
28
  @tabs_data.keys.select{|tab_key| tab_key.present?}.each do |tab_key|
29
29
  elements += content_tag :li, link_to(tab_key, "#tabs-#{@index}-#{@tab_index}")
30
30
  @tab_index += 1
@@ -46,9 +46,17 @@ class RailsInfo::Logs::Server::ActionPresenter < ::RailsInfo::Presenter
46
46
 
47
47
  def tab(tab_key)
48
48
  @content = @tabs_data[tab_key]
49
-
49
+
50
50
  content_tag :div, class: 'tabs', id: "tabs-#{@index}-#{@tab_index}" do
51
- raw @content.is_a?(Hash) ? sub_tabs : sub_content_tab
51
+ html = if tab_key == 'Request'
52
+ raw render partial: 'rails_info/logs/server/request', locals: { content: @content }
53
+ else
54
+ raw @content.is_a?(Hash) ? sub_tabs : sub_content_tab
55
+ end
56
+
57
+ @tab_index += 1
58
+
59
+ html
52
60
  end
53
61
  end
54
62
 
@@ -65,12 +73,11 @@ class RailsInfo::Logs::Server::ActionPresenter < ::RailsInfo::Presenter
65
73
  def sub_content_tab
66
74
  content_tag :div, style: 'max-height:400px; width:100%; overflow: auto' do
67
75
  if @content.is_a?(Array)
68
- @content.map!{|c| CGI.escapeHTML(c) }.join('<br/><br/>')
76
+ @content.map!{|c| CGI.escapeHTML(c) }
77
+ @content = @content.join('<br/><br/>')
69
78
  else
70
79
  @content = CGI.escapeHTML(@content)
71
80
  end
72
-
73
- @tab_index += 1
74
81
 
75
82
  raw @content
76
83
  end
@@ -99,7 +106,7 @@ class RailsInfo::Logs::Server::ActionPresenter < ::RailsInfo::Presenter
99
106
 
100
107
  html += content_tag :div, class: 'tabs', id: "tabs-#{@index}-#{@tab_index}-#{sub_tab_index}" do
101
108
  sub_tab_index += 1
102
- @tab_index += 1
109
+
103
110
  raw render partial: 'rails_info/logs/server/table', locals: { sub_content: sub_content }
104
111
  end
105
112
  end
@@ -7,7 +7,7 @@ class RailsInfo::Logs::ServerPresenter < ::RailsInfo::Presenter
7
7
 
8
8
  def accordion
9
9
  @action_index = 0
10
-
10
+
11
11
  content_tag :div, id: 'actions', class: 'accordions' do
12
12
  html = ''
13
13
 
@@ -25,8 +25,7 @@ class RailsInfo::Logs::ServerPresenter < ::RailsInfo::Presenter
25
25
 
26
26
  def write_tabs
27
27
  content_tag :div, class: 'tabs', id: 'writes' do
28
- write_navigation
29
- write_body
28
+ raw(write_navigation) + raw(write_body)
30
29
  end
31
30
  end
32
31
 
@@ -34,24 +33,31 @@ class RailsInfo::Logs::ServerPresenter < ::RailsInfo::Presenter
34
33
  tab_index = 0
35
34
 
36
35
  content_tag :ul do
36
+ elements = ''
37
+
37
38
  @rails_info_log.writes.each do |table_name,data|
38
- li = content_tag :li, link_to(table_name, "writes-#{tab_index}")
39
+ elements += content_tag :li, link_to(table_name, "#writes-#{tab_index}")
39
40
 
40
41
  tab_index += 1
41
-
42
- li
43
42
  end
43
+
44
+ raw elements
44
45
  end
45
46
  end
46
47
 
47
48
  def write_body
48
49
  tab_index = 0
49
50
 
51
+ html = ''
52
+
50
53
  @rails_info_log.writes.each do |table_name,data|
51
- content_tag :div, class: 'tabs', id: "writes-#{tab_index}" do
52
- tab_index += 1
53
- render partial: 'table', locals: { sub_content: data }
54
+ html += content_tag :div, id: "writes-#{tab_index}" do
55
+ raw render partial: 'rails_info/logs/server/table', locals: { sub_content: data }
54
56
  end
57
+
58
+ tab_index += 1
55
59
  end
60
+
61
+ html
56
62
  end
57
63
  end
@@ -8,7 +8,7 @@ class RailsInfo::Logs::Test::RspecPresenter < ::RailsInfo::Presenter
8
8
  end
9
9
 
10
10
  def summary
11
- text = ["#{@rails_info_log.hash.keys.length} files"]
11
+ text = ["#{@rails_info_log.number_of_files} files"]
12
12
  text << @rails_info_log.summary unless @rails_info_log.summary.blank?
13
13
 
14
14
  content_tag :p, text.join(', ')
@@ -17,19 +17,23 @@ class RailsInfo::Logs::Test::RspecPresenter < ::RailsInfo::Presenter
17
17
  def accordion
18
18
  @index = 0
19
19
 
20
- content_tag :div, id: 'files', class: 'accordions' do
21
- html = ''
20
+ if @rails_info_log.hash.is_a?(Hash)
21
+ content_tag :div, id: 'files', class: 'accordions' do
22
+ html = ''
22
23
 
23
- @rails_info_log.hash.each do |file, examples|
24
- file_presenter = ::RailsInfo::Logs::Test::Rspec::FilePresenter.new(
25
- @subject, name: "#{file} (#{examples.length})",
26
- tabs_data: examples, index: @index, rails_root: @rails_info_log.rails_root
27
- )
28
- @index += 1
29
- html += raw file_presenter.tabs
24
+ @rails_info_log.hash.each do |file, examples|
25
+ file_presenter = ::RailsInfo::Logs::Test::Rspec::FilePresenter.new(
26
+ @subject, name: "#{file} (#{examples.length})",
27
+ tabs_data: examples, index: @index, rails_root: @rails_info_log.rails_root
28
+ )
29
+ @index += 1
30
+ html += raw file_presenter.tabs
31
+ end
32
+
33
+ raw html
30
34
  end
31
-
32
- raw html
33
- end
35
+ else
36
+ content_tag :pre, @rails_info_log.hash.join("\n")
37
+ end
34
38
  end
35
39
  end
@@ -2,6 +2,8 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Rails Info</title>
5
+ <meta charset='utf-8'>
6
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
7
  <%= stylesheet_link_tag rails_info_stylesheet, media: 'all' %>
6
8
  <%= javascript_include_tag 'rails_info/application' %>
7
9
  <%= csrf_meta_tags %>
@@ -0,0 +1,18 @@
1
+ <div>
2
+ <div>
3
+ <strong>Route:</strong> <%= content['Route']%> |
4
+ <strong>Format:</strong> <%= content['Format']%>
5
+ </div>
6
+ <% if content['Parameters'].present? %>
7
+ <hr/>
8
+ <fieldset>
9
+ <legend><strong>Parameters</strong>
10
+ <div>
11
+ <%= render partial: 'rails_info/logs/server/table', locals: {
12
+ sub_content: { 'columns' => content['Parameters'].keys, 'rows' => [content['Parameters']] }
13
+ }
14
+ %>
15
+ </div>
16
+ </fieldset>
17
+ <% end %>
18
+ </div>
@@ -1,7 +1,9 @@
1
1
  <div style="max-height:400px; width:100%; overflow: auto">
2
- <table>
2
+ <table class="table table-striped">
3
3
  <thead>
4
- <th><%= raw sub_content['columns'].uniq.join('</th><th>') %></th>
4
+ <tr>
5
+ <th><%= raw sub_content['columns'].uniq.join('</th><th>') %></th>
6
+ </tr>
5
7
  </thead>
6
8
  <tbody>
7
9
  <% sub_content['rows'].each do |row| %>
@@ -1,8 +1,3 @@
1
- <style type="text/css">
2
- .ui-widget {
3
- font-size: xx-small;
4
- }
5
- </style>
6
1
  <% form_tag rails_info_server_log_path do %>
7
2
  <%= check_box_tag 'debug' %> debug?
8
3
  <p>
@@ -15,5 +10,15 @@
15
10
  <%= submit_tag 'submit' %>
16
11
  </p>
17
12
  <% end %>
13
+ <ul class="nav nav-tabs nav-stacked">
14
+ <li><a name="top" href="#">1 ) Actions</a></li>
15
+ <li><a href="#writes">2 ) Writes</a></li>
16
+ </ul>
17
+ <hr/>
18
+ <h3><a href="#top">1 ) Actions</a></h3>
19
+ <hr/>
18
20
  <%= raw @rails_info_log.accordion %>
21
+ <hr/>
22
+ <h3><a name="writes" href="#top">2 ) Writes</a></h3>
23
+ <hr/>
19
24
  <%= raw @rails_info_log.write_tabs %>
@@ -2,7 +2,7 @@
2
2
  <p>
3
3
  <%= check_box_tag 'debug' %> debug? &nbsp;&nbsp;
4
4
  <%= label_tag 'log[rails_root]', raw('<strong>Rails root:</strong>') %>
5
- <%= text_field_tag 'log[rails_root]', (params['log']['rails_root'] rescue "#{Rails.root}/"), size: 50 %> &nbsp;&nbsp;
5
+ <%= text_field_tag 'log[rails_root]', (params['log']['rails_root'] rescue "#{Rails.root}/"), size: 75 %> &nbsp;&nbsp;
6
6
  <%= submit_tag 'submit' %>
7
7
  </p>
8
8
  <% end %>
@@ -7,6 +7,7 @@ class RailsInfo::Logs::Server
7
7
  path = options[:log][:path] || "#{Rails.root}/log/"
8
8
  env = options[:log][:env] || Rails.env
9
9
  @body = options[:log][:body]
10
+ @start_after_last_shutdown = options[:log][:start_after_last_shutdown] || true
10
11
 
11
12
  unless @body
12
13
  file_path = "#{path}#{env}.log"
@@ -31,114 +32,67 @@ class RailsInfo::Logs::Server
31
32
  private
32
33
 
33
34
  def process
34
- @start_after_last_shutdown = true
35
- @body = @body.split("\n").map(&:strip)
35
+ @body = @body.split("\n").map{|l| l.gsub(/\e/, '')}.map(&:strip)
36
36
 
37
37
  reset_log
38
-
39
- group_by_action = false
40
-
41
- @body.each do |line|
42
- if line.match('Processing') && line.match('#') && line.match(/\[/) && line.match(/\]/)
43
- # rails 2
44
- group_by_action = true
45
- elsif line.match('Started') && line.match(' for ') && line.match(' at ') && line.split(' ').length == 9
46
- # rails 3
47
- group_by_action = true
48
- elsif line.match('Processing by') && line.match('#') && line.match(' as ') && line.split(' ').length == 5
49
- # rails 3
50
- group_by_action = true
51
- end
52
- end
53
-
54
- unless group_by_action
55
- @action = 'no_action_grouping'
56
- @log[@action] ||= { 'Parameters' => '', 'WRITE' => {}, 'READ' => [], 'views' => [], 'misc' => [], 'errors' => []}
57
- end
38
+ group_by_action?
58
39
 
59
40
  @body.each do |line|
60
41
  process_line(line)
42
+ @last_action = @action
61
43
  end
62
44
 
63
- @log.each do |action,tabs|
64
- tabs.each do |tab,content|
65
- @log[action].delete(tab) if @log[action][tab].blank?
66
- end
67
- end
68
-
69
- @log.each do |action,tabs|
70
- tabs.each do |tab,content|
71
- next unless tab == 'WRITE'
72
-
73
- # define WHERE column as last one
74
- content.each do |table_name,data|
75
- @log[action][tab][table_name]['columns'] << 'WHERE'
76
- end
45
+ delete_empty_tabs
46
+ set_where_column_as_last_one_in_write_tab
47
+ end
48
+
49
+ def reset_log
50
+ @log, @action_indexes, @route, @action, @format, @last_action = {}, {}, '', '', '', ''
51
+ end
52
+
53
+ def group_by_action?
54
+ group_by_action = false
77
55
 
56
+ @body.each do |line|
57
+ if line.match('Processing by') && line.match('#') && line.match(' as ') && line.split(' ').length == 5
58
+ # rails 3
59
+ group_by_action = true
60
+ #elsif line.match('Processing') && line.match('#') && line.match(/\[/) && line.match(/\]/)
61
+ # rails 2
62
+ # group_by_action = true
63
+ #elsif line.match('Started') && line.match(' for ') && line.match(' at ') && line.split(' ').length == 9
64
+ # rails 3
65
+ # group_by_action = true
78
66
  break
79
67
  end
80
68
  end
81
69
 
82
- @writes.each do |table_name,data|
83
- @writes[table_name]['columns'] << 'WHERE'
70
+ unless group_by_action
71
+ @action = 'no_action_grouping'
72
+ @log[@action] ||= { 'Request' => {}, 'WRITE' => {}, 'READ' => [], 'views' => [], 'misc' => [], 'errors' => []}
84
73
  end
85
74
  end
86
75
 
87
- def reset_log
88
- @log, @action_indexes, @action, @last_action = {}, {}, "", ""
89
- end
90
-
91
76
  # TODO: process test.log which don't have action grouping, too
92
77
  # TODO: look if newrelic & Co. already does that but are only doing it for the last action
93
78
  # TODO: parse stack traces by grouping the lines by file and than method, generate a pseudo web sequence diagram code for files as participants and their methods
94
79
  # TODO: integrate a code snippet for each line of the stack trace like brakeman & co. do
95
80
  # TODO: extend rails stack trace output by code snippets
96
81
  def process_line(line)
97
- if line.match('Ctrl-C to shutdown server') && @start_after_last_shutdown
98
- reset_log
99
- elsif line.match('Processing') && line.match('#') && line.match(/\[/) && line.match(/\]/)
100
- # rails 2 start of action
101
- # Processing Clickworker::DashboardsController#show (for 127.0.0.1 at 2011-08-26 12:22:58) [GET]
102
- @action = line.split(' ')[1]
103
-
104
- init_log_action
105
- #elsif line.match('Started') && line.match(' for ') && line.match(' at ') && line.split(' ').length == 9
106
- # rails 3 start of action
107
- # Started GET "/orders/815?truncate_length=1000" for 127.0.0.1 at 2011-10-04 19:58:44 +0200
108
- elsif line.match('Processing by') && line.match('#') && line.match(' as ') && line.split(' ').length == 5
109
- # rails 3 start of action
110
- # Processing by OrdersController#show as HTML
111
- @action = line.split(' ')[2]
112
-
113
- init_log_action
114
- elsif @action.blank?
115
- elsif line.match('Parameters:') && line.match('{') && line.match('}')
116
- line = line.split(' ')
117
- line.pop
118
- @log[@action]['Parameters'] = line.join(' ').strip
119
- elsif line.match('INSERT INTO') || line.match('UPDATE')
120
- table_name = table_name_from_line(line)
121
-
122
- data = line.match('INSERT INTO') ? process_insert(line) : process_update(table_name, line)
123
-
124
- # TaskTemplate Create (0.2ms) INSERT INTO `task_templates` (`slug`, `name`, `created_at`, `product_id`, `updated_at`, `customer_id`, `state`) VALUES('the code', 'a customer name', '2011-08-26 10:22:54', 2, '2011-08-26 10:22:54', 1002, 'draft')
125
- #
126
- # InputDataItem Update (0.3ms) UPDATE `data_items` SET `input` = '<opt>\n <input>\n <__dynamic_form__>\n <df_create>\n <the_input></the_input>\n <the_output>Output field 1</the_output>\n </df_create>\n </__dynamic_form__>\n </input>\n</opt>\n', `updated_at` = '2011-08-26 10:22:55' WHERE `id` = 5485
127
-
128
-
129
- @log[@action]['WRITE'][table_name] ||= { 'columns' => ['id'], 'rows' => [] }
130
- @writes[table_name] ||= { 'columns' => ['id'], 'rows' => [] }
131
-
132
- @log[@action]['WRITE'][table_name]['columns'] = @log[@action]['WRITE'][table_name]['columns'].concat(data.keys).uniq
133
- @writes[table_name]['columns'] = @writes[table_name]['columns'].concat(data.keys).uniq
134
- @log[@action]['WRITE'][table_name]['rows'] << data
135
- @writes[table_name]['rows'] << data
136
- elsif (line.match('Load') && line.match('SELECT')) || (line.match('CACHE') && line.match('\(') && line.match('ms\)'))
137
- line = line.split(')')
138
- line.shift
139
- @log[@action]['READ'] ||= []
140
- @log[@action]['READ'] << line.join(')').strip
141
- elsif line.match('Rendered') && line.match('\(') && line.match('ms\)')
82
+ return if line.blank?
83
+
84
+ reset_log and return if line.match('Ctrl-C to shutdown server') && @start_after_last_shutdown
85
+
86
+ parse_route(line) and return
87
+ parse_action(line) and return
88
+
89
+ return if @action.blank?
90
+
91
+ parse_request(line) and return
92
+ parse_read(line) and return
93
+ parse_write(line) and return
94
+
95
+ if line.match('Rendered') && line.match('\(') && line.match('ms\)')
142
96
  @log[@action]['Views'] ||= []
143
97
  line = line.split('Rendered')
144
98
  line.shift
@@ -154,21 +108,123 @@ class RailsInfo::Logs::Server
154
108
  else
155
109
  @log[@action]['misc'] << line
156
110
  end
157
-
158
- @last_action = @action
159
111
  end
160
112
 
161
- def table_name_from_line(line)
162
- line = line.split(')')
163
- line.shift
164
- line = line.join(')')
113
+ def delete_empty_tabs
114
+ @log.each do |action,tabs|
115
+ tabs.each do |tab,content|
116
+ @log[action].delete(tab) if @log[action][tab].blank?
117
+ end
118
+ end
119
+ end
120
+
121
+ def set_where_column_as_last_one_in_write_tab
122
+ @log.select{|a,t| t['WRITE'].is_a?(Hash) }.each do |action,tabs|
123
+ tabs['WRITE'].each do |table_name,data|
124
+ @log[action]['WRITE'][table_name]['columns'] << 'WHERE'
125
+ end
126
+ end
127
+
128
+ @writes.each {|table_name,data| @writes[table_name]['columns'] << 'WHERE' }
129
+ end
130
+
131
+ def parse_route(line)
132
+ reg_exp = /^Started(.{1,})for/
133
+
134
+ return false unless line.match(reg_exp)
135
+
136
+ @route = line.match(reg_exp)[1].strip
137
+
138
+ true
139
+ end
140
+
141
+ def parse_action(line)
142
+ reg_exp = /^Processing by {1}(.{1,}) {1}as {1}(.{1,})$/
143
+
144
+ return false unless line.match(reg_exp)
145
+
146
+ @action = line.match(reg_exp)[1].strip
147
+ @format = line.match(reg_exp)[2].strip
148
+
149
+ init_log_action unless @action.blank?
150
+
151
+ true
152
+ end
153
+
154
+ def parse_request(line)
155
+ reg_exp = /^Parameters:( ){1}(\{(.)+\}$)/
156
+
157
+ if line.match(reg_exp)
158
+ @log[@action]['Request']['Parameters'] = eval(line.match(reg_exp)[2]) rescue line
159
+
160
+ true
161
+ else
162
+ false
163
+ end
164
+ end
165
+
166
+ def parse_read(line)
167
+ reg_exp_begin = '\[([0-9]+)m( {2}|)(SELECT.+)'
168
+
169
+ #[1mCommunity Load (0.5ms) SELECT `communities`.* FROM `communities` WHERE `communities`.`id` = 2 LIMIT 1
170
+ reg_exp1 = "#{reg_exp_begin}(\\[)"
171
+
172
+ #[1mCACHE (0.0ms) SELECT `communities`.* FROM `communities` WHERE `communities`.`deleted` = 0 AND `communities`.`slug` = 'bronze' LIMIT 1
173
+ reg_exp2 = "#{reg_exp_begin}$"
174
+
175
+ reg_exp = if line.match(reg_exp1)
176
+ reg_exp1
177
+ elsif line.match(reg_exp2)
178
+ reg_exp2
179
+ else
180
+ nil
181
+ end
182
+
183
+ return false unless reg_exp
184
+
185
+ @log[@action]['READ'] ||= []
186
+ @log[@action]['READ'] << line.match(reg_exp)[3].strip
187
+
188
+ true
189
+ end
190
+
191
+ def parse_write(line)
192
+ reg_exp = /([0-9]+)m( ){2}((INSERT INTO|UPDATE|DELETE FROM)(.)+)$/
193
+
194
+ return false unless line.match(reg_exp)
195
+
196
+ table_name = line.match(/(INSERT INTO|UPDATE|DELETE FROM) {1}`([a-zA-Z0-9_]+)`/)[2]
197
+
198
+ data = {}
199
+
200
+ if line.match(/([0-9]+)m( ){2}INSERT INTO( ){1}`(.{1,})`( ){1}(.)+$/)
201
+ data = process_insert(line)
202
+ elsif line.match(/([0-9]+)m( ){2}UPDATE( ){1}`(.{1,})`( ){1}(.)+$/)
203
+ data = process_update(table_name, line)
204
+ elsif line.match(/([0-9]+)m( ){2}DELETE FROM( ){1}`(.{1,})`( ){1}(.)+$/)
205
+ data = process_delete(table_name, line)
206
+ else
207
+ raise NotImplementedError
208
+ end
209
+
210
+ # TaskTemplate Create (0.2ms) INSERT INTO `task_templates` (`slug`, `name`, `created_at`, `product_id`, `updated_at`, `customer_id`, `state`) VALUES('the code', 'a customer name', '2011-08-26 10:22:54', 2, '2011-08-26 10:22:54', 1002, 'draft')
211
+ #
212
+ # InputDataItem Update (0.3ms) UPDATE `data_items` SET `input` = '<opt>\n <input>\n <__dynamic_form__>\n <df_create>\n <the_input></the_input>\n <the_output>Output field 1</the_output>\n </df_create>\n </__dynamic_form__>\n </input>\n</opt>\n', `updated_at` = '2011-08-26 10:22:55' WHERE `id` = 5485
213
+
165
214
 
166
- line = line.split('`')
167
- line[1]
215
+ @log[@action]['WRITE'][table_name] ||= { 'columns' => ['-action-', 'id'], 'rows' => [] }
216
+ @writes[table_name] ||= { 'columns' => ['-action-', 'id'], 'rows' => [] }
217
+
218
+ @log[@action]['WRITE'][table_name]['columns'] = @log[@action]['WRITE'][table_name]['columns'].concat(data.keys).uniq
219
+ @writes[table_name]['columns'] = @writes[table_name]['columns'].concat(data.keys).uniq
220
+ @log[@action]['WRITE'][table_name]['rows'] << data
221
+ @writes[table_name]['rows'] << data
222
+
223
+ true
168
224
  end
169
225
 
170
226
  def process_insert(line)
171
- data = {}
227
+ data = {'-action-' => 'INSERT'}
172
228
 
173
229
  columns = line.match(/\(`(.)+\)(( |)VALUES)/)[0].split('VALUES').first.strip.gsub('`', '')[1..-2].split(',').map(&:strip)
174
230
 
@@ -191,18 +247,17 @@ class RailsInfo::Logs::Server
191
247
  end
192
248
 
193
249
  def process_update(table_name, line)
194
- data = {}
250
+ data = {'-action-' => 'UPDATE'}
251
+
252
+ # "`editable` = 0, `updated_at` = '2012-07-09 16:33:31'"
253
+ data_string = line.match(/SET (.+) WHERE/)[1].strip
254
+ conditions = line.match(/WHERE(.+)$/)[1].strip
255
+
256
+ data_string = data_string.gsub(/(', `|, `)/, "||||").gsub(/(` = '|` = )/, "=").gsub(/(`|')/, '').split('||||')
195
257
 
196
- # SET `input` = '<opt>\n <input>\n <__dynamic_form__>\n <df_create>\n <the_input></the_input>\n <the_output>Output field 1</the_output>\n </df_create>\n </__dynamic_form__>\n </input>\n</opt>\n', `updated_at` = '2011-08-26 10:22:55' WHERE `id` = 5485
197
- line = line.split('WHERE')
198
- data_string = line.first
199
- conditions = line.last
200
- data_string = data_string.split(' '); data_string.shift; data_string = data_string.join(' ')
201
- data_string = data_string.gsub("', `", "||||").gsub(", `", '||||').gsub("` = '", "=").split('||||')
202
-
203
258
  data_string.each do |data_element|
204
259
  data_element = data_element.split('=')
205
- data[data_element.shift.gsub('`', '').strip] = data_element.join('=')
260
+ data[data_element.shift.strip] = data_element.join('=')
206
261
  end
207
262
 
208
263
  if conditions.match("`#{table_name}`.`id` = ([0-9]+)")
@@ -216,6 +271,23 @@ class RailsInfo::Logs::Server
216
271
  data
217
272
  end
218
273
 
274
+ def process_delete(table_name, line)
275
+ data = {'-action-' => 'DELETE'}
276
+
277
+ # ... WHERE `id` = 5485
278
+ conditions = line.split('WHERE').last
279
+
280
+ if conditions.match("`#{table_name}`.`id` = ([0-9]+)")
281
+ data['id'] = conditions.match("`#{table_name}`.`id` = ([0-9]+)")[0].split('=').last.strip
282
+ elsif conditions.match(/`id` = ([0-9]+)/)
283
+ data['id'] = conditions.match(/`id` = ([0-9]+)/)[0].split('=').last.strip
284
+ end
285
+
286
+ data['WHERE'] = conditions
287
+
288
+ data
289
+ end
290
+
219
291
  def init_log_action
220
292
  if @action_indexes.has_key?(@action)
221
293
  @action_indexes[@action] = @action_indexes[@action] + 1
@@ -225,6 +297,6 @@ class RailsInfo::Logs::Server
225
297
 
226
298
  @action = "#{@action} ##{@action_indexes[@action]}"
227
299
 
228
- @log[@action] ||= { 'Parameters' => '', 'WRITE' => {}, 'READ' => [], 'views' => [], 'misc' => [], 'errors' => []}
300
+ @log[@action] ||= { 'Request' => {'Route' => @route, 'Format' => @format}, 'WRITE' => {}, 'READ' => [], 'views' => [], 'misc' => [], 'errors' => []}
229
301
  end
230
302
  end
@@ -26,7 +26,11 @@ class RailsInfo::Logs::Test::Rspec
26
26
  end
27
27
 
28
28
  def hash
29
- @log
29
+ @log.keys.any? ? @log : (@body || [''])
30
+ end
31
+
32
+ def number_of_files
33
+ hash.is_a?(Hash) ? hash.keys.length : 0
30
34
  end
31
35
 
32
36
  def rails_root
@@ -97,6 +101,9 @@ class RailsInfo::Logs::Test::Rspec
97
101
  stack_trace << line
98
102
  end
99
103
  end
104
+
105
+ # free memory if log could be read otherwise keep text in memory to show instead
106
+ @body = nil if @log.keys.any?
100
107
  end
101
108
 
102
109
  def add_entry(example, failure_code, exception_class, exception_message, stack_trace, after_stack_trace_entry = nil)
@@ -131,9 +138,10 @@ class RailsInfo::Logs::Test::Rspec
131
138
  end
132
139
 
133
140
  if @log[file_name].has_key?(example)
134
- raise NotImplementedError.new(
135
- "RSpec file #{file_name} not expected to have more than 1 example named #{example.inspect}"
136
- )
141
+ # TODO: increment example tab count in this case
142
+ #raise NotImplementedError.new(
143
+ # "RSpec file #{file_name} not expected to have more than 1 example named #{example.inspect}"
144
+ #)
137
145
  end
138
146
 
139
147
  @log[file_name][example] = {
@@ -1,3 +1,3 @@
1
1
  module RailsInfo
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -7,8 +7,8 @@ require 'rails_info/logs'
7
7
  require 'rails_info/logs/server'
8
8
 
9
9
  describe RailsInfo::Logs::Server do
10
- before do
11
- body = "Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
10
+ =begin
11
+ Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
12
12
  Creating scope :visible. Overwriting existing method Reaction.visible.
13
13
  Processing by DeviseCustomized::RegistrationsController#create as HTML
14
14
  Parameters: {\"utf8\"=>'', \"authenticity_token\"=>\"k4xMIcuqMThMsdlbsVJ7GFgzNDw/HgGGp1ldElFULoY=\", \"user\"=>{\"screen_name\"=>\"mgawlista\", \"email\"=>\"gawlista@googlemail.com\", \"password\"=>\"[FILTERED]\", \"password_confirmation\"=>\"[FILTERED]\"}, \"community_id\"=>\"bronze\"}
@@ -20,31 +20,139 @@ Rendered devise/shared/_header.html.erb (70.4ms)
20
20
  Community Load (0.5ms) SELECT `communities`.* FROM `communities` WHERE `communities`.`id` = 2 LIMIT 1
21
21
  Redirected to http://localhost:3000/bronze
22
22
  SOLR Request (45541.1ms) [ path=#<RSolr::Client:0x007fbf26dc8b28> parameters={data: <?xml version=\"1.0\" encoding=\"UTF-8\"?><commit/>, headers: {\"Content-Type\"=>\"text/xml\"}, method: post, params: {:wt=>:ruby}, query: wt=ruby, path: update, uri: http://localhost:8982/solr/update?wt=ruby} ]
23
- Completed 302 Found in 125493ms"
24
- end
25
-
23
+ Completed 302 Found in 125493ms
24
+ =end
26
25
  describe '#process' do
27
- context 'just read' do
28
- it 'principally works' do
29
- body = "Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
26
+ describe '#parse_request' do
27
+ subject {
28
+ ::RailsInfo::Logs::Server.new(
29
+ log: {
30
+ body: "Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
30
31
  Processing by DeviseCustomized::RegistrationsController#create as HTML
32
+ Parameters: {\"authenticity_token\"=>\"k4xMIcuqMThMsdlbsVJ7GFgzNDw/HgGGp1ldElFULoY=\", \"user\"=>{\"screen_name\"=>\"mgawlista\"}}
33
+  "
34
+ }
35
+ )
36
+ }
37
+
38
+ it 'parses request correctly' do
39
+ subject.hash.should == {
40
+ 'DeviseCustomized::RegistrationsController#create #1' => {
41
+ 'Request' => {
42
+ 'Route' => "POST \"/users/bronze\"",
43
+ 'Format' => 'HTML',
44
+ 'Parameters' => {"authenticity_token"=>"k4xMIcuqMThMsdlbsVJ7GFgzNDw/HgGGp1ldElFULoY=", "user"=>{"screen_name"=>"mgawlista"}},
45
+ }
46
+ }
47
+ }
48
+ end
49
+ end
50
+
51
+ describe '#parse_read' do
52
+ context 'line ending LIMIT 1' do
53
+ subject {
54
+ ::RailsInfo::Logs::Server.new(
55
+ log: {
56
+ body: "Processing by DeviseCustomized::RegistrationsController#create as HTML
31
57
  [1mCACHE (0.0ms) SELECT `communities`.* FROM `communities` WHERE `communities`.`deleted` = 0 AND `communities`.`slug` = 'bronze' LIMIT 1
32
- "
33
- @rails_info_log = ::RailsInfo::Logs::Server.new(log: { body: body })
34
-
35
- raise @rails_info_log.hash.inspect
58
+ "
59
+ }
60
+ )
61
+ }
36
62
 
37
- @rails_info_log.hash.should == {
38
- 'DeviseCustomized::RegistrationsController#create #1' => {
39
- 'READ' => [
40
- "SELECT `communities`.* FROM `communities` WHERE `communities`.`deleted` = 0 AND `communities`.`slug` = 'bronze' LIMIT 1'",
41
- ],
42
- 'misc' => [
43
- 'Processing by DeviseCustomized::RegistrationsController#create as HTML'
44
- ]
63
+ it 'will be parsed correctly' do
64
+ subject.hash.should == {
65
+ 'DeviseCustomized::RegistrationsController#create #1' => {
66
+ 'Request' => { 'Route' => '', 'Format' => 'HTML' },
67
+ 'READ' => [
68
+ "SELECT `communities`.* FROM `communities` WHERE `communities`.`deleted` = 0 AND `communities`.`slug` = 'bronze' LIMIT 1",
69
+ ]
70
+ }
45
71
  }
72
+ end
73
+ end
74
+
75
+ context 'line ending LIMIT 1[.' do
76
+ subject {
77
+ ::RailsInfo::Logs::Server.new(
78
+ log: {
79
+ body: "Processing by DeviseCustomized::RegistrationsController#create as HTML
80
+ [1mCommunity Load (0.5ms) SELECT `communities`.* FROM `communities` WHERE `communities`.`id` = 2 LIMIT 1
81
+ "
82
+ }
83
+ )
46
84
  }
85
+
86
+ it 'will be parsed correctly' do
87
+ subject.hash.should == {
88
+ 'DeviseCustomized::RegistrationsController#create #1' => {
89
+ 'Request' => { 'Route' => '', 'Format' => 'HTML' },
90
+ 'READ' => [
91
+ "SELECT `communities`.* FROM `communities` WHERE `communities`.`id` = 2 LIMIT 1",
92
+ ]
93
+ }
94
+ }
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#process_insert' do
100
+ subject {
101
+ ::RailsInfo::Logs::Server.new(
102
+ log: {
103
+ body: "Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
104
+ Processing by DeviseCustomized::RegistrationsController#create as HTML
105
+ [1mSQL (276.4ms) INSERT INTO `users` (`city`, `city_permissions`, `confirmation_sent_at`, `confirmation_token`, `confirmed_at`, `created_at`, `current_sign_in_at`, `current_sign_in_ip`, `delete_token`, `deleted`, `developer`, `email`, `encrypted_password`, `facebook`, `facebook_id`, `facebook_permissions`, `failed_attempts`, `forename`, `google_id`, `initial_community_id`, `last_sign_in_at`, `last_sign_in_ip`, `linkedin`, `linkedin_permissions`, `locked_at`, `master`, `name_permissions`, `notification_email`, `password_salt`, `phone`, `phone_permissions`, `photo_content_type`, `photo_file_name`, `photo_file_size`, `photo_updated_at`, `remember_created_at`, `reset_password_sent_at`, `reset_password_token`, `screen_name`, `screen_name_permissions`, `sign_in_count`, `slug`, `street`, `street_permissions`, `surname`, `tagline`, `tagline_permissions`, `twitter`, `twitter_permissions`, `unconfirmed_email`, `unlock_token`, `updated_at`, `url`, `website`, `website_permissions`, `xing`, `xing_permissions`, `zipcode`, `zipcode_permissions`) VALUES (NULL, 0, '2012-07-05 17:33:50', 'xVQj9z8xGm1bzqqJBjUn', NULL, '2012-07-05 17:33:50', NULL, NULL, NULL, 0, NULL, 'gawlista@googlemail.com', '$2a$10$KnrBV6m64g0zqKwUnQRR/exiUN9HtzJCGLSUse.jPTxLp0WQtNec2', NULL, NULL, 0, 0, NULL, NULL, 2, NULL, NULL, NULL, 0, NULL, 0, 0, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'mgawlista', 0, 0, 'mgawlista', NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL, '2012-07-05 17:33:50', NULL, NULL, 0, NULL, 0, NULL, 0)
106
+ "
107
+ }
108
+ )
109
+ }
110
+
111
+ it 'parses INSERT entries correctly' do
112
+ action = 'DeviseCustomized::RegistrationsController#create #1'
113
+ subject.hash[action]['Request'].should == { 'Route' => "POST \"/users/bronze\"", 'Format' => 'HTML' }
114
+
115
+ compare_data(
116
+ subject.hash[action]['WRITE']['users'],
117
+ { '-action-' => 'INSERT', 'id' => nil, 'city' => 'NULL', 'WHERE' => nil }
118
+ )
119
+ end
120
+ end
121
+
122
+ describe '#process_update' do
123
+ subject {
124
+ ::RailsInfo::Logs::Server.new(
125
+ log: {
126
+ body: "Started POST \"/users/bronze\" for 127.0.0.1 at 2012-07-05 19:33:44 +0200
127
+ Processing by DeviseCustomized::RegistrationsController#create as HTML
128
+ [1m (0.4ms) UPDATE `feedbacks` SET `editable` = 0, `updated_at` = '2012-07-09 16:33:31' WHERE `feedbacks`.`type` IN ('Question') AND `feedbacks`.`id` = 3
129
+ "
130
+ }
131
+ )
132
+ }
133
+
134
+ it 'parses UPDATE entries correctly' do
135
+ action = 'DeviseCustomized::RegistrationsController#create #1'
136
+ subject.hash[action]['Request'].should == { 'Route' => "POST \"/users/bronze\"", 'Format' => 'HTML' }
137
+
138
+ compare_data(
139
+ subject.hash[action]['WRITE']['feedbacks'],
140
+ {
141
+ '-action-' => 'UPDATE', 'id' => '3', 'editable' => '0', 'updated_at' => '2012-07-09 16:33:31',
142
+ 'WHERE' => "`feedbacks`.`type` IN ('Question') AND `feedbacks`.`id` = 3"
143
+ }
144
+ )
47
145
  end
48
146
  end
49
147
  end
50
148
  end
149
+
150
+ def compare_data(table, data)
151
+ data.keys.each_index do |current_index|
152
+ index = data.keys[current_index] == 'WHERE' ? table['columns'].length - 1 : current_index
153
+ column = data.keys[current_index]
154
+ table['columns'][index].should == column
155
+
156
+ table['rows'].first[column].should == data[column] unless data[column] == nil
157
+ end
158
+ end
@@ -3,6 +3,10 @@ unless defined? Rails
3
3
  def self.root
4
4
  File.expand_path('dummy', __FILE__)
5
5
  end
6
+
7
+ def self.env
8
+ 'test'
9
+ end
6
10
  end
7
11
  end
8
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_info
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-06 00:00:00.000000000 Z
12
+ date: 2012-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70253477230800 !ruby/object:Gem::Requirement
16
+ requirement: &70242337984640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70253477230800
24
+ version_requirements: *70242337984640
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: coffee-script
27
- requirement: &70253477230000 !ruby/object:Gem::Requirement
27
+ requirement: &70242337983580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70253477230000
35
+ version_requirements: *70242337983580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: uglifier
38
- requirement: &70253477228920 !ruby/object:Gem::Requirement
38
+ requirement: &70242337982560 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70253477228920
46
+ version_requirements: *70242337982560
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jquery-rails
49
- requirement: &70253477228160 !ruby/object:Gem::Requirement
49
+ requirement: &70242337981960 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70253477228160
57
+ version_requirements: *70242337981960
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jquery-ui-rails
60
- requirement: &70253477227440 !ruby/object:Gem::Requirement
60
+ requirement: &70242337981320 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70253477227440
68
+ version_requirements: *70242337981320
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pygments.rb
71
- requirement: &70253477226720 !ruby/object:Gem::Requirement
71
+ requirement: &70242337980500 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70253477226720
79
+ version_requirements: *70242337980500
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: twitter-bootstrap-rails
82
- requirement: &70253477226040 !ruby/object:Gem::Requirement
82
+ requirement: &70242337979860 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70253477226040
90
+ version_requirements: *70242337979860
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: simple-navigation-bootstrap
93
- requirement: &70253477225320 !ruby/object:Gem::Requirement
93
+ requirement: &70242337979280 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *70253477225320
101
+ version_requirements: *70242337979280
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: awesome_print
104
- requirement: &70253477224820 !ruby/object:Gem::Requirement
104
+ requirement: &70242337978780 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70253477224820
112
+ version_requirements: *70242337978780
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rspec-rails
115
- requirement: &70253477224320 !ruby/object:Gem::Requirement
115
+ requirement: &70242337978360 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70253477224320
123
+ version_requirements: *70242337978360
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: mysql2
126
- requirement: &70253477223880 !ruby/object:Gem::Requirement
126
+ requirement: &70242337977840 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,7 +131,7 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *70253477223880
134
+ version_requirements: *70242337977840
135
135
  description: Engine for a rails application which extends /rails/info about some information
136
136
  resources in development environment.
137
137
  email:
@@ -177,6 +177,7 @@ files:
177
177
  - app/views/layouts/rails_info.html.erb
178
178
  - app/views/layouts/shared/_navigation.html.erb
179
179
  - app/views/rails_info/data/index.html.erb
180
+ - app/views/rails_info/logs/server/_request.html.erb
180
181
  - app/views/rails_info/logs/server/_table.html.erb
181
182
  - app/views/rails_info/logs/server/new.html.erb
182
183
  - app/views/rails_info/logs/test/rspec/new.html.erb
@@ -256,7 +257,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
256
257
  version: '0'
257
258
  segments:
258
259
  - 0
259
- hash: 206197979266972554
260
+ hash: -3145686660104229554
260
261
  required_rubygems_version: !ruby/object:Gem::Requirement
261
262
  none: false
262
263
  requirements:
@@ -265,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
266
  version: '0'
266
267
  segments:
267
268
  - 0
268
- hash: 206197979266972554
269
+ hash: -3145686660104229554
269
270
  requirements: []
270
271
  rubyforge_project:
271
272
  rubygems_version: 1.8.17