[bugzilla-gnome-org-extensions] Deal with the fact that traces come to us pre-wrapped.



commit 4aacc8c7f731992d756042c2ffae95c372e4d609
Author: Max Kanat-Alexander <mkanat everythingsolved com>
Date:   Wed Aug 5 02:24:22 2009 -0500

    Deal with the fact that traces come to us pre-wrapped.

 ...ug-linkify_comment.pl => bug-format_comment.pl} |    5 +--
 code/db_schema-abstract_schema.pl                  |   11 ++--
 lib/TraceParser/Hooks.pm                           |   53 +++++++++++++-------
 lib/TraceParser/Trace.pm                           |   53 +++++++++----------
 template/en/default/pages/trace.html.tmpl          |    2 +-
 5 files changed, 67 insertions(+), 57 deletions(-)
---
diff --git a/code/bug-linkify_comment.pl b/code/bug-format_comment.pl
similarity index 90%
rename from code/bug-linkify_comment.pl
rename to code/bug-format_comment.pl
index 1344659..3b03414 100644
--- a/code/bug-linkify_comment.pl
+++ b/code/bug-format_comment.pl
@@ -23,8 +23,5 @@
 use strict;
 use warnings;
 use Bugzilla;
-use Bugzilla::Error;
-use TraceParser::Trace;
 use TraceParser::Hooks;
-
-linkify_comment(%{ Bugzilla->hook_args });
+format_comment(%{ Bugzilla->hook_args });
diff --git a/code/db_schema-abstract_schema.pl b/code/db_schema-abstract_schema.pl
index 4646543..db7112a 100644
--- a/code/db_schema-abstract_schema.pl
+++ b/code/db_schema-abstract_schema.pl
@@ -29,21 +29,20 @@ $schema->{trace} = {
     FIELDS => [
         id          => {TYPE => 'MEDIUMSERIAL',  NOTNULL => 1, 
                         PRIMARYKEY => 1},
-        bug_id      => {TYPE => 'INT3', NOTNULL => 1, 
-                        REFERENCES => {TABLE  => 'bugs',
-                                       COLUMN => 'bug_id',
+        comment_id  => {TYPE => 'INT3', NOTNULL => 1, 
+                        REFERENCES => {TABLE  => 'longdescs',
+                                       COLUMN => 'comment_id',
                                        DELETE => 'CASCADE'}},
         type        => {TYPE => 'varchar(255)', NOTNULL => 1},
-        short_stack => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
         short_hash  => {TYPE => 'char(22)', NOTNULL => 1},
         stack_hash  => {TYPE => 'char(22)', NOTNULL => 1},
         trace_hash  => {TYPE => 'char(22)', NOTNULL => 1},
         trace_text  => {TYPE => 'LONGTEXT', NOTNULL => 1},
-        quality     => {TYPE => 'INT3', NOTNULL => 1},
+        quality     => {TYPE => 'real', NOTNULL => 1},
     ],
     INDEXES => [
         trace_short_hash_idx => ['short_hash'],
         trace_stack_hash_idx => ['stack_hash'],
-        trace_bug_id_idx => ['bug_id'],
+        trace_comment_id_idx => {TYPE => 'UNIQUE', FIELDS => ['comment_id']},
     ],
 };
diff --git a/lib/TraceParser/Hooks.pm b/lib/TraceParser/Hooks.pm
index 17a6f75..dd07e37 100644
--- a/lib/TraceParser/Hooks.pm
+++ b/lib/TraceParser/Hooks.pm
@@ -27,7 +27,7 @@ use TraceParser::Trace;
 
 our @EXPORT = qw(
     install_update_db
-    linkify_comment
+    format_comment
     page
 );
 
@@ -35,25 +35,26 @@ sub install_update_db {
     my $dbh = Bugzilla->dbh;
     my $has_traces = $dbh->selectrow_array('SELECT 1 FROM trace '
                                            . $dbh->sql_limit('1'));
-    return if !$has_traces;
+    return if $has_traces;
 
     print "Parsing traces from comments...\n";
-    my $total = $dbh->selectrow_array('SELECT COUNT(*) FROM longdescs');
+    my $total = 50000; #$dbh->selectrow_array('SELECT COUNT(*) FROM longdescs');
 
     if ($dbh->isa('Bugzilla::DB::Mysql')) {
         $dbh->{'mysql_use_result'} = 1;
     }
 
-    my $sth = $dbh->prepare('SELECT bug_id, thetext FROM longdescs');
+    my $sth = $dbh->prepare('SELECT comment_id, thetext FROM longdescs ORDER BY comment_id DESC LIMIT 
50000');
     $sth->execute();
-    my $count = 0;
+    my $count = 1;
     my @traces;
-    while (my ($bug_id, $text) = $sth->fetchrow_array) {
-        $count++;
-        my $trace = TraceParser::Trace->parse_from_text($text, $bug_id);
-        push(@traces, $trace) if $trace;
-        indicate_progress({ current => $count, total => $total,
+    while (my ($comment_id, $text) = $sth->fetchrow_array) {
+        my $trace = TraceParser::Trace->parse_from_text($text);
+        indicate_progress({ current => $count++, total => $total,
                             every => 100 });
+        next if !$trace;
+        $trace->{comment_id} = $comment_id;
+        push(@traces, $trace);
     }
 
     my $total_traces = scalar(@traces);
@@ -74,22 +75,38 @@ sub install_update_db {
     $dbh->bz_commit_transaction();
 }
 
-sub linkify_comment {
+sub format_comment {
     my %params = @_;
-    my ($text, $bug_id, $match, $replace) = @params{qw(text bug_id match replace)};
-    my $trace = TraceParser::Trace->new_from_text($$text, $bug_id);
+    my ($text, $bug, $regexes, $comment) = @params{qw(text bug regexes comment)};
+    return if !$comment;
+    my ($trace) = @{ TraceParser::Trace->match({ comment_id => $comment->{id} }) };
     return if !$trace;
-    my $template = Bugzilla->template_inner;
-    my $match_text = quotemeta($trace->text);
-    push(@$match, qr/$match_text/s);
+
+    # $$text contains the wrapped text, and $comment contains the unwrapped
+    # text. To find the trace that we want from the DB, we need to use the
+    # unwrapped text. But to find the text that we need to replace, we
+    # need to use the wrapped text.
+    my $match_text;
+    if ($comment->{already_wrapped}) {
+        $match_text = $trace->text;
+    }
+    else {
+        my $stacktrace = TraceParser::Trace->stacktrace_from_text($$text);
+        $trace->{stacktrace_object} = $stacktrace;
+        $match_text = $stacktrace->text;
+    }
+
+    $match_text = quotemeta($match_text);
     my $replacement;
+    my $template = Bugzilla->template_inner;
     $template->process('trace/format.html.tmpl', { trace => $trace },
                        \$replacement)
       || ThrowTemplateError($template->error);
-    push(@$replace, $replacement);
+    # Make sure that replacements don't contain $1, $2, etc.
+    $replacement =~ s{\$}{\\\$};
+    push(@$regexes, { match => qr/$match_text/s, replace => $replacement });
 }
 
-
 sub page {
     my %params = @_;
     my ($vars, $page) = @params{qw(vars page_id)};
diff --git a/lib/TraceParser/Trace.pm b/lib/TraceParser/Trace.pm
index af2b39f..3a910ac 100644
--- a/lib/TraceParser/Trace.pm
+++ b/lib/TraceParser/Trace.pm
@@ -36,9 +36,8 @@ use Digest::MD5 qw(md5_base64);
 
 use constant DB_COLUMNS => qw(
     id
-    bug_id
+    comment_id
     short_hash
-    short_stack
     stack_hash
     trace_hash
     trace_text
@@ -48,24 +47,24 @@ use constant DB_COLUMNS => qw(
 
 use constant DB_TABLE => 'trace';
 
-use constant LIST_ORDER => 'bug_id';
+use constant LIST_ORDER => 'comment_id';
 
 use constant VALIDATORS => {
     stack_hash  => \&_check_hash,
     short_hash  => \&_check_hash,
     trace_hash  => \&_check_hash,
-    short_stack => \&_check_short_stack,
     trace_text  => \&_check_thetext,
     type        => \&_check_type,
     quality     => \&_check_quality,
 };
 
 use constant REQUIRED_CREATE_FIELDS => qw(
-    type
-    trace_hash
-    stack_hash
+    comment_id
     short_hash
+    stack_hash
+    trace_hash
     trace_text
+    type
 );
 
 # This is how long a Base64 MD5 Hash is.
@@ -84,12 +83,16 @@ use constant IGNORE_FUNCTIONS => qw(
 # Constructors #
 ################
 
+sub stacktrace_from_text {
+    my ($class, $text) = @_;
+    return Parse::StackTrace->parse(types => TRACE_TYPES, text => $text);
+}
+
 # Returns a hash suitable for passing to create(), or undef if there is no
 # trace in the comment.
 sub parse_from_text {
     my ($class, $text) = @_;
-    my $trace = Parse::StackTrace->parse(types => TRACE_TYPES, 
-                                         text => $text);
+    my $trace = $class->stacktrace_from_text($text);
     return undef if !$trace;
 
     my @all_functions;
@@ -106,6 +109,8 @@ sub parse_from_text {
         }
     }
 
+    $quality = $quality / scalar(@{ $crash_thread->frames });
+
     my $max_short_stack = $#all_functions > 4 ? 4 : $#all_functions;
     my @short_stack = @all_functions[0..$max_short_stack];
     my $stack_hash = md5_base64(join(',', @all_functions));
@@ -116,7 +121,6 @@ sub parse_from_text {
     return {
         stack_hash  => $stack_hash,
         short_hash  => $short_hash,
-        short_stack => join(', ', @short_stack),
         trace_hash  => $trace_hash,
         trace_text  => $trace_text,
         type        => ref($trace),
@@ -124,33 +128,28 @@ sub parse_from_text {
     };
 }
 
-sub new_from_text {
-    my ($class, $text, $bug_id) = @_;
-    my $parsed = Parse::StackTrace->parse(types => TRACE_TYPES,
-                                          text => $text);
-    return undef if !$parsed;
-    my $hash = md5_base64($parsed->text);
-    my $traces = $class->match({ trace_hash => $hash, bug_id => $bug_id });
-    if (@$traces) {
-        $traces->[0]->{stacktrace_object} = $parsed;
-        return $traces->[0];
-    }
-    warn "No trace found on bug $bug_id with hash $hash";
-    return undef;
-}
-
 ###############################
 ####      Accessors      ######
 ###############################
 
+sub comment_id  { return $_[0]->{comment_id};  }
 sub full_hash   { return $_[0]->{full_hash};   }
 sub short_hash  { return $_[0]->{short_hash};  }
-sub short_stack { return $_[0]->{short_stack}; }
 sub trace_hash  { return $_[0]->{trace_hash};  }
 sub text        { return $_[0]->{trace_text};  }
 sub type        { return $_[0]->{type};        }
 sub quality     { return $_[0]->{quality};     }
 
+sub bug {
+    my $self = shift;
+    return $self->{bug} if exists $self->{bug};
+    my $bug_id = Bugzilla->dbh->selectrow_array(
+        'SELECT bug_id FROM longdescs WHERE comment_id = ?', undef, 
+        $self->comment_id);
+    $self->{bug} = new Bugzilla::Bug($bug_id);
+    return $self->{bug};
+}
+
 sub stacktrace_object {
     my $self = shift;
     my $type = $self->type;
@@ -172,8 +171,6 @@ sub _check_hash {
     return $hash;
 }
 
-sub _check_short_stack { return trim($_[1]) || '' }
-
 sub _check_thetext {
     my ($invocant, $text) = @_;
     if (!$text or $text =~ /^\s+$/s) {
diff --git a/template/en/default/pages/trace.html.tmpl b/template/en/default/pages/trace.html.tmpl
index 4b302be..68472c1 100644
--- a/template/en/default/pages/trace.html.tmpl
+++ b/template/en/default/pages/trace.html.tmpl
@@ -20,7 +20,7 @@
   #%]
 
 [% PROCESS global/header.html.tmpl
-   title = "Trace $trace.id From Bug $trace.bug_id" 
+   title = "Trace $trace.id From Bug $trace.bug.id" 
 %]
 
 <table border="0" cellpadding="0" cellspacing="0"><tr><td><div class="trace">


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]