Skip to content

Commit

Permalink
ds: added support for monitoring ajax requests
Browse files Browse the repository at this point in the history
  • Loading branch information
dsboulder committed Feb 27, 2008
1 parent 79f884e commit 5ce90a6
Show file tree
Hide file tree
Showing 6 changed files with 390 additions and 329 deletions.
27 changes: 20 additions & 7 deletions lib/query_reviewer/controller_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,42 @@ def self.included(base)
base.helper_method :query_review_output
end

def query_review_output
def query_review_output(ajax = false)
if QueryReviewer::CONFIGURATION["enabled"]
faux_view = QueryViewBase.new([File.join(File.dirname(__FILE__), "views")], {}, self)
queries = SqlQueryCollection.new(Thread.current["queries"])
queries.analyze!
faux_view.instance_variable_set("@queries", queries)
html = faux_view.render(:partial => "/box")
if ajax
js = faux_view.render(:partial => "/box_ajax.js")
else
html = faux_view.render(:partial => "/box")
end
else
""
end
end

def add_query_output_to_view
if response.body.match(/<\/body>/i) && Thread.current["queries"]
idx = (response.body =~ /<\/body>/i)
html = query_review_output
response.body.insert(idx, html)
if request.xhr?
if !response.content_type || response.content_type.include?("text/html")
response.body += "<script type=\"text/javascript\">"+query_review_output(true)+"</script>"
elsif response.content_type && response.content_type.include?("text/javascript")
response.body += ";\n"+query_review_output(true)
end
else
if response.body.match(/<\/body>/i) && Thread.current["queries"]
idx = (response.body =~ /<\/body>/i)
html = query_review_output
response.body.insert(idx, html)
end
end
end

def perform_action_with_query_review
r = perform_action_without_query_review
if response.content_type.blank? || response.content_type == "text/html"
if QueryReviewer::CONFIGURATION["enabled"] &&
(response.content_type.blank? || response.content_type.include?("text/html") || response.content_type.include?("text/javascript"))
add_query_output_to_view
end
r
Expand Down
333 changes: 11 additions & 322 deletions lib/query_reviewer/views/_box.rhtml
Original file line number Diff line number Diff line change
@@ -1,322 +1,11 @@
<style>
#query_review {
position: absolute;
top: 1px;
left: 1px;
height: 18px;
margin: 1px;
opacity: 0.75;
padding-left: 3px;
padding-right: 3px;
border: 1px solid black;
font-size: 12px;
font-weight: bold;
}

#query_review.sql_ok {
background-color: #090;
color: #020;
}

#query_review.sql_warning {
background-color: #FAE100;
color: #F05000;
}

#query_review.sql_critical {
background-color: #F99;
color: #A00;
}

#query_review a {
color: inherit;
text-decoration: none;
}

#query_review_details {
position: absolute;
top: 21px;
left: 1px;
width: 900px;
height: 600px;
opacity: 0.9;
margin: 1px;
padding: 2px;
border: 1px solid black;
font-size: 12px;
overflow: auto;
background-color: #DDD;
}

#query_review_details p {
margin: 2px 0 2px 0;
padding: 0px;
}

#query_review_details a {
color: #29ABE2;
}

#query_review_details ul {
list-style-type: circle;
padding-left: 15px;
}

#query_review_details code {
white-space: normal;
line-height: 120%;
}

#query_review_details .title {
font-weight: bold;
}

#query_review_details .indent {
padding-left: 10px;
}

#query_review_details .number {
font-weight: bold;
}

#query_review_details .bad {
color: #900;
}

#query_review_details .good {
color: #090;
}

#query_review_details div.divider {
width: 504px;
position: relative;
left: -2px;
height: 1px;
border-top: 1px dashed black;
margin: 2px 0 2px 0;
}

#query_review_details .small {
font-size: 10px;
}

#query_review_details .tbpadded {
padding-top: 3px;
padding-bottom: 3px;
}

#query_review_details .trace {
background-color: #0C1021;
color: #7F908A;
padding: 5px;
margin-right: 30px;
}

#query_review_details .trace .bold {
color: white;
}

#query_review_details div.spectrum_container {
margin-top: 4px;
width: 35px;
display: block;
float: left;
position: relative;
height: 14px;
margin-right: 5px;
}

#query_review_details div.spectrum_elem {
width: 1px;
display: block;
float: left;
height: 10px;
}
#query_review_details div.spectrum_pointer {
width: 2px;
display: block;
float: left;
position: absolute;
height: 14px;
background-color: black;
top: -2px;
}

#query_review_details table {
background-color: white;
border: 1px solid gray;
padding: 0px;
margin: 0px;
}

#query_review_details tbody {
border: 0px;
padding: 0px;
margin: 0px;
}

#query_review_details thead {
border-bottom: 1px solid gray;
padding: 0px;
margin: 0px;
}


#query_review_details tr {
border: 0px;
padding: 0px;
margin: 0px;
}

#query_review_details td {
border: 0px;
padding: 0px;
margin: 0px;
overflow: hidden;
}

#query_review_details th {
border-bottom: 1px solid gray;
padding: 0px;
margin: 0px;
}

</style>

<style>
.sql {
color: black;
}
.sql .String {
color: #009933;
}
.sql .Keyword {
color: #0000FF;
}
.sql .Constant {
color: #6782D3;
}
.sql .Number {
color: #0066FF;
}
.sql .Comment {
color: #0066FF;
font-style: italic;
}
</style>

<script type="text/javascript">
//Super lame show/hide functions so we don't need any 3rd party JS libs
function query_review_show(id) {
document.getElementById(id).style.display = "block";
}

function query_review_hide(id) {
document.getElementById(id).style.display = "none";
}
function query_review_toggle(id) {
if(document.getElementById(id).style.display == "none") {
document.getElementById(id).style.display = "block";
} else {
document.getElementById(id).style.display = "none";
}
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}

function eraseCookie(name) {
createCookie(name,"",-1);
}

function ignore_list() {
var ignore_list = readCookie("query_review_ignore_list")
if (!ignore_list)
ignore_list = []
else
ignore_list = ignore_list.split(",")
return ignore_list
}

function add_ignore_hash(h){
var list = ignore_list();
list[list.length] = h
createCookie("query_review_ignore_list", list.join(","))
}

function remove_ignore_hash(h) {
var list = ignore_list();
var new_list = []
for(var i=0; i<list.length; i++)
{
if(list[i].toString() != h.toString()) {
new_list[new_list.length] = list[i]
}
}
createCookie("query_review_ignore_list", new_list.join(","))
}
</script>

<div id="query_review" class="<%= parent_div_class %>">
<a href="javascript: query_review_toggle('query_review_details')">SQL <%= parent_div_status %></a>
</div>
<div id="query_review_details" style="display: none;">
<p>Total queries: <span class="number"><%= @queries.queries.length %></span></p>
<p class="indent">With warnings: <span class="number bad"><%= @queries.total_with_warnings %></span> (<%= @queries.percent_with_warnings %>%)</p>
<p class="indent">Without warnings: <span class="number good"><%= @queries.total_without_warnings %></span> (<%= @queries.percent_without_warnings %>%)</p>
<% if warnings_no_query_sorted.length + queries_with_warnings_sorted.length > 0 %>
<div class="divider"></div>
<% if warnings_no_query_sorted_nonignored.length + queries_with_warnings_sorted_nonignored.length > 0 %>
<p class="title"><%= warnings_no_query_sorted_nonignored.length + queries_with_warnings_sorted_nonignored.length %> Warnings:</p>
<ul>
<%= render :partial => "/warning_no_query", :collection => warnings_no_query_sorted_nonignored %>
<%= render :partial => "/query_with_warning", :collection => queries_with_warnings_sorted_nonignored %>
</ul>
<% end %>
<% if warnings_no_query_sorted_ignored.length + queries_with_warnings_sorted_ignored.length > 0 %>
<%= warnings_no_query_sorted_ignored.length + queries_with_warnings_sorted_ignored.length %> <a class="title" href="javascript: query_review_toggle('query_review_ignored_warnings')">Ignored Warnings</a>:
<ul style="display: none;" id="query_review_ignored_warnings">
<%= render :partial => "/warning_no_query", :collection => warnings_no_query_sorted_ignored %>
<%= render :partial => "/query_with_warning", :collection => queries_with_warnings_sorted_ignored %>
</ul>
<% end %>
<% end %>
<div class="divider"></div>
<p class="title">Safe queries:</p>
<% if @queries.queries.empty? %>
No queries to display.
<% else %>
<ul class="small">
<% @queries.queries.reject{|q| q.has_warnings?}.each do |query| %>
<li>
<%= render :partial => "/query_sql", :object => query %>
<a href="javascript: query_review_toggle('warning_<%= query.id %>_explain')" title="show/hide sql">EXPLN</a>
<a href="javascript: query_review_toggle('warning_<%= query.id %>_trace')" title="show/hide stack trace">TRACE</a>
<div style="display: none" id="warning_<%= query.id %>_explain" class="indent small tbpadded">
<%= render :partial => "/explain", :locals => {:query => query} %>
</div>
<div style="display: none" id="warning_<%= query.id %>_trace" class="indent small">
<%= render :partial => "/trace", :object => query.relevant_trace, :locals => {:query_id => query.id, :full_trace => query.full_trace} %>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>
<div id="query_review_parent" class="query_review_parent">
<div id="query_review_0" class="query_review_container">
<%= render :partial => "/box_includes"%>
<div class="query_review <%= parent_div_class %>" id = "query_review_header_0">
<%= render :partial => "/box_header" %>
</div>
<div class="query_review_details" id="query_review_details_0" style="display: none;">
<%= render :partial => "/box_body" %>
</div>
</div>
</div>
Loading

0 comments on commit 5ce90a6

Please sign in to comment.