rack-mini-profiler 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-mini-profiler might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 661dc965f1499d7a00baa35f5699e91e1552ff68
4
- data.tar.gz: 7bbccf4b17154aab14f7bd2012afcf2dac0efe25
3
+ metadata.gz: 09e877779936ca60a9be72fc14ae574a450cd338
4
+ data.tar.gz: b53fc49ccabb1d8560c0ee8014199388fbf6749a
5
5
  SHA512:
6
- metadata.gz: 903fe47823489fae4a2b18aff1cddca204130c1e41b2132c5db951007a5c1fe85b7b110f3264b8abc2f22c07d438071b81c93251bc31cbe26db725b868ca0a2a
7
- data.tar.gz: 400bb2bf85475461de90d238eb95cbac925710f758f576c7371cb7b25ef0998bf39d637835520b42dd96fbbeb7cd53f36fe531f83e9e9c8c1cf36022795fcb8c
6
+ metadata.gz: a5b9ced034cd204f59eb4be61c718a97960fed72a7e4484af99748b9ed62eb7a736a7ebc78668b46b71f743432c53758ced36f918a1c31859c7f965917f0c826
7
+ data.tar.gz: 3c97726e0f276ff8b1bd3cf220f64f4b9908ca950b4485f6c9978c05d3479582aa166314e0dbc2afb2c1cb478ebb6801f1459a9cb4bcc51df7cec7826ee96356
@@ -1,5 +1,22 @@
1
1
  # CHANGELOG
2
2
 
3
+ ##
4
+
5
+ ## 0.9.9 2016-03-06
6
+
7
+ - [FIX] removes alias_method_chain in favor of alias_method until Ruby 1.9.3 (@ayfredlund)
8
+ - [FIX] Dont block mongo when already patched for another db (@rrooding @kbrock)
9
+ - [FIX] get_profile_script when running under passenger configured with RailsBaseURI (@nspring)
10
+ - [FEATURE] Add support for neo4j (@ProGM)
11
+ - [FIX] ArgumentError: comparison of String with 200 failed (@paweljw)
12
+ - [FEATURE] Add support for Riak (@janx)
13
+ - [PERF] GC profiler much faster (@dgynn)
14
+ - [FIX] If local storage is disabled don't bomb out (@elia)
15
+ - [FIX] Create tmp directory when actually using it (@kbrock)
16
+ - [ADDED] Default collapse_results setting that collapses multiple timings on same page to a single one (@sam)
17
+ - [ADDED] Rack::MiniProfiler.profile_singleton_method (@kbrock)
18
+ - [CHANGE] Added Rack 2.0 support (and dropped support for Rack 1.1) (@dgynn)
19
+
3
20
  ## 0.9.8 - 2015-11-27 (Sam Saffron)
4
21
 
5
22
  - [FEATURE] disable_env_dump config setting (@mathias)
data/README.md CHANGED
@@ -66,11 +66,17 @@ end
66
66
 
67
67
  ```ruby
68
68
  require 'rack-mini-profiler'
69
+
70
+ home = lambda { |env|
71
+ [200, {'Content-Type' => 'text/html'}, ["<html><body>hello!</body></html>"]]
72
+ }
73
+
69
74
  builder = Rack::Builder.new do
70
75
  use Rack::MiniProfiler
71
-
72
- map('/') { run get }
76
+ map('/') { run home }
73
77
  end
78
+
79
+ run builder
74
80
  ```
75
81
 
76
82
  #### Sinatra
@@ -145,11 +151,11 @@ if Rails.env.production?
145
151
  end
146
152
  ```
147
153
 
148
- MemoryStore stores results in a processes heap - something that does not work well in a multi process environment.
149
- FileStore stores results in the file system - something that may not work well in a multi machine environment.
150
- RedisStore/MemcacheStore work in multi process and multi machine environments (RedisStore only saves results for up to 24 hours so it won't continue to fill up Redis).
154
+ `MemoryStore` stores results in a processes heap - something that does not work well in a multi process environment.
155
+ `FileStore` stores results in the file system - something that may not work well in a multi machine environment.
156
+ `RedisStore`/`MemcacheStore` work in multi process and multi machine environments (`RedisStore` only saves results for up to 24 hours so it won't continue to fill up Redis).
151
157
 
152
- Additionally you may implement an AbstractStore for your own provider.
158
+ Additionally you may implement an `AbstractStore` for your own provider.
153
159
 
154
160
  ### User result segregation
155
161
 
@@ -167,6 +173,17 @@ Rack::MiniProfiler.config.user_provider = Proc.new{ |env| CurrentUser.get(env) }
167
173
 
168
174
  The string this function returns should be unique for each user on the system (for anonymous you may need to fall back to ip address)
169
175
 
176
+ ### Profiling specific methods
177
+
178
+ You can increase the granularity of profiling by measuring the performance of specific methods. Add methods of interest to an initializer.
179
+
180
+ ```ruby
181
+ Rails.application.config.to_prepare do
182
+ ::Rack::MiniProfiler.profile_singleton_method(User, :non_admins) { |a| "executing all_non_admins" }
183
+ ::Rack::MiniProfiler.profile_method(User, :favorite_post) { |a| "executing favorite_post" }
184
+ end
185
+ ```
186
+
170
187
  ### Configuration Options
171
188
 
172
189
  You can set configuration options using the configuration accessor on `Rack::MiniProfiler`.
@@ -178,19 +195,23 @@ Rack::MiniProfiler.config.start_hidden = true
178
195
  ```
179
196
  The available configuration options are:
180
197
 
181
- * pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
182
- * position - Can either be 'right' or 'left'. Default is 'left'.
183
- * skip_paths - Specifies path list that can be skipped.
184
- * skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'false', 'true' in rails development.
185
- * auto_inject (default true) - when false the miniprofiler script is not injected in the page
186
- * backtrace_ignores (default nil) - an array of regexes you can use to filter out unwanted lines from the backtraces
187
- * backtrace_includes (default nil, or [/^\/?(app|config|lib|test)/] in rails) - an array of regexes you can use to keep lines in the backtrace
188
- * backtrace_remove (default nil, or Rails.root in rails) - A string or regex to remove part of each line in the backtrace
189
- * toggle_shortcut (default Alt+P) - a jquery.hotkeys.js-style keyboard shortcut, used to toggle the mini_profiler's visibility. See https://github.com/jeresig/jquery.hotkeys for more info.
190
- * start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
191
- * backtrace_threshold_ms (default zero) - Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
192
- * flamegraph_sample_rate (default 0.5ms) - How often fast_stack should get stack trace info to generate flamegraphs
193
- * disable_env_dump (default false) - When enabled, disables the `?pp=env` which can be useful when you are concerned about not sending ENV vars out over HTTP.
198
+ Option|Default|Description
199
+ -------|---|--------
200
+ pre_authorize_cb|Rails: dev only<br>Rack: always on|A lambda callback that returns true to make mini_profiler visible on a given request.
201
+ position|`'left'`|Display mini_profiler on `'right'` or `'left'`.
202
+ skip_paths|`[]`|Paths that skip profiling.
203
+ skip_schema_queries|Rails dev: `'true'`<br>Othwerwise: `'false'`|`'true'` to log schema queries.
204
+ auto_inject|`true`|`true` to inject the miniprofiler script in the page.
205
+ backtrace_ignores|`[]`|Regexes of lines to be removed from backtraces.
206
+ backtrace_includes|Rails: `[/^\/?(app|config|lib|test)/]`<br>Rack: `[]`|Regexes of lines to keep in backtraces.
207
+ backtrace_remove|rails: `Rails.root`<br>Rack: `nil`|A string or regex to remove part of each line in the backtrace.
208
+ toggle_shortcut|Alt+P|Keyboard shortcut to toggle the mini_profiler's visibility. See [jquery.hotkeys](https://github.com/jeresig/jquery.hotkeys).
209
+ start_hidden|`false`|`false` to make mini_profiler visible on page load.
210
+ backtrace_threshold_ms|`0`|Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
211
+ flamegraph_sample_rate|`0.5ms`|How often to capture stack traces for flamegraphs.
212
+ disable_env_dump|`false`|`true` disables `?pp=env`, which prevents sending ENV vars over HTTP.
213
+ base_url_path|`'/mini-profiler-resources/'`|Path for assets; added as a prefix when naming assets and sought when responding to requests.
214
+ collapse_results|`true`|If multiple timing results exist in a single page, collapse them till clicked.
194
215
 
195
216
  ### Custom middleware ordering (required if using `Rack::Deflate` with Rails)
196
217
 
@@ -267,6 +267,7 @@
267
267
  .profiler-results.profiler-left {
268
268
  left: 0px;
269
269
  }
270
+ .profiler-results.profiler-left.profiler-no-controls .profiler-totals,
270
271
  .profiler-results.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,
271
272
  .profiler-results.profiler-left .profiler-controls {
272
273
  -webkit-border-bottom-right-radius: 10px;
@@ -280,6 +281,7 @@
280
281
  .profiler-results.profiler-right {
281
282
  right: 0px;
282
283
  }
284
+ .profiler-results.profiler-right.profiler-no-controls .profiler-totals,
283
285
  .profiler-results.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,
284
286
  .profiler-results.profiler-right .profiler-controls {
285
287
  -webkit-border-bottom-left-radius: 10px;
@@ -316,6 +318,16 @@
316
318
  color: #fff;
317
319
  font-weight: normal;
318
320
  }
321
+ .profiler-results .profiler-totals .profiler-reqs {
322
+ font-family: Consolas, monospace, serif;
323
+ font-size: 10px;
324
+ margin-left: 6px;
325
+ }
326
+ .profiler-results .profiler-totals .profiler-reqs:before {
327
+ font-family: Consolas, monospace, serif;
328
+ content: "×";
329
+ margin-right: 1px;
330
+ }
319
331
  .profiler-results .profiler-controls {
320
332
  display: block;
321
333
  font-size: 12px;
@@ -10,9 +10,12 @@ var MiniProfiler = (function () {
10
10
  ajaxStartTime
11
11
  ;
12
12
 
13
- var hasLocalStorage = function () {
13
+ var hasLocalStorage = function (keyPrefix) {
14
14
  try {
15
- return 'localStorage' in window && window['localStorage'] !== null;
15
+ // attempt to save to localStorage as Safari private windows will throw an error
16
+ localStorage[keyPrefix+'-test'] = '1';
17
+ localStorage.removeItem(keyPrefix+'-test');
18
+ return 'localStorage' in window && window['localStorage'] !== null ;
16
19
  } catch (e) {
17
20
  return false;
18
21
  }
@@ -23,7 +26,7 @@ var MiniProfiler = (function () {
23
26
  };
24
27
 
25
28
  var save = function (keyPrefix, value) {
26
- if (!hasLocalStorage()) { return; }
29
+ if (!hasLocalStorage(keyPrefix)) { return; }
27
30
 
28
31
  // clear old keys with this prefix, if any
29
32
  for (var i = 0; i < localStorage.length; i++) {
@@ -37,7 +40,7 @@ var MiniProfiler = (function () {
37
40
  };
38
41
 
39
42
  var load = function (keyPrefix) {
40
- if (!hasLocalStorage()) { return null; }
43
+ if (!hasLocalStorage(keyPrefix)) { return null; }
41
44
 
42
45
  return localStorage[getVersionedKey(keyPrefix)];
43
46
  };
@@ -62,7 +65,7 @@ var MiniProfiler = (function () {
62
65
  };
63
66
 
64
67
  var getClientPerformance = function() {
65
- return window.performance == null ? null : window.performance;
68
+ return window.performance === null ? null : window.performance;
66
69
  };
67
70
 
68
71
  var fetchResults = function (ids) {
@@ -86,7 +89,7 @@ var MiniProfiler = (function () {
86
89
 
87
90
  clientPerformance = getClientPerformance();
88
91
 
89
- if (clientPerformance != null) {
92
+ if (clientPerformance !== null) {
90
93
  // ie is buggy strip out functions
91
94
  var copy = { navigation: {}, timing: {} };
92
95
 
@@ -114,7 +117,7 @@ var MiniProfiler = (function () {
114
117
 
115
118
  }
116
119
  }
117
- } else if (ajaxStartTime != null && clientProbes && clientProbes.length > 0) {
120
+ } else if (ajaxStartTime !== null && clientProbes && clientProbes.length > 0) {
118
121
  clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
119
122
  ajaxStartTime = null;
120
123
  }
@@ -146,9 +149,39 @@ var MiniProfiler = (function () {
146
149
  return $('#profilerTemplate').tmpl(json);
147
150
  };
148
151
 
152
+ var totalsControl;
153
+ var reqs = 0;
154
+ var totalTime = 0;
155
+
149
156
  var buttonShow = function (json) {
150
157
  var result = renderTemplate(json);
151
158
 
159
+ totalTime += parseFloat(json.duration_milliseconds, 10);
160
+ reqs++;
161
+
162
+ if (!controls && reqs > 1 && options.collapseResults) {
163
+ if (!totalsControl) {
164
+ container.find('.profiler-result').hide();
165
+
166
+ totalsControl = $("<div class='profiler-result'><div class='profiler-button profiler-totals'></div></div>");
167
+ totalsControl.appendTo(container);
168
+ totalsControl.click(function(){
169
+ totalsControl.parent().find('.profiler-result').show();
170
+ totalsControl.hide();
171
+ options.collapseResults = false;
172
+ });
173
+
174
+ totalsControl.find('.profiler-button').show();
175
+ }
176
+
177
+ var reqsHtml = reqs > 1 ? ("<span class='profiler-reqs'>" + reqs + "</span>") : "";
178
+ totalsControl.find('.profiler-button').html("<span class='profiler-number'>" +
179
+ totalTime.toFixed(1) + "</span> <span class='profiler-unit'>ms</span>" +
180
+ reqsHtml);
181
+
182
+ result.hide();
183
+ }
184
+
152
185
  if (controls)
153
186
  result.insertBefore(controls);
154
187
  else
@@ -480,7 +513,7 @@ var MiniProfiler = (function () {
480
513
  PageRequestManager.add_endRequest(function (sender, args) {
481
514
  if (args) {
482
515
  var response = args.get_response();
483
- if (response.get_responseAvailable() && response._xmlHttpRequest != null) {
516
+ if (response.get_responseAvailable() && response._xmlHttpRequest !== null) {
484
517
  var stringIds = args.get_response().getResponseHeader('X-MiniProfiler-Ids');
485
518
  if (stringIds) {
486
519
  var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
@@ -557,14 +590,14 @@ var MiniProfiler = (function () {
557
590
  }
558
591
  }
559
592
 
560
- if (this.miniprofiler.prev_onreadystatechange != null)
593
+ if (this.miniprofiler.prev_onreadystatechange !== null)
561
594
  return this.miniprofiler.prev_onreadystatechange.apply(this, arguments);
562
595
  };
563
596
  }
564
597
  }
565
598
 
566
599
  return _send.apply(this, arguments);
567
- }
600
+ };
568
601
  }
569
602
 
570
603
  // some elements want to be hidden on certain doc events
@@ -594,11 +627,12 @@ var MiniProfiler = (function () {
594
627
  var maxTraces = parseInt(script.getAttribute('data-max-traces'), 10);
595
628
  }
596
629
 
597
- if (script.getAttribute('data-trivial') === 'true') var trivial = true;
598
- if (script.getAttribute('data-children') == 'true') var children = true;
599
- if (script.getAttribute('data-controls') == 'true') var controls = true;
600
- if (script.getAttribute('data-authorized') == 'true') var authorized = true;
601
- if (script.getAttribute('data-start-hidden') == 'true') var startHidden = true;
630
+ var collapseResults = script.getAttribute('data-collapse-results') === 'true';
631
+ var trivial = script.getAttribute('data-trivial') === 'true';
632
+ var children = script.getAttribute('data-children') === 'true';
633
+ var controls = script.getAttribute('data-controls') === 'true';
634
+ var authorized = script.getAttribute('data-authorized') === 'true';
635
+ var startHidden = script.getAttribute('data-start-hidden') === 'true';
602
636
 
603
637
  return {
604
638
  ids: ids,
@@ -612,7 +646,8 @@ var MiniProfiler = (function () {
612
646
  currentId: currentId,
613
647
  authorized: authorized,
614
648
  toggleShortcut: toggleShortcut,
615
- startHidden: startHidden
649
+ startHidden: startHidden,
650
+ collapseResults: collapseResults
616
651
  };
617
652
  })();
618
653
 
@@ -842,7 +877,7 @@ var MiniProfiler = (function () {
842
877
  var processTimes = function (elem, parent) {
843
878
  var duration = { start: elem.start_milliseconds, finish: (elem.start_milliseconds + elem.duration_milliseconds) };
844
879
  elem.richTiming = [duration];
845
- if (parent != null) {
880
+ if (parent !== null) {
846
881
  elem.parent = parent;
847
882
  elem.parent.richTiming = removeDuration(elem.parent.richTiming, duration);
848
883
  }
@@ -877,7 +912,7 @@ var MiniProfiler = (function () {
877
912
 
878
913
  var determineGap = function (gap, node, match) {
879
914
  var overlap = determineOverlap(gap, node);
880
- if (match == null || overlap > match.duration) {
915
+ if (match === null || overlap > match.duration) {
881
916
  match = { name: node.name, duration: overlap };
882
917
  }
883
918
  else if (match.name == node.name) {
@@ -247,7 +247,7 @@
247
247
  }
248
248
 
249
249
  // ajaxed-in results will be appended to this
250
- .profiler-results
250
+ .profiler-results
251
251
  {
252
252
  z-index:@zindex + 3;
253
253
  position:fixed;
@@ -258,7 +258,7 @@
258
258
  &.profiler-left {
259
259
  left:0px;
260
260
 
261
- &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
261
+ &.profiler-no-controls .profiler-totals, &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
262
262
  -webkit-border-bottom-right-radius: @radius;
263
263
  -moz-border-radius-bottomright: @radius;
264
264
  border-bottom-right-radius: @radius;
@@ -272,7 +272,7 @@
272
272
  &.profiler-right {
273
273
  right:0px;
274
274
 
275
- &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
275
+ &.profiler-no-controls .profiler-totals, &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
276
276
  -webkit-border-bottom-left-radius: @radius;
277
277
  -moz-border-radius-bottomleft: @radius;
278
278
  border-bottom-left-radius: @radius;
@@ -306,6 +306,20 @@
306
306
  }
307
307
  }
308
308
 
309
+
310
+ .profiler-totals {
311
+ .profiler-reqs {
312
+ font-family: @codeFonts;
313
+ font-size: 10px;
314
+ margin-left: 6px;
315
+ &:before {
316
+ font-family: @codeFonts;
317
+ content: "×";
318
+ margin-right: 1px;
319
+ }
320
+ }
321
+ }
322
+
309
323
  .profiler-controls {
310
324
  display: block;
311
325
  font-size:12px;
@@ -1 +1 @@
1
- <script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}"></script>
1
+ <script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}"></script>
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- ASSET_VERSION = 'e0e50f551fa464f9d95c2e082bb2d45b'.freeze
3
+ ASSET_VERSION = '16af8af9ec9b135097ff8209e717f825'.freeze
4
4
  end
5
5
  end
@@ -18,7 +18,7 @@ module Rack
18
18
  :flamegraph_sample_rate, :logger, :position, :pre_authorize_cb,
19
19
  :skip_paths, :skip_schema_queries, :start_hidden, :storage,
20
20
  :storage_failure, :storage_instance, :storage_options, :toggle_shortcut,
21
- :user_provider
21
+ :user_provider, :collapse_results
22
22
 
23
23
  # Deprecated options
24
24
  attr_accessor :use_existing_jquery
@@ -48,6 +48,7 @@ module Rack
48
48
  end
49
49
  @enabled = true
50
50
  @disable_env_dump = false
51
+ @collapse_results = true
51
52
  self
52
53
  }
53
54
  end
@@ -6,18 +6,15 @@ class Rack::MiniProfiler::GCProfiler
6
6
  end
7
7
 
8
8
  def object_space_stats
9
- stats = {}
10
- ids = {}
9
+ stats = Hash.new(0).compare_by_identity
10
+ ids = Hash.new.compare_by_identity
11
11
 
12
12
  @ignore << stats.__id__
13
13
  @ignore << ids.__id__
14
14
 
15
- i=0
16
15
  ObjectSpace.each_object { |o|
17
16
  begin
18
- i = stats[o.class] || 0
19
- i += 1
20
- stats[o.class] = i
17
+ stats[o.class] += 1
21
18
  ids[o.__id__] = o if Integer === o.__id__
22
19
  rescue NoMethodError
23
20
  # protect against BasicObject
@@ -38,12 +35,12 @@ class Rack::MiniProfiler::GCProfiler
38
35
  end
39
36
 
40
37
  def diff_object_stats(before, after)
41
- diff = {}
38
+ diff = {}.compare_by_identity
42
39
  after.each do |k,v|
43
- diff[k] = v - (before[k] || 0)
40
+ diff[k] = v - before[k]
44
41
  end
45
42
  before.each do |k,v|
46
- diff[k] = 0 - v unless after[k]
43
+ diff[k] = 0 - v unless after.has_key?(k)
47
44
  end
48
45
 
49
46
  diff
@@ -97,11 +94,6 @@ class Rack::MiniProfiler::GCProfiler
97
94
  # for memsize_of
98
95
  require 'objspace'
99
96
 
100
- body = [];
101
-
102
- stat_before,stat_after,diff,string_analysis,
103
- new_objects, memory_allocated, stat, memory_before, objects_before = nil
104
-
105
97
  # clean up before
106
98
  GC.start
107
99
  stat = GC.stat
@@ -118,13 +110,17 @@ class Rack::MiniProfiler::GCProfiler
118
110
  new_objects, memory_allocated = analyze_growth(stat_before[:ids], stat_after[:ids])
119
111
  objects_before, memory_before = analyze_initial_state(stat_before[:ids])
120
112
 
113
+ body = []
121
114
 
122
115
  body << "
123
116
  Overview
124
- ------------------------------------
125
- Initial state: object count - #{objects_before} , memory allocated outside heap (bytes) #{memory_before}
117
+ --------
118
+ Initial state: object count: #{objects_before}
119
+ Memory allocated outside heap (bytes): #{memory_before}
126
120
 
127
- GC Stats: #{stat.map{|k,v| "#{k} : #{v}" }.join(", ")}
121
+ GC Stats:
122
+ --------
123
+ #{stat.map{|k,v| "#{k} : #{v}" }.sort!.join("\n")}
128
124
 
129
125
  New bytes allocated outside of Ruby heaps: #{memory_allocated}
130
126
  New objects: #{new_objects}
@@ -132,16 +128,16 @@ New objects: #{new_objects}
132
128
 
133
129
  body << "
134
130
  ObjectSpace delta caused by request:
135
- --------------------------------------------\n"
136
- diff.to_a.reject{|k,v| v == 0}.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
137
- body << "#{k} : #{v}\n" if v != 0
131
+ -----------------------------------\n"
132
+ diff.to_a.delete_if{|_k, v| v == 0}.sort_by! { |_k, v| v }.reverse_each do |k,v|
133
+ body << "#{k} : #{v}\n"
138
134
  end
139
135
 
140
136
  body << "\n
141
137
  ObjectSpace stats:
142
138
  -----------------\n"
143
139
 
144
- stat_after[:stats].to_a.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
140
+ stat_after[:stats].to_a.sort_by!{ |_k, v| v }.reverse_each do |k,v|
145
141
  body << "#{k} : #{v}\n"
146
142
  end
147
143
 
@@ -150,7 +146,7 @@ ObjectSpace stats:
150
146
  String stats:
151
147
  ------------\n"
152
148
 
153
- string_analysis.to_a.sort{|x,y| y[1] <=> x[1] }.take(1000).each do |string,count|
149
+ string_analysis.to_a.sort_by!{ |_k, v| -v }.take(1000).each do |string,count|
154
150
  body << "#{count} : #{string}\n"
155
151
  end
156
152
 
@@ -17,6 +17,10 @@ module Rack
17
17
  @config ||= Config.default
18
18
  end
19
19
 
20
+ def resources_root
21
+ @resources_root ||= ::File.expand_path("../../html", __FILE__)
22
+ end
23
+
20
24
  def share_template
21
25
  @share_template ||= ::File.read(::File.expand_path("../html/share.html", ::File.dirname(__FILE__)))
22
26
  end
@@ -37,10 +41,11 @@ module Rack
37
41
 
38
42
  def create_current(env={}, options={})
39
43
  # profiling the request
40
- self.current = Context.new
41
- self.current.inject_js = config.auto_inject && (!env['HTTP_X_REQUESTED_WITH'].eql? 'XMLHttpRequest')
42
- self.current.page_struct = TimerStruct::Page.new(env)
43
- self.current.current_timer = current.page_struct[:root]
44
+ context = Context.new
45
+ context.inject_js = config.auto_inject && (!env['HTTP_X_REQUESTED_WITH'].eql? 'XMLHttpRequest')
46
+ context.page_struct = TimerStruct::Page.new(env)
47
+ context.current_timer = context.page_struct[:root]
48
+ self.current = context
44
49
  end
45
50
 
46
51
  def authorize_request
@@ -92,24 +97,26 @@ module Rack
92
97
  @storage.set_viewed(user(env), id)
93
98
  end
94
99
 
95
- result_json = page_struct.to_json
96
100
  # If we're an XMLHttpRequest, serve up the contents as JSON
97
101
  if request.xhr?
102
+ result_json = page_struct.to_json
98
103
  [200, { 'Content-Type' => 'application/json'}, [result_json]]
99
104
  else
100
-
101
105
  # Otherwise give the HTML back
102
- html = MiniProfiler.share_template.dup
103
- html.gsub!(/\{path\}/, "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}")
104
- html.gsub!(/\{version\}/, MiniProfiler::ASSET_VERSION)
105
- html.gsub!(/\{json\}/, result_json)
106
- html.gsub!(/\{includes\}/, get_profile_script(env))
107
- html.gsub!(/\{name\}/, page_struct[:name])
108
- html.gsub!(/\{duration\}/, "%.1f" % page_struct.duration_ms)
109
-
106
+ html = generate_html(page_struct, env)
110
107
  [200, {'Content-Type' => 'text/html'}, [html]]
111
108
  end
109
+ end
112
110
 
111
+ def generate_html(page_struct, env, result_json = page_struct.to_json)
112
+ html = MiniProfiler.share_template.dup
113
+ html.sub!('{path}', "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}")
114
+ html.sub!('{version}', MiniProfiler::ASSET_VERSION)
115
+ html.sub!('{json}', result_json)
116
+ html.sub!('{includes}', get_profile_script(env))
117
+ html.sub!('{name}', page_struct[:name])
118
+ html.sub!('{duration}', page_struct.duration_ms.round(1).to_s)
119
+ html
113
120
  end
114
121
 
115
122
  def serve_html(env)
@@ -117,21 +124,11 @@ module Rack
117
124
 
118
125
  return serve_results(env) if file_name.eql?('results')
119
126
 
120
- full_path = ::File.expand_path("../html/#{file_name}", ::File.dirname(__FILE__))
121
- return [404, {}, ["Not found"]] unless ::File.exists? full_path
122
- f = Rack::File.new nil
123
- f.path = full_path
124
-
125
- begin
126
- f.cache_control = "max-age:86400"
127
- f.serving env
128
- rescue
129
- # old versions of rack have a different api
130
- status, headers, body = f.serving
131
- headers.merge! 'Cache-Control' => "max-age:86400"
132
- [status, headers, body]
133
- end
127
+ resources_env = env.dup
128
+ resources_env['PATH_INFO'] = file_name
134
129
 
130
+ rack_file = Rack::File.new(MiniProfiler.resources_root, {'Cache-Control' => 'max-age:86400'})
131
+ rack_file.call(resources_env)
135
132
  end
136
133
 
137
134
 
@@ -197,11 +194,13 @@ module Rack
197
194
  client_settings.disable_profiling = false
198
195
  end
199
196
 
197
+ # profile gc
200
198
  if query_string =~ /pp=profile-gc/
201
199
  current.measure = false if current
202
200
  return Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env)
203
201
  end
204
202
 
203
+ # profile memory
205
204
  if query_string =~ /pp=profile-memory/
206
205
  query_params = Rack::Utils.parse_nested_query(query_string)
207
206
  options = {
@@ -291,7 +290,7 @@ module Rack
291
290
  if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
292
291
  # this is non-obvious, don't kill the profiling cookie on errors or short requests
293
292
  # this ensures that stuff that never reaches the rails stack does not kill profiling
294
- if status >= 200 && status < 300 && ((Time.now - start) > 0.1)
293
+ if status.to_i >= 200 && status.to_i < 300 && ((Time.now - start) > 0.1)
295
294
  client_settings.discard_cookie!(headers)
296
295
  end
297
296
  skip_it = true
@@ -389,39 +388,17 @@ module Rack
389
388
  end
390
389
 
391
390
  def inject(fragment, script)
392
- if fragment.match(/<\/body>/i)
393
- # explicit </body>
394
-
395
- regex = /<\/body>/i
396
- close_tag = '</body>'
397
- elsif fragment.match(/<\/html>/i)
398
- # implicit </body>
399
-
400
- regex = /<\/html>/i
401
- close_tag = '</html>'
402
- else
403
- # implicit </body> and </html>. Don't do anything.
404
-
405
- return fragment
406
- end
407
-
408
- matches = fragment.scan(regex).length
409
- index = 1
410
- fragment.gsub(regex) do
411
- # though malformed there is an edge case where /body exists earlier in the html, work around
412
- if index < matches
413
- index += 1
414
- close_tag
415
- else
416
-
417
- # if for whatever crazy reason we dont get a utf string,
418
- # just force the encoding, no utf in the mp scripts anyway
419
- if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
420
- (script + close_tag).force_encoding(fragment.encoding)
421
- else
422
- script + close_tag
423
- end
391
+ # find explicit or implicit body
392
+ index = fragment.rindex(/<\/body>/i) || fragment.rindex(/<\/html>/i)
393
+ if index
394
+ # if for whatever crazy reason we dont get a utf string,
395
+ # just force the encoding, no utf in the mp scripts anyway
396
+ if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
397
+ script = script.force_encoding(fragment.encoding)
424
398
  end
399
+ fragment.insert(index, script)
400
+ else
401
+ fragment
425
402
  end
426
403
  end
427
404
 
@@ -594,7 +571,13 @@ Append the following to your query string:
594
571
  # * you have disabled auto append behaviour throught :auto_inject => false flag
595
572
  # * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
596
573
  def get_profile_script(env)
597
- path = if env["action_controller.instance"]
574
+ path = if ENV["PASSENGER_BASE_URI"] then
575
+ # added because the SCRIPT_NAME workaround below then
576
+ # breaks running under a prefix as permitted by Passenger.
577
+ "#{ENV['PASSENGER_BASE_URI']}#{@config.base_url_path}"
578
+ elsif env["action_controller.instance"]
579
+ # Rails engines break SCRIPT_NAME; the following appears to discard SCRIPT_NAME
580
+ # since url_for appears documented to return any String argument unmodified
598
581
  env["action_controller.instance"].url_for("#{@config.base_url_path}")
599
582
  else
600
583
  "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
@@ -610,7 +593,8 @@ Append the following to your query string:
610
593
  :showControls => false,
611
594
  :authorized => true,
612
595
  :toggleShortcut => @config.toggle_shortcut,
613
- :startHidden => @config.start_hidden
596
+ :startHidden => @config.start_hidden,
597
+ :collapseResults => @config.collapse_results
614
598
  }
615
599
 
616
600
  if current && current.page_struct
@@ -3,9 +3,9 @@ module Rack
3
3
  module ProfilingMethods
4
4
 
5
5
  def record_sql(query, elapsed_ms)
6
- return unless current
6
+ return unless current && current.current_timer
7
7
  c = current
8
- c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace) if (c && c.current_timer)
8
+ c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace)
9
9
  end
10
10
 
11
11
  def start_step(name)
@@ -26,10 +26,9 @@ module Rack
26
26
  def step(name, opts = nil)
27
27
  if current
28
28
  parent_timer = current.current_timer
29
- result = nil
30
29
  current.current_timer = current_timer = current.current_timer.add_child(name)
31
30
  begin
32
- result = yield if block_given?
31
+ yield if block_given?
33
32
  ensure
34
33
  current_timer.record_time
35
34
  current.current_timer = parent_timer
@@ -87,34 +86,37 @@ module Rack
87
86
  end
88
87
  end
89
88
 
90
- result = nil
91
89
  parent_timer = Rack::MiniProfiler.current.current_timer
92
90
 
93
91
  if type == :counter
94
92
  start = Time.now
95
93
  begin
96
- result = self.send without_profiling, *args, &orig
94
+ self.send without_profiling, *args, &orig
97
95
  ensure
98
96
  duration_ms = (Time.now - start).to_f * 1000
99
97
  parent_timer.add_custom(name, duration_ms, Rack::MiniProfiler.current.page_struct )
100
98
  end
101
99
  else
102
- page_struct = Rack::MiniProfiler.current.page_struct
103
-
104
100
  Rack::MiniProfiler.current.current_timer = current_timer = parent_timer.add_child(name)
105
101
  begin
106
- result = self.send without_profiling, *args, &orig
102
+ self.send without_profiling, *args, &orig
107
103
  ensure
108
104
  current_timer.record_time
109
105
  Rack::MiniProfiler.current.current_timer = parent_timer
110
106
  end
111
107
  end
112
-
113
- result
114
108
  end
115
109
  klass.send :alias_method, method, with_profiling
116
110
  end
117
111
 
112
+ def profile_singleton_method(klass, method, type = :profile, &blk)
113
+ profile_method(singleton_class(klass), method, type, &blk)
114
+ end
115
+
116
+ def unprofile_singleton_method(klass, method)
117
+ unprofile_method(singleton_class(klass), method)
118
+ end
119
+
118
120
  # Add a custom timing. These are displayed similar to SQL/query time in
119
121
  # columns expanding to the right.
120
122
  #
@@ -140,6 +142,10 @@ module Rack
140
142
 
141
143
  private
142
144
 
145
+ def singleton_class(klass)
146
+ class << klass; self; end
147
+ end
148
+
143
149
  def clean_method_name(method)
144
150
  method.to_s.gsub(/[\?\!]/, "")
145
151
  end
@@ -44,6 +44,8 @@ module Rack
44
44
  @path = args[:path]
45
45
  @expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
46
46
  raise ArgumentError.new :path unless @path
47
+ FileUtils.mkdir_p(@path) unless ::File.exists?(@path)
48
+
47
49
  @timer_struct_cache = FileCache.new(@path, "mp_timers")
48
50
  @timer_struct_lock = Mutex.new
49
51
  @user_view_cache = FileCache.new(@path, "mp_views")
@@ -40,10 +40,18 @@ module Rack
40
40
  self[:root] = TimerStruct::Request.createRoot(name, self)
41
41
  end
42
42
 
43
+ def name
44
+ @attributes[:name]
45
+ end
46
+
43
47
  def duration_ms
44
48
  @attributes[:root][:duration_milliseconds]
45
49
  end
46
50
 
51
+ def duration_ms_in_sql
52
+ @attributes[:duration_milliseconds_in_sql]
53
+ end
54
+
47
55
  def root
48
56
  @attributes[:root]
49
57
  end
@@ -44,10 +44,18 @@ module Rack
44
44
  @page = page
45
45
  end
46
46
 
47
+ def name
48
+ @attributes[:name]
49
+ end
50
+
47
51
  def duration_ms
48
52
  self[:duration_milliseconds]
49
53
  end
50
54
 
55
+ def duration_ms_in_sql
56
+ @attributes[:duration_milliseconds_in_sql]
57
+ end
58
+
51
59
  def start_ms
52
60
  self[:start_milliseconds]
53
61
  end
@@ -17,11 +17,11 @@ module Rack
17
17
  (
18
18
  (
19
19
  Rack::MiniProfiler.config.backtrace_includes.nil? or
20
- Rack::MiniProfiler.config.backtrace_includes.all?{|regex| ln =~ regex}
20
+ Rack::MiniProfiler.config.backtrace_includes.any?{|regex| ln =~ regex}
21
21
  ) and
22
22
  (
23
23
  Rack::MiniProfiler.config.backtrace_ignores.nil? or
24
- Rack::MiniProfiler.config.backtrace_ignores.all?{|regex| !(ln =~ regex)}
24
+ Rack::MiniProfiler.config.backtrace_ignores.none?{|regex| ln =~ regex}
25
25
  )
26
26
  )
27
27
  stack_trace << ln << "\n"
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- VERSION = '0.9.8'
3
+ VERSION = '0.9.9'
4
4
  end
5
5
  end
@@ -4,9 +4,9 @@ module Rack::MiniProfilerRails
4
4
 
5
5
  # call direct if needed to do a defer init
6
6
  def self.initialize!(app)
7
-
7
+
8
8
  raise "MiniProfilerRails initialized twice. Set `require: false' for rack-mini-profiler in your Gemfile" if @already_initialized
9
-
9
+
10
10
  c = Rack::MiniProfiler.config
11
11
 
12
12
  # By default, only show the MiniProfiler in development mode.
@@ -24,7 +24,9 @@ module Rack::MiniProfilerRails
24
24
 
25
25
  c.skip_paths ||= []
26
26
 
27
- c.skip_paths << app.config.assets.prefix if serves_static_assets?(app)
27
+ if serves_static_assets?(app)
28
+ c.skip_paths << app.config.assets.prefix
29
+ end
28
30
 
29
31
  if Rails.env.development?
30
32
  c.skip_schema_queries = true
@@ -41,7 +43,6 @@ module Rack::MiniProfilerRails
41
43
  # The file store is just so much less flaky
42
44
  base_path = Rails.application.config.paths['tmp'].first rescue "#{Rails.root}/tmp"
43
45
  tmp = base_path + '/miniprofiler'
44
- FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
45
46
 
46
47
  c.storage_options = {:path => tmp}
47
48
  c.storage = Rack::MiniProfiler::FileStore
@@ -61,17 +62,23 @@ module Rack::MiniProfilerRails
61
62
  ActiveSupport.on_load(:action_view) do
62
63
  ::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
63
64
  end
64
-
65
+
65
66
  @already_initialized = true
66
67
  end
67
68
 
68
69
  def self.serves_static_assets?(app)
69
- return false if !app.respond_to?(:assets)
70
- # Rails 4.2 deprecates serve_static_assets in favor of serve_static_files
71
- if app.config.respond_to?(:serve_static_files)
72
- app.config.serve_static_files
70
+ config = app.config
71
+
72
+ if !config.respond_to?(:assets) || !config.assets.respond_to?(:prefix)
73
+ return false
74
+ end
75
+
76
+ if ::Rails.version >= "5.0.0"
77
+ ::Rails.configuration.public_file_server.enabled
78
+ elsif ::Rails.version >= "4.2.0"
79
+ ::Rails.configuration.serve_static_files
73
80
  else
74
- app.config.serve_static_assets
81
+ ::Rails.configuration.serve_static_assets
75
82
  end
76
83
  end
77
84
 
@@ -21,6 +21,8 @@ module Rack
21
21
  rval = log_without_miniprofiler(*args, &block)
22
22
 
23
23
  # Don't log schema queries if the option is set
24
+ # return rval unless sql =~ /\"vms\"/
25
+ # return rval unless sql =~ /\"(vms|ext_management_systems)\"/
24
26
  return rval if Rack::MiniProfiler.config.skip_schema_queries and name =~ /SCHEMA/
25
27
 
26
28
  elapsed_time = SqlPatches.elapsed_time(start)
@@ -8,5 +8,9 @@ class Mongo::Server::Connection
8
8
  end
9
9
  return result
10
10
  end
11
- alias_method_chain :dispatch, :timing
11
+
12
+ # TODO: change to Module#prepend as soon as Ruby 1.9.3 support is dropped
13
+ alias_method :dispatch_without_timing, :dispatch
14
+ alias_method :dispatch, :dispatch_with_timing
15
+
12
16
  end
@@ -0,0 +1,14 @@
1
+ class Neo4j::Core::Query
2
+ alias_method :response_without_miniprofiler, :response
3
+
4
+ def response
5
+ return @response if @response
6
+ start = Time.now
7
+ rval = response_without_miniprofiler
8
+ elapsed_time = SqlPatches.elapsed_time(start)
9
+ Rack::MiniProfiler.record_sql(to_cypher, elapsed_time)
10
+ rval
11
+ end
12
+
13
+ alias_method :response_with_miniprofiler, :response
14
+ end
@@ -0,0 +1,103 @@
1
+ # riak-client 2.2.2 patches
2
+ class Riak::Multiget
3
+ class <<self
4
+ alias_method :get_all_without_profiling, :get_all
5
+ def get_all(client, fetch_list)
6
+ return get_all_without_profiling(client, fetch_list) unless SqlPatches.should_measure?
7
+
8
+ start = Time.now
9
+ result = get_all_without_profiling(client, fetch_list)
10
+ elapsed_time = SqlPatches.elapsed_time(start)
11
+ record = ::Rack::MiniProfiler.record_sql("get_all size=#{fetch_list.size}", elapsed_time)
12
+
13
+ result
14
+ end
15
+ end
16
+ end
17
+
18
+ class Riak::Client
19
+
20
+ alias_method :buckets_without_profiling, :buckets
21
+ def buckets(options={}, &blk)
22
+ profile("buckets #{options}") { buckets_without_profiling(options, &blk) }
23
+ end
24
+
25
+ alias_method :client_id_without_profiling, :client_id
26
+ def client_id
27
+ profile("client_id") { client_id_without_profiling }
28
+ end
29
+
30
+ alias_method :delete_object_without_profiling, :delete_object
31
+ def delete_object(bucket, key, options={})
32
+ profile("delete_object bucket=#{bucket.name} key=#{key} options=#{options}") { delete_object_without_profiling(bucket, key, options) }
33
+ end
34
+
35
+ alias_method :get_bucket_props_without_profiling, :get_bucket_props
36
+ def get_bucket_props(bucket, options={})
37
+ profile("get_bucket_props bucket=#{bucket.name} options=#{options}") { get_bucket_props_without_profiling(bucket, options) }
38
+ end
39
+
40
+ alias_method :get_index_without_profiling, :get_index
41
+ def get_index(bucket, index, query, options={})
42
+ profile("get_index bucket=#{bucket.name} index=#{index} query=#{query} options=#{options}") { get_index_without_profiling(bucket, index, query, options) }
43
+ end
44
+
45
+ alias_method :get_preflist_without_profiling, :get_preflist
46
+ def get_preflist(bucket, key, type=nil, options={})
47
+ profile("get_preflist bucket=#{bucket.name} key=#{key} type=#{type} options=#{options}") { get_preflist_without_profiling(bucket, key, type, options) }
48
+ end
49
+
50
+ alias_method :get_object_without_profiling, :get_object
51
+ def get_object(bucket, key, options={})
52
+ profile("get_object bucket=#{bucket.name} key=#{key} options=#{options}") { get_object_without_profiling(bucket, key, options) }
53
+ end
54
+
55
+ alias_method :list_keys_without_profiling, :list_keys
56
+ def list_keys(bucket, options={}, &block)
57
+ profile("list_keys bucket=#{bucket.name} options=#{options}") { list_keys_without_profiling(bucket, options, &block) }
58
+ end
59
+
60
+ alias_method :mapred_without_profiling, :mapred
61
+ def mapred(mr, &block)
62
+ profile("mapred") { mapred_without_profiling(mr, &block) }
63
+ end
64
+
65
+ alias_method :ping_without_profiling, :ping
66
+ def ping
67
+ profile("ping") { ping_without_profiling }
68
+ end
69
+
70
+ alias_method :reload_object_without_profiling, :reload_object
71
+ def reload_object(object, options={})
72
+ profile("reload_object bucket=#{object.bucket.name} key=#{object.key} vclock=#{object.vclock} options=#{options}") { reload_object_without_profiling(object, options) }
73
+ end
74
+
75
+ alias_method :set_bucket_props_without_profiling, :set_bucket_props
76
+ def set_bucket_props(bucket, properties, type=nil)
77
+ profile("set_bucket_props bucket=#{bucket.name} type=#{type}") { set_bucket_props_without_profiling(bucket, properties, type) }
78
+ end
79
+
80
+ alias_method :clear_bucket_props_without_profiling, :clear_bucket_props
81
+ def clear_bucket_props(bucket, options={})
82
+ profile("clear_bucket_props bucket=#{bucket.name} options=#{options}") { clear_bucket_props_without_profiling(bucket, options) }
83
+ end
84
+
85
+ alias_method :store_object_without_profiling, :store_object
86
+ def store_object(object, options={})
87
+ profile("store_object bucket=#{object.bucket.name} key=#{object.key} vclock=#{object.vclock} options=#{options}") { store_object_without_profiling(object, options) }
88
+ end
89
+
90
+ private
91
+
92
+ def profile(request, &blk)
93
+ return yield unless SqlPatches.should_measure?
94
+
95
+ start = Time.now
96
+ result = yield
97
+ elapsed_time = SqlPatches.elapsed_time(start)
98
+ record = ::Rack::MiniProfiler.record_sql(request, elapsed_time)
99
+
100
+ result
101
+ end
102
+
103
+ end
@@ -46,10 +46,12 @@ end
46
46
  require 'patches/db/mysql2' if defined?(Mysql2::Client) && SqlPatches.class_exists?("Mysql2::Client")
47
47
  require 'patches/db/pg' if defined?(PG::Result) && SqlPatches.class_exists?("PG::Result")
48
48
  require 'patches/db/oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && SqlPatches.class_exists?("ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter") && SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
49
- require 'patches/db/mongo' if defined?(Mongo) &&!SqlPatches.patched? && SqlPatches.module_exists?("Mongo")
49
+ require 'patches/db/mongo' if defined?(Mongo) && SqlPatches.module_exists?("Mongo")
50
50
  require 'patches/db/moped' if defined?(Moped::Node) && SqlPatches.class_exists?("Moped::Node")
51
51
  require 'patches/db/plucky' if defined?(Plucky::Query) && SqlPatches.class_exists?("Plucky::Query")
52
52
  require 'patches/db/rsolr' if defined?(RSolr::Connection) && SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
53
53
  require 'patches/db/sequel' if defined?(Sequel::Database) && !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
54
54
  require 'patches/db/activerecord' if defined?(ActiveRecord) &&!SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
55
55
  require 'patches/db/nobrainer' if defined?(NoBrainer) && SqlPatches.module_exists?("NoBrainer")
56
+ require 'patches/db/riak' if defined?(Riak) && SqlPatches.module_exists?("Riak")
57
+ require 'patches/db/neo4j' if defined?(Neo4j::Core) && SqlPatches.class_exists?("Neo4j::Core::Query")
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  "README.md",
19
19
  "CHANGELOG.md"
20
20
  ]
21
- s.add_runtime_dependency 'rack', '>= 1.1.3'
21
+ s.add_runtime_dependency 'rack', '>= 1.2.0'
22
22
  if RUBY_VERSION < "1.9"
23
23
  s.add_runtime_dependency 'json', '>= 1.6'
24
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-mini-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-11-27 00:00:00.000000000 Z
13
+ date: 2016-03-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 1.1.3
21
+ version: 1.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: 1.1.3
28
+ version: 1.2.0
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rake
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -226,10 +226,12 @@ files:
226
226
  - lib/patches/db/mongo.rb
227
227
  - lib/patches/db/moped.rb
228
228
  - lib/patches/db/mysql2.rb
229
+ - lib/patches/db/neo4j.rb
229
230
  - lib/patches/db/nobrainer.rb
230
231
  - lib/patches/db/oracle_enhanced.rb
231
232
  - lib/patches/db/pg.rb
232
233
  - lib/patches/db/plucky.rb
234
+ - lib/patches/db/riak.rb
233
235
  - lib/patches/db/rsolr.rb
234
236
  - lib/patches/db/sequel.rb
235
237
  - lib/patches/net_patches.rb
@@ -256,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
258
  version: '0'
257
259
  requirements: []
258
260
  rubyforge_project:
259
- rubygems_version: 2.4.5.1
261
+ rubygems_version: 2.4.5
260
262
  signing_key:
261
263
  specification_version: 4
262
264
  summary: Profiles loading speed for rack applications.