diff options
author | Perl Tidy <perltidy@bugzilla.org> | 2018-12-05 21:38:52 +0100 |
---|---|---|
committer | Dylan William Hardison <dylan@hardison.net> | 2018-12-05 23:49:08 +0100 |
commit | 8ec8da0491ad89604700b3e29a227966f6d84ba1 (patch) | |
tree | 9d270f173330ca19700e0ba9f2ee931300646de1 /extensions/UserProfile | |
parent | a7bb5a65b71644d9efce5fed783ed545b9336548 (diff) | |
download | bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.gz bugzilla-8ec8da0491ad89604700b3e29a227966f6d84ba1.tar.xz |
no bug - reformat all the code using the new perltidy rules
Diffstat (limited to 'extensions/UserProfile')
-rw-r--r-- | extensions/UserProfile/Config.pm | 6 | ||||
-rw-r--r-- | extensions/UserProfile/Extension.pm | 796 | ||||
-rwxr-xr-x | extensions/UserProfile/bin/migrate.pl | 14 | ||||
-rwxr-xr-x | extensions/UserProfile/bin/update.pl | 62 | ||||
-rw-r--r-- | extensions/UserProfile/lib/Util.pm | 365 |
5 files changed, 582 insertions, 661 deletions
diff --git a/extensions/UserProfile/Config.pm b/extensions/UserProfile/Config.pm index 99fae1610..83b562163 100644 --- a/extensions/UserProfile/Config.pm +++ b/extensions/UserProfile/Config.pm @@ -11,8 +11,8 @@ use 5.10.1; use strict; use warnings; -use constant NAME => 'UserProfile'; -use constant REQUIRED_MODULES => [ ]; -use constant OPTIONAL_MODULES => [ ]; +use constant NAME => 'UserProfile'; +use constant REQUIRED_MODULES => []; +use constant OPTIONAL_MODULES => []; __PACKAGE__->NAME; diff --git a/extensions/UserProfile/Extension.pm b/extensions/UserProfile/Extension.pm index 9171b942d..cc8be3f1f 100644 --- a/extensions/UserProfile/Extension.pm +++ b/extensions/UserProfile/Extension.pm @@ -29,44 +29,43 @@ our $VERSION = '1'; # BEGIN { - *Bugzilla::User::last_activity_ts = \&_user_last_activity_ts; - *Bugzilla::User::set_last_activity_ts = \&_user_set_last_activity_ts; - *Bugzilla::User::last_statistics_ts = \&_user_last_statistics_ts; - *Bugzilla::User::clear_last_statistics_ts = \&_user_clear_last_statistics_ts; - *Bugzilla::User::address = \&_user_address; + *Bugzilla::User::last_activity_ts = \&_user_last_activity_ts; + *Bugzilla::User::set_last_activity_ts = \&_user_set_last_activity_ts; + *Bugzilla::User::last_statistics_ts = \&_user_last_statistics_ts; + *Bugzilla::User::clear_last_statistics_ts = \&_user_clear_last_statistics_ts; + *Bugzilla::User::address = \&_user_address; } -sub _user_last_activity_ts { $_[0]->{last_activity_ts} } -sub _user_last_statistics_ts { $_[0]->{last_statistics_ts} } +sub _user_last_activity_ts { $_[0]->{last_activity_ts} } +sub _user_last_statistics_ts { $_[0]->{last_statistics_ts} } + sub _user_address { - my $mode = Bugzilla->usage_mode; + my $mode = Bugzilla->usage_mode; - Email::Address->disable_cache if any { $mode == $_ } USAGE_MODE_CMDLINE, USAGE_MODE_TEST, USAGE_MODE_EMAIL; - return Email::Address->new(undef, $_[0]->email); + Email::Address->disable_cache + if any { $mode == $_ } USAGE_MODE_CMDLINE, USAGE_MODE_TEST, USAGE_MODE_EMAIL; + return Email::Address->new(undef, $_[0]->email); } -sub _user_set_last_activity_ts { - my ($self, $value) = @_; - $self->set('last_activity_ts', $_[1]); +sub _user_set_last_activity_ts { + my ($self, $value) = @_; + $self->set('last_activity_ts', $_[1]); - # we update the database directly to avoid audit_log entries - Bugzilla->dbh->do( - "UPDATE profiles SET last_activity_ts = ? WHERE userid = ?", - undef, - $value, $self->id); - Bugzilla->memcached->clear({ table => 'profiles', id => $self->id }); + # we update the database directly to avoid audit_log entries + Bugzilla->dbh->do("UPDATE profiles SET last_activity_ts = ? WHERE userid = ?", + undef, $value, $self->id); + Bugzilla->memcached->clear({table => 'profiles', id => $self->id}); } sub _user_clear_last_statistics_ts { - my ($self) = @_; - $self->set('last_statistics_ts', undef); - - # we update the database directly to avoid audit_log entries - Bugzilla->dbh->do( - "UPDATE profiles SET last_statistics_ts = NULL WHERE userid = ?", - undef, - $self->id); - Bugzilla->memcached->clear({ table => 'profiles', id => $self->id }); + my ($self) = @_; + $self->set('last_statistics_ts', undef); + + # we update the database directly to avoid audit_log entries + Bugzilla->dbh->do( + "UPDATE profiles SET last_statistics_ts = NULL WHERE userid = ?", + undef, $self->id); + Bugzilla->memcached->clear({table => 'profiles', id => $self->id}); } # @@ -76,327 +75,331 @@ sub _user_clear_last_statistics_ts { sub request_cleanup { Email::Address->purge_cache } sub bug_after_create { - my ($self, $args) = @_; - $self->_bug_touched($args); + my ($self, $args) = @_; + $self->_bug_touched($args); } sub bug_after_update { - my ($self, $args) = @_; - $self->_bug_touched($args); + my ($self, $args) = @_; + $self->_bug_touched($args); } sub _bug_touched { - my ($self, $args) = @_; - my $bug = $args->{bug}; - - my $user = Bugzilla->user; - my ($assigned_to, $qa_contact); - - # bug update - if (exists $args->{changes}) { - return unless - scalar(keys %{ $args->{changes} }) - || exists $args->{bug}->{added_comments}; - - # if the assignee or qa-contact is changed to someone other than the - # current user, update them - if (exists $args->{changes}->{assigned_to} - && $args->{changes}->{assigned_to}->[1] ne $user->login) - { - $assigned_to = $bug->assigned_to; - } - if (exists $args->{changes}->{qa_contact} - && ($args->{changes}->{qa_contact}->[1] || '') ne $user->login) - { - $qa_contact = $bug->qa_contact; - } - - # if the product is changed, we need to recount everyone involved with - # this bug - if (exists $args->{changes}->{product}) { - tag_for_recount_from_bug($bug->id); - } - + my ($self, $args) = @_; + my $bug = $args->{bug}; + + my $user = Bugzilla->user; + my ($assigned_to, $qa_contact); + + # bug update + if (exists $args->{changes}) { + return + unless scalar(keys %{$args->{changes}}) + || exists $args->{bug}->{added_comments}; + + # if the assignee or qa-contact is changed to someone other than the + # current user, update them + if (exists $args->{changes}->{assigned_to} + && $args->{changes}->{assigned_to}->[1] ne $user->login) + { + $assigned_to = $bug->assigned_to; } - # new bug - else { - # if the assignee or qa-contact is created set to someone other than - # the current user, update them - if ($bug->assigned_to->id != $user->id) { - $assigned_to = $bug->assigned_to; - } - if ($bug->qa_contact && $bug->qa_contact->id != $user->id) { - $qa_contact = $bug->qa_contact; - } + if (exists $args->{changes}->{qa_contact} + && ($args->{changes}->{qa_contact}->[1] || '') ne $user->login) + { + $qa_contact = $bug->qa_contact; } - my $dbh = Bugzilla->dbh; - $dbh->bz_start_transaction(); + # if the product is changed, we need to recount everyone involved with + # this bug + if (exists $args->{changes}->{product}) { + tag_for_recount_from_bug($bug->id); + } - # update user's last_activity_ts + } + + # new bug + else { + # if the assignee or qa-contact is created set to someone other than + # the current user, update them + if ($bug->assigned_to->id != $user->id) { + $assigned_to = $bug->assigned_to; + } + if ($bug->qa_contact && $bug->qa_contact->id != $user->id) { + $qa_contact = $bug->qa_contact; + } + } + + my $dbh = Bugzilla->dbh; + $dbh->bz_start_transaction(); + + # update user's last_activity_ts + eval { + $user->set_last_activity_ts($args->{timestamp}); + $self->_recalc_remove($user); + }; + if ($@) { + warn $@; + $self->_recalc_insert($user); + } + + # clear the last_statistics_ts for assignee/qa-contact to force a recount + # at the next poll + if ($assigned_to) { eval { - $user->set_last_activity_ts($args->{timestamp}); - $self->_recalc_remove($user); + $assigned_to->clear_last_statistics_ts(); + $self->_recalc_remove($assigned_to); }; if ($@) { - warn $@; - $self->_recalc_insert($user); + warn $@; + $self->_recalc_insert($assigned_to); } - - # clear the last_statistics_ts for assignee/qa-contact to force a recount - # at the next poll - if ($assigned_to) { - eval { - $assigned_to->clear_last_statistics_ts(); - $self->_recalc_remove($assigned_to); - }; - if ($@) { - warn $@; - $self->_recalc_insert($assigned_to); - } - } - if ($qa_contact) { - eval { - $qa_contact->clear_last_statistics_ts(); - $self->_recalc_remove($qa_contact); - }; - if ($@) { - warn $@; - $self->_recalc_insert($qa_contact); - } + } + if ($qa_contact) { + eval { + $qa_contact->clear_last_statistics_ts(); + $self->_recalc_remove($qa_contact); + }; + if ($@) { + warn $@; + $self->_recalc_insert($qa_contact); } + } - $dbh->bz_commit_transaction(); + $dbh->bz_commit_transaction(); } sub _recalc_insert { - my ($self, $user) = @_; - Bugzilla->dbh->do( - "INSERT IGNORE INTO profiles_statistics_recalc SET user_id=?", - undef, $user->id - ); + my ($self, $user) = @_; + Bugzilla->dbh->do("INSERT IGNORE INTO profiles_statistics_recalc SET user_id=?", + undef, $user->id); } sub _recalc_remove { - my ($self, $user) = @_; - Bugzilla->dbh->do( - "DELETE FROM profiles_statistics_recalc WHERE user_id=?", - undef, $user->id - ); + my ($self, $user) = @_; + Bugzilla->dbh->do("DELETE FROM profiles_statistics_recalc WHERE user_id=?", + undef, $user->id); } sub object_end_of_create { - my ($self, $args) = @_; - $self->_object_touched($args); + my ($self, $args) = @_; + $self->_object_touched($args); } sub object_end_of_update { - my ($self, $args) = @_; - $self->_object_touched($args); + my ($self, $args) = @_; + $self->_object_touched($args); } sub _object_touched { - my ($self, $args) = @_; - my $object = $args->{object} - or return; - return if exists $args->{changes} && !scalar(keys %{ $args->{changes} }); - - if ($object->isa('Bugzilla::Attachment')) { - # if an attachment is created or updated, that counts as user activity - my $user = Bugzilla->user; - my $timestamp = Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - eval { - $user->set_last_activity_ts($timestamp); - $self->_recalc_remove($user); - }; - if ($@) { - warn $@; - $self->_recalc_insert($user); - } - } - elsif ($object->isa('Bugzilla::Product') && exists $args->{changes}->{name}) { - # if a product is renamed by an admin, rename in the - # profiles_statistics_products table - Bugzilla->dbh->do( - "UPDATE profiles_statistics_products SET product=? where product=?", - undef, - $args->{changes}->{name}->[1], $args->{changes}->{name}->[0], - ); + my ($self, $args) = @_; + my $object = $args->{object} or return; + return if exists $args->{changes} && !scalar(keys %{$args->{changes}}); + + if ($object->isa('Bugzilla::Attachment')) { + + # if an attachment is created or updated, that counts as user activity + my $user = Bugzilla->user; + my $timestamp = Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); + eval { + $user->set_last_activity_ts($timestamp); + $self->_recalc_remove($user); + }; + if ($@) { + warn $@; + $self->_recalc_insert($user); } + } + elsif ($object->isa('Bugzilla::Product') && exists $args->{changes}->{name}) { + + # if a product is renamed by an admin, rename in the + # profiles_statistics_products table + Bugzilla->dbh->do( + "UPDATE profiles_statistics_products SET product=? where product=?", + undef, + $args->{changes}->{name}->[1], + $args->{changes}->{name}->[0], + ); + } } sub reorg_move_bugs { - my ($self, $args) = @_; - my $bug_ids = $args->{bug_ids}; - printf "Touching user profile data for %s bugs.\n", scalar(@$bug_ids); - my $count = 0; - foreach my $bug_id (@$bug_ids) { - $count += tag_for_recount_from_bug($bug_id); - } - print "Updated $count users.\n"; + my ($self, $args) = @_; + my $bug_ids = $args->{bug_ids}; + printf "Touching user profile data for %s bugs.\n", scalar(@$bug_ids); + my $count = 0; + foreach my $bug_id (@$bug_ids) { + $count += tag_for_recount_from_bug($bug_id); + } + print "Updated $count users.\n"; } sub merge_users_before { - my ($self, $args) = @_; - my ($old_id, $new_id) = @$args{qw(old_id new_id)}; - # when users are merged, we have to delete all the statistics for both users - # we'll recalcuate the stats after the merge - print "deleting user profile statistics for $old_id and $new_id\n"; - my $dbh = Bugzilla->dbh; - foreach my $table (qw( profiles_statistics profiles_statistics_status profiles_statistics_products )) { - $dbh->do("DELETE FROM $table WHERE " . $dbh->sql_in('user_id', [ $old_id, $new_id ])); - } + my ($self, $args) = @_; + my ($old_id, $new_id) = @$args{qw(old_id new_id)}; + + # when users are merged, we have to delete all the statistics for both users + # we'll recalcuate the stats after the merge + print "deleting user profile statistics for $old_id and $new_id\n"; + my $dbh = Bugzilla->dbh; + foreach my $table ( + qw( profiles_statistics profiles_statistics_status profiles_statistics_products ) + ) + { + $dbh->do( + "DELETE FROM $table WHERE " . $dbh->sql_in('user_id', [$old_id, $new_id])); + } } sub merge_users_after { - my ($self, $args) = @_; - my $new_id = $args->{new_id}; - print "generating user profile statistics $new_id\n"; - update_statistics_by_user($new_id); + my ($self, $args) = @_; + my $new_id = $args->{new_id}; + print "generating user profile statistics $new_id\n"; + update_statistics_by_user($new_id); } sub webservice_user_get { - my ($self, $args) = @_; - my ($service, $users) = @$args{qw(webservice users)}; - - my $dbh = Bugzilla->dbh; - my $ids = [ - map { blessed($_->{id}) ? $_->{id}->value : $_->{id} } - grep { exists $_->{id} } - @$users - ]; - return unless @$ids; - my $timestamps = $dbh->selectall_hashref( - "SELECT userid,last_activity_ts FROM profiles WHERE " . $dbh->sql_in('userid', $ids), - 'userid', - ); - foreach my $user (@$users) { - my $id = blessed($user->{id}) ? $user->{id}->value : $user->{id}; - $user->{last_activity} = $service->type('dateTime', $timestamps->{$id}->{last_activity_ts}); - } + my ($self, $args) = @_; + my ($service, $users) = @$args{qw(webservice users)}; + + my $dbh = Bugzilla->dbh; + my $ids = [map { blessed($_->{id}) ? $_->{id}->value : $_->{id} } + grep { exists $_->{id} } @$users]; + return unless @$ids; + my $timestamps = $dbh->selectall_hashref( + "SELECT userid,last_activity_ts FROM profiles WHERE " + . $dbh->sql_in('userid', $ids), + 'userid', + ); + foreach my $user (@$users) { + my $id = blessed($user->{id}) ? $user->{id}->value : $user->{id}; + $user->{last_activity} + = $service->type('dateTime', $timestamps->{$id}->{last_activity_ts}); + } } sub template_before_create { - my ($self, $args) = @_; - $args->{config}->{FILTERS}->{timeago} = sub { - my ($time_str) = @_; - return time_ago(datetime_from($time_str, 'UTC')); - }; + my ($self, $args) = @_; + $args->{config}->{FILTERS}->{timeago} = sub { + my ($time_str) = @_; + return time_ago(datetime_from($time_str, 'UTC')); + }; } sub page_before_template { - my ($self, $args) = @_; - my ($vars, $page) = @$args{qw(vars page_id)}; - return unless $page eq 'user_profile.html'; - my $user = Bugzilla->user; - - # determine user to display - my ($target, $login); - my $input = Bugzilla->input_params; - if (my $user_id = $input->{user_id}) { - # load from user_id - $user_id = 0 if $user_id =~ /\D/; - $target = Bugzilla::User->check({ id => $user_id }); - } else { - # loading from login name requires authentication - Bugzilla->login(LOGIN_REQUIRED); - $login = $input->{login}; - if (!$login) { - # show current user's profile by default - $target = $user; - } else { - my $limit = Bugzilla->params->{'maxusermatches'} + 1; - my $users = Bugzilla::User::match($login, $limit, 1); - if (scalar(@$users) == 1) { - # always allow singular matches without confirmation - $target = $users->[0]; - } else { - Bugzilla::User::match_field({ 'login' => {'type' => 'single'} }); - $target = Bugzilla::User->check($login); - } - } + my ($self, $args) = @_; + my ($vars, $page) = @$args{qw(vars page_id)}; + return unless $page eq 'user_profile.html'; + my $user = Bugzilla->user; + + # determine user to display + my ($target, $login); + my $input = Bugzilla->input_params; + if (my $user_id = $input->{user_id}) { + + # load from user_id + $user_id = 0 if $user_id =~ /\D/; + $target = Bugzilla::User->check({id => $user_id}); + } + else { + # loading from login name requires authentication + Bugzilla->login(LOGIN_REQUIRED); + $login = $input->{login}; + if (!$login) { + + # show current user's profile by default + $target = $user; + } + else { + my $limit = Bugzilla->params->{'maxusermatches'} + 1; + my $users = Bugzilla::User::match($login, $limit, 1); + if (scalar(@$users) == 1) { + + # always allow singular matches without confirmation + $target = $users->[0]; + } + else { + Bugzilla::User::match_field({'login' => {'type' => 'single'}}); + $target = Bugzilla::User->check($login); + } } - $login ||= $target->login; + } + $login ||= $target->login; - # load statistics into $vars - my $dbh = Bugzilla->switch_to_shadow_db; + # load statistics into $vars + my $dbh = Bugzilla->switch_to_shadow_db; - my $stats = $dbh->selectall_hashref( - "SELECT name, count + my $stats = $dbh->selectall_hashref( + "SELECT name, count FROM profiles_statistics - WHERE user_id = ?", - "name", - undef, - $target->id, - ); - map { $stats->{$_} = $stats->{$_}->{count} } keys %$stats; + WHERE user_id = ?", "name", undef, $target->id, + ); + map { $stats->{$_} = $stats->{$_}->{count} } keys %$stats; - my $statuses = $dbh->selectall_hashref( - "SELECT status, count + my $statuses = $dbh->selectall_hashref( + "SELECT status, count FROM profiles_statistics_status - WHERE user_id = ?", - "status", - undef, - $target->id, - ); - map { $statuses->{$_} = $statuses->{$_}->{count} } keys %$statuses; + WHERE user_id = ?", "status", undef, $target->id, + ); + map { $statuses->{$_} = $statuses->{$_}->{count} } keys %$statuses; - my $products = $dbh->selectall_arrayref( - "SELECT product, count + my $products = $dbh->selectall_arrayref( + "SELECT product, count FROM profiles_statistics_products WHERE user_id = ? - ORDER BY product = '', count DESC", - { Slice => {} }, - $target->id, - ); - - # ensure there's always an "other" product entry - my ($other_product) = grep { $_->{product} eq '' } @$products; - if (!$other_product) { - $other_product = { product => '', count => 0 }; - push @$products, $other_product; + ORDER BY product = '', count DESC", {Slice => {}}, $target->id, + ); + + # ensure there's always an "other" product entry + my ($other_product) = grep { $_->{product} eq '' } @$products; + if (!$other_product) { + $other_product = {product => '', count => 0}; + push @$products, $other_product; + } + + # load product objects and validate product visibility + foreach my $product (@$products) { + next if $product->{product} eq ''; + my $product_obj = Bugzilla::Product->new({name => $product->{product}}); + if (!$product_obj || !$user->can_see_product($product_obj->name)) { + + # products not accessible to current user are moved into "other" + $other_product->{count} += $product->{count}; + $product->{count} = 0; } - - # load product objects and validate product visibility - foreach my $product (@$products) { - next if $product->{product} eq ''; - my $product_obj = Bugzilla::Product->new({ name => $product->{product} }); - if (!$product_obj || !$user->can_see_product($product_obj->name)) { - # products not accessible to current user are moved into "other" - $other_product->{count} += $product->{count}; - $product->{count} = 0; - } else { - $product->{product} = $product_obj; - } + else { + $product->{product} = $product_obj; } + } - # set other's name, and remove empty products - $other_product->{product} = { name => 'Other' }; - $products = [ grep { $_->{count} } @$products ]; + # set other's name, and remove empty products + $other_product->{product} = {name => 'Other'}; + $products = [grep { $_->{count} } @$products]; - $vars->{stats} = $stats; - $vars->{statuses} = $statuses; - $vars->{products} = $products; - $vars->{login} = $login; - $vars->{target} = $target; + $vars->{stats} = $stats; + $vars->{statuses} = $statuses; + $vars->{products} = $products; + $vars->{login} = $login; + $vars->{target} = $target; } sub object_columns { - my ($self, $args) = @_; - my ($class, $columns) = @$args{qw(class columns)}; - if ($class->isa('Bugzilla::User')) { - my $dbh = Bugzilla->dbh; - my @new_columns = qw(last_activity_ts last_statistics_ts); - push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; - } + my ($self, $args) = @_; + my ($class, $columns) = @$args{qw(class columns)}; + if ($class->isa('Bugzilla::User')) { + my $dbh = Bugzilla->dbh; + my @new_columns = qw(last_activity_ts last_statistics_ts); + push @$columns, + grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; + } } sub object_update_columns { - my ($self, $args) = @_; - my ($object, $columns) = @$args{qw(object columns)}; - if ($object->isa('Bugzilla::User')) { - push(@$columns, qw(last_activity_ts last_statistics_ts)); - } + my ($self, $args) = @_; + my ($object, $columns) = @$args{qw(object columns)}; + if ($object->isa('Bugzilla::User')) { + push(@$columns, qw(last_activity_ts last_statistics_ts)); + } } # @@ -404,161 +407,96 @@ sub object_update_columns { # sub db_schema_abstract_schema { - my ($self, $args) = @_; - $args->{'schema'}->{'profiles_statistics'} = { - FIELDS => [ - id => { - TYPE => 'MEDIUMSERIAL', - NOTNULL => 1, - PRIMARYKEY => 1, - }, - user_id => { - TYPE => 'INT3', - NOTNULL => 1, - REFERENCES => { - TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE', - } - }, - name => { - TYPE => 'VARCHAR(30)', - NOTNULL => 1, - }, - count => { - TYPE => 'INT', - NOTNULL => 1, - }, - ], - INDEXES => [ - profiles_statistics_name_idx => { - FIELDS => [ 'user_id', 'name' ], - TYPE => 'UNIQUE', - }, - ], - }; - $args->{'schema'}->{'profiles_statistics_status'} = { - FIELDS => [ - id => { - TYPE => 'MEDIUMSERIAL', - NOTNULL => 1, - PRIMARYKEY => 1, - }, - user_id => { - TYPE => 'INT3', - NOTNULL => 1, - REFERENCES => { - TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE', - } - }, - status => { - TYPE => 'VARCHAR(64)', - NOTNULL => 1, - }, - count => { - TYPE => 'INT', - NOTNULL => 1, - }, - ], - INDEXES => [ - profiles_statistics_status_idx => { - FIELDS => [ 'user_id', 'status' ], - TYPE => 'UNIQUE', - }, - ], - }; - $args->{'schema'}->{'profiles_statistics_products'} = { - FIELDS => [ - id => { - TYPE => 'MEDIUMSERIAL', - NOTNULL => 1, - PRIMARYKEY => 1, - }, - user_id => { - TYPE => 'INT3', - NOTNULL => 1, - REFERENCES => { - TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE', - } - }, - product => { - TYPE => 'VARCHAR(64)', - NOTNULL => 1, - }, - count => { - TYPE => 'INT', - NOTNULL => 1, - }, - ], - INDEXES => [ - profiles_statistics_products_idx => { - FIELDS => [ 'user_id', 'product' ], - TYPE => 'UNIQUE', - }, - ], - }; - $args->{'schema'}->{'profiles_statistics_recalc'} = { - FIELDS => [ - user_id => { - TYPE => 'INT3', - NOTNULL => 1, - REFERENCES => { - TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE', - } - }, - ], - INDEXES => [ - profiles_statistics_recalc_idx => { - FIELDS => [ 'user_id' ], - TYPE => 'UNIQUE', - }, - ], - }; - $args->{'schema'}->{'profiles_statistics_recalc'} = { - FIELDS => [ - user_id => { - TYPE => 'INT3', - NOTNULL => 1, - REFERENCES => { - TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE', - } - }, - ], - INDEXES => [ - profiles_statistics_recalc_idx => { - FIELDS => [ 'user_id' ], - TYPE => 'UNIQUE', - }, - ], - }; + my ($self, $args) = @_; + $args->{'schema'}->{'profiles_statistics'} = { + FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,}, + user_id => { + TYPE => 'INT3', + NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',} + }, + name => {TYPE => 'VARCHAR(30)', NOTNULL => 1,}, + count => {TYPE => 'INT', NOTNULL => 1,}, + ], + INDEXES => [ + profiles_statistics_name_idx => + {FIELDS => ['user_id', 'name'], TYPE => 'UNIQUE',}, + ], + }; + $args->{'schema'}->{'profiles_statistics_status'} = { + FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,}, + user_id => { + TYPE => 'INT3', + NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',} + }, + status => {TYPE => 'VARCHAR(64)', NOTNULL => 1,}, + count => {TYPE => 'INT', NOTNULL => 1,}, + ], + INDEXES => [ + profiles_statistics_status_idx => + {FIELDS => ['user_id', 'status'], TYPE => 'UNIQUE',}, + ], + }; + $args->{'schema'}->{'profiles_statistics_products'} = { + FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1,}, + user_id => { + TYPE => 'INT3', + NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',} + }, + product => {TYPE => 'VARCHAR(64)', NOTNULL => 1,}, + count => {TYPE => 'INT', NOTNULL => 1,}, + ], + INDEXES => [ + profiles_statistics_products_idx => + {FIELDS => ['user_id', 'product'], TYPE => 'UNIQUE',}, + ], + }; + $args->{'schema'}->{'profiles_statistics_recalc'} = { + FIELDS => [ + user_id => { + TYPE => 'INT3', + NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',} + }, + ], + INDEXES => [ + profiles_statistics_recalc_idx => {FIELDS => ['user_id'], TYPE => 'UNIQUE',}, + ], + }; + $args->{'schema'}->{'profiles_statistics_recalc'} = { + FIELDS => [ + user_id => { + TYPE => 'INT3', + NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', COLUMN => 'userid', DELETE => 'CASCADE',} + }, + ], + INDEXES => [ + profiles_statistics_recalc_idx => {FIELDS => ['user_id'], TYPE => 'UNIQUE',}, + ], + }; } sub install_update_db { - my $dbh = Bugzilla->dbh; - $dbh->bz_add_column('profiles', 'last_activity_ts', { TYPE => 'DATETIME' }); - $dbh->bz_add_column('profiles', 'last_statistics_ts', { TYPE => 'DATETIME' }); + my $dbh = Bugzilla->dbh; + $dbh->bz_add_column('profiles', 'last_activity_ts', {TYPE => 'DATETIME'}); + $dbh->bz_add_column('profiles', 'last_statistics_ts', {TYPE => 'DATETIME'}); } sub install_filesystem { - my ($self, $args) = @_; - my $files = $args->{'files'}; - my $extensions_dir = bz_locations()->{'extensionsdir'}; - my $script_name = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/update.pl"; - $files->{$script_name} = { - perms => Bugzilla::Install::Filesystem::WS_EXECUTE - }; - $script_name = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/migrate.pl"; - $files->{$script_name} = { - perms => Bugzilla::Install::Filesystem::OWNER_EXECUTE - }; + my ($self, $args) = @_; + my $files = $args->{'files'}; + my $extensions_dir = bz_locations()->{'extensionsdir'}; + my $script_name = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/update.pl"; + $files->{$script_name} = {perms => Bugzilla::Install::Filesystem::WS_EXECUTE}; + $script_name = $extensions_dir . "/" . __PACKAGE__->NAME . "/bin/migrate.pl"; + $files->{$script_name} + = {perms => Bugzilla::Install::Filesystem::OWNER_EXECUTE}; } __PACKAGE__->NAME; diff --git a/extensions/UserProfile/bin/migrate.pl b/extensions/UserProfile/bin/migrate.pl index dd257f6bd..08c9f54f4 100755 --- a/extensions/UserProfile/bin/migrate.pl +++ b/extensions/UserProfile/bin/migrate.pl @@ -26,7 +26,7 @@ Bugzilla->usage_mode(USAGE_MODE_CMDLINE); my $dbh = Bugzilla->dbh; my $user_ids = $dbh->selectcol_arrayref( - "SELECT userid + "SELECT userid FROM profiles WHERE last_activity_ts IS NULL ORDER BY userid" @@ -34,11 +34,9 @@ my $user_ids = $dbh->selectcol_arrayref( my ($current, $total) = (1, scalar(@$user_ids)); foreach my $user_id (@$user_ids) { - indicate_progress({ current => $current++, total => $total, every => 25 }); - my $ts = last_user_activity($user_id); - next unless $ts; - $dbh->do( - "UPDATE profiles SET last_activity_ts = ? WHERE userid = ?", - undef, - $ts, $user_id); + indicate_progress({current => $current++, total => $total, every => 25}); + my $ts = last_user_activity($user_id); + next unless $ts; + $dbh->do("UPDATE profiles SET last_activity_ts = ? WHERE userid = ?", + undef, $ts, $user_id); } diff --git a/extensions/UserProfile/bin/update.pl b/extensions/UserProfile/bin/update.pl index 4d704a1f0..bdbcef329 100755 --- a/extensions/UserProfile/bin/update.pl +++ b/extensions/UserProfile/bin/update.pl @@ -26,56 +26,50 @@ my $user_ids; my $verbose = grep { $_ eq '-v' } @ARGV; $user_ids = $dbh->selectcol_arrayref( - "SELECT user_id + "SELECT user_id FROM profiles_statistics_recalc - ORDER BY user_id", - { Slice => {} } + ORDER BY user_id", {Slice => {}} ); if (@$user_ids) { - print "recalculating last_user_activity\n"; - my ($count, $total) = (0, scalar(@$user_ids)); - foreach my $user_id (@$user_ids) { - if ($verbose) { - $count++; - my $login = user_id_to_login($user_id); - print "$count/$total $login ($user_id)\n"; - } - $dbh->do( - "UPDATE profiles - SET last_activity_ts = ?, - last_statistics_ts = NULL - WHERE userid = ?", - undef, - last_user_activity($user_id), - $user_id - ); - Bugzilla->memcached->clear({ table => 'profiles', id => $user_id }); + print "recalculating last_user_activity\n"; + my ($count, $total) = (0, scalar(@$user_ids)); + foreach my $user_id (@$user_ids) { + if ($verbose) { + $count++; + my $login = user_id_to_login($user_id); + print "$count/$total $login ($user_id)\n"; } $dbh->do( - "DELETE FROM profiles_statistics_recalc WHERE " . $dbh->sql_in('user_id', $user_ids) + "UPDATE profiles + SET last_activity_ts = ?, + last_statistics_ts = NULL + WHERE userid = ?", undef, last_user_activity($user_id), $user_id ); + Bugzilla->memcached->clear({table => 'profiles', id => $user_id}); + } + $dbh->do("DELETE FROM profiles_statistics_recalc WHERE " + . $dbh->sql_in('user_id', $user_ids)); } $user_ids = $dbh->selectcol_arrayref( - "SELECT userid + "SELECT userid FROM profiles WHERE last_activity_ts IS NOT NULL AND (last_statistics_ts IS NULL OR last_activity_ts > last_statistics_ts) - ORDER BY userid", - { Slice => {} } + ORDER BY userid", {Slice => {}} ); if (@$user_ids) { - $verbose && print "updating statistics\n"; - my ($count, $total) = (0, scalar(@$user_ids)); - foreach my $user_id (@$user_ids) { - if ($verbose) { - $count++; - my $login = user_id_to_login($user_id); - print "$count/$total $login ($user_id)\n"; - } - update_statistics_by_user($user_id); + $verbose && print "updating statistics\n"; + my ($count, $total) = (0, scalar(@$user_ids)); + foreach my $user_id (@$user_ids) { + if ($verbose) { + $count++; + my $login = user_id_to_login($user_id); + print "$count/$total $login ($user_id)\n"; } + update_statistics_by_user($user_id); + } } diff --git a/extensions/UserProfile/lib/Util.pm b/extensions/UserProfile/lib/Util.pm index 6b2eff098..54a9c2eea 100644 --- a/extensions/UserProfile/lib/Util.pm +++ b/extensions/UserProfile/lib/Util.pm @@ -13,44 +13,45 @@ use warnings; use base qw(Exporter); our @EXPORT = qw( update_statistics_by_user - tag_for_recount_from_bug - last_user_activity ); + tag_for_recount_from_bug + last_user_activity ); use Bugzilla; sub update_statistics_by_user { - my ($user_id) = @_; + my ($user_id) = @_; - # run all our queries on the slaves + # run all our queries on the slaves - my $dbh = Bugzilla->switch_to_shadow_db(); + my $dbh = Bugzilla->switch_to_shadow_db(); - my $now = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); + my $now = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - # grab the current values + # grab the current values - my $last_statistics_ts = _get_last_statistics_ts($user_id); + my $last_statistics_ts = _get_last_statistics_ts($user_id); - my $statistics = _get_stats($user_id, 'profiles_statistics', 'name'); - my $by_status = _get_stats($user_id, 'profiles_statistics_status', 'status'); - my $by_product = _get_stats($user_id, 'profiles_statistics_products', 'product'); + my $statistics = _get_stats($user_id, 'profiles_statistics', 'name'); + my $by_status = _get_stats($user_id, 'profiles_statistics_status', 'status'); + my $by_product + = _get_stats($user_id, 'profiles_statistics_products', 'product'); - # bugs filed - _update_statistics($statistics, 'bugs_filed', [ $user_id ], <<EOF); + # bugs filed + _update_statistics($statistics, 'bugs_filed', [$user_id], <<EOF); SELECT COUNT(*) FROM bugs WHERE bugs.reporter = ? EOF - # comments made - _update_statistics($statistics, 'comments', [ $user_id ], <<EOF); + # comments made + _update_statistics($statistics, 'comments', [$user_id], <<EOF); SELECT COUNT(*) FROM longdescs WHERE who = ? EOF - # commented on - _update_statistics($statistics, 'commented_on', [ $user_id ], <<EOF); + # commented on + _update_statistics($statistics, 'commented_on', [$user_id], <<EOF); SELECT COUNT(*) FROM ( SELECT longdescs.bug_id FROM longdescs @@ -59,8 +60,9 @@ EOF ) AS temp EOF - # confirmed - _update_statistics($statistics, 'confirmed', [ $user_id, _field_id('bug_status') ], <<EOF); + # confirmed + _update_statistics($statistics, 'confirmed', + [$user_id, _field_id('bug_status')], <<EOF); SELECT COUNT(*) FROM bugs_activity WHERE who = ? @@ -69,8 +71,8 @@ EOF AND added = 'NEW' EOF - # patches submitted - _update_statistics($statistics, 'patches', [ $user_id ], <<EOF); + # patches submitted + _update_statistics($statistics, 'patches', [$user_id], <<EOF); SELECT COUNT(*) FROM attachments WHERE submitter_id = ? @@ -80,8 +82,8 @@ EOF 'text/x-phabricator-request')) EOF - # patches reviewed - _update_statistics($statistics, 'reviews', [ $user_id ], <<EOF); + # patches reviewed + _update_statistics($statistics, 'reviews', [$user_id], <<EOF); SELECT COUNT(*) FROM flags INNER JOIN attachments ON attachments.attach_id = flags.attach_id @@ -93,22 +95,22 @@ EOF AND status IN ('+', '-') EOF - # assigned to - _update_statistics($statistics, 'assigned', [ $user_id ], <<EOF); + # assigned to + _update_statistics($statistics, 'assigned', [$user_id], <<EOF); SELECT COUNT(*) FROM bugs WHERE assigned_to = ? EOF - # qa contact - _update_statistics($statistics, 'qa_contact', [ $user_id ], <<EOF); + # qa contact + _update_statistics($statistics, 'qa_contact', [$user_id], <<EOF); SELECT COUNT(*) FROM bugs WHERE qa_contact = ? EOF - # bugs touched - _update_statistics($statistics, 'touched', [ $user_id, $user_id], <<EOF); + # bugs touched + _update_statistics($statistics, 'touched', [$user_id, $user_id], <<EOF); SELECT COUNT(*) FROM ( SELECT bugs_activity.bug_id FROM bugs_activity @@ -122,42 +124,45 @@ EOF ) temp EOF - # activity by status/resolution, and product - _activity_by_status($by_status, $user_id); - _activity_by_product($by_product, $user_id); + # activity by status/resolution, and product + _activity_by_status($by_status, $user_id); + _activity_by_product($by_product, $user_id); - # if nothing is dirty, no need to do anything else - if ($last_statistics_ts) { - return unless _has_dirty($statistics) - || _has_dirty($by_status) - || _has_dirty($by_product); - } + # if nothing is dirty, no need to do anything else + if ($last_statistics_ts) { + return + unless _has_dirty($statistics) + || _has_dirty($by_status) + || _has_dirty($by_product); + } - # switch back to the main db for updating + # switch back to the main db for updating - $dbh = Bugzilla->switch_to_main_db(); - $dbh->bz_start_transaction(); + $dbh = Bugzilla->switch_to_main_db(); + $dbh->bz_start_transaction(); - # commit updated statistics + # commit updated statistics - _set_stats($statistics, $user_id, 'profiles_statistics', 'name') - if _has_dirty($statistics); - _set_stats($by_status, $user_id, 'profiles_statistics_status', 'status') - if _has_dirty($by_status); - _set_stats($by_product, $user_id, 'profiles_statistics_products', 'product') - if _has_dirty($by_product); + _set_stats($statistics, $user_id, 'profiles_statistics', 'name') + if _has_dirty($statistics); + _set_stats($by_status, $user_id, 'profiles_statistics_status', 'status') + if _has_dirty($by_status); + _set_stats($by_product, $user_id, 'profiles_statistics_products', 'product') + if _has_dirty($by_product); - # update the user's last_statistics_ts - _set_last_statistics_ts($user_id, $now); + # update the user's last_statistics_ts + _set_last_statistics_ts($user_id, $now); - $dbh->bz_commit_transaction(); + $dbh->bz_commit_transaction(); } sub tag_for_recount_from_bug { - my ($bug_id) = @_; - my $dbh = Bugzilla->dbh; - # get a list of all users associated with this bug - my $user_ids = $dbh->selectcol_arrayref(<<EOF, undef, $bug_id, _field_id('cc'), $bug_id); + my ($bug_id) = @_; + my $dbh = Bugzilla->dbh; + + # get a list of all users associated with this bug + my $user_ids + = $dbh->selectcol_arrayref(<<EOF, undef, $bug_id, _field_id('cc'), $bug_id); SELECT DISTINCT user_id FROM ( SELECT DISTINCT who AS user_id @@ -170,20 +175,22 @@ sub tag_for_recount_from_bug { WHERE bug_id = ? ) tmp EOF - # clear last_statistics_ts - $dbh->do( - "UPDATE profiles SET last_statistics_ts=NULL WHERE " . $dbh->sql_in('userid', $user_ids) - ); - foreach my $id (@$user_ids) { - Bugzilla->memcached->clear({ table => 'profiles', id => $id }); - } - return scalar(@$user_ids); + + # clear last_statistics_ts + $dbh->do("UPDATE profiles SET last_statistics_ts=NULL WHERE " + . $dbh->sql_in('userid', $user_ids)); + foreach my $id (@$user_ids) { + Bugzilla->memcached->clear({table => 'profiles', id => $id}); + } + return scalar(@$user_ids); } sub last_user_activity { - # last comment, or change to a bug (excluding CC changes) - my ($user_id) = @_; - return Bugzilla->dbh->selectrow_array(<<EOF, undef, $user_id, $user_id, _field_id('cc')); + + # last comment, or change to a bug (excluding CC changes) + my ($user_id) = @_; + return Bugzilla->dbh->selectrow_array( + <<EOF, undef, $user_id, $user_id, _field_id('cc')); SELECT MAX(bug_when) FROM ( SELECT MAX(bug_when) AS bug_when @@ -201,45 +208,39 @@ EOF # for performance reasons hit the db directly rather than using the user object sub _get_last_statistics_ts { - my ($user_id) = @_; - return Bugzilla->dbh->selectrow_array( - "SELECT last_statistics_ts FROM profiles WHERE userid = ?", - undef, $user_id - ); + my ($user_id) = @_; + return Bugzilla->dbh->selectrow_array( + "SELECT last_statistics_ts FROM profiles WHERE userid = ?", + undef, $user_id); } sub _set_last_statistics_ts { - my ($user_id, $timestamp) = @_; - Bugzilla->dbh->do( - "UPDATE profiles SET last_statistics_ts = ? WHERE userid = ?", - undef, - $timestamp, $user_id, - ); - Bugzilla->memcached->clear({ table => 'profiles', id => $user_id }); + my ($user_id, $timestamp) = @_; + Bugzilla->dbh->do("UPDATE profiles SET last_statistics_ts = ? WHERE userid = ?", + undef, $timestamp, $user_id,); + Bugzilla->memcached->clear({table => 'profiles', id => $user_id}); } sub _update_statistics { - my ($statistics, $name, $values, $sql) = @_; - my ($count) = Bugzilla->dbh->selectrow_array($sql, undef, @$values); - if (!exists $statistics->{$name}) { - $statistics->{$name} = { - id => 0, - count => $count, - dirty => 1, - }; - } elsif ($statistics->{$name}->{count} != $count) { - $statistics->{$name}->{count} = $count; - $statistics->{$name}->{dirty} = 1; - }; + my ($statistics, $name, $values, $sql) = @_; + my ($count) = Bugzilla->dbh->selectrow_array($sql, undef, @$values); + if (!exists $statistics->{$name}) { + $statistics->{$name} = {id => 0, count => $count, dirty => 1,}; + } + elsif ($statistics->{$name}->{count} != $count) { + $statistics->{$name}->{count} = $count; + $statistics->{$name}->{dirty} = 1; + } } sub _activity_by_status { - my ($by_status, $user_id) = @_; - my $dbh = Bugzilla->dbh; + my ($by_status, $user_id) = @_; + my $dbh = Bugzilla->dbh; - # we actually track both status and resolution changes as statuses - my @values = ($user_id, _field_id('bug_status'), $user_id, _field_id('resolution')); - my $rows = $dbh->selectall_arrayref(<<EOF, { Slice => {} }, @values); + # we actually track both status and resolution changes as statuses + my @values + = ($user_id, _field_id('bug_status'), $user_id, _field_id('resolution')); + my $rows = $dbh->selectall_arrayref(<<EOF, {Slice => {}}, @values); SELECT added AS status, COUNT(*) AS count FROM bugs_activity WHERE who = ? @@ -254,29 +255,26 @@ sub _activity_by_status { GROUP BY added EOF - foreach my $row (@$rows) { - my $status = $row->{status}; - if (!exists $by_status->{$status}) { - $by_status->{$status} = { - id => 0, - count => $row->{count}, - dirty => 1, - }; - } elsif ($by_status->{$status}->{count} != $row->{count}) { - $by_status->{$status}->{count} = $row->{count}; - $by_status->{$status}->{dirty} = 1; - } + foreach my $row (@$rows) { + my $status = $row->{status}; + if (!exists $by_status->{$status}) { + $by_status->{$status} = {id => 0, count => $row->{count}, dirty => 1,}; + } + elsif ($by_status->{$status}->{count} != $row->{count}) { + $by_status->{$status}->{count} = $row->{count}; + $by_status->{$status}->{dirty} = 1; } + } } sub _activity_by_product { - my ($by_product, $user_id) = @_; - my $dbh = Bugzilla->dbh; + my ($by_product, $user_id) = @_; + my $dbh = Bugzilla->dbh; - my %products; + my %products; - # changes - my $rows = $dbh->selectall_arrayref(<<EOF, { Slice => {} }, $user_id); + # changes + my $rows = $dbh->selectall_arrayref(<<EOF, {Slice => {}}, $user_id); SELECT products.name AS product, count(*) AS count FROM bugs_activity INNER JOIN bugs ON bugs.bug_id = bugs_activity.bug_id @@ -284,10 +282,10 @@ sub _activity_by_product { WHERE who = ? GROUP BY bugs.product_id EOF - map { $products{$_->{product}} += $_->{count} } @$rows; + map { $products{$_->{product}} += $_->{count} } @$rows; - # comments - $rows = $dbh->selectall_arrayref(<<EOF, { Slice => {} }, $user_id); + # comments + $rows = $dbh->selectall_arrayref(<<EOF, {Slice => {}}, $user_id); SELECT products.name AS product, count(*) AS count FROM longdescs INNER JOIN bugs ON bugs.bug_id = longdescs.bug_id @@ -295,96 +293,89 @@ EOF WHERE who = ? GROUP BY bugs.product_id EOF - map { $products{$_->{product}} += $_->{count} } @$rows; - - # store only the top 10 and 'other' (which is an empty string) - my @sorted = sort { $products{$b} <=> $products{$a} } keys %products; - my @other; - @other = splice(@sorted, 10) if scalar(@sorted) > 10; - map { $products{''} += $products{$_} } @other; - push @sorted, '' if $products{''}; - - # update by_product - foreach my $product (@sorted) { - if (!exists $by_product->{$product}) { - $by_product->{$product} = { - id => 0, - count => $products{$product}, - dirty => 1, - }; - } elsif ($by_product->{$product}->{count} != $products{$product}) { - $by_product->{$product}->{count} = $products{$product}; - $by_product->{$product}->{dirty} = 1; - } + map { $products{$_->{product}} += $_->{count} } @$rows; + + # store only the top 10 and 'other' (which is an empty string) + my @sorted = sort { $products{$b} <=> $products{$a} } keys %products; + my @other; + @other = splice(@sorted, 10) if scalar(@sorted) > 10; + map { $products{''} += $products{$_} } @other; + push @sorted, '' if $products{''}; + + # update by_product + foreach my $product (@sorted) { + if (!exists $by_product->{$product}) { + $by_product->{$product} = {id => 0, count => $products{$product}, dirty => 1,}; } - foreach my $product (keys %$by_product) { - if (!grep { $_ eq $product } @sorted) { - delete $by_product->{$product}; - } + elsif ($by_product->{$product}->{count} != $products{$product}) { + $by_product->{$product}->{count} = $products{$product}; + $by_product->{$product}->{dirty} = 1; } + } + foreach my $product (keys %$by_product) { + if (!grep { $_ eq $product } @sorted) { + delete $by_product->{$product}; + } + } } our $_field_id_cache; + sub _field_id { - my ($name) = @_; - if (!$_field_id_cache) { - my $rows = Bugzilla->dbh->selectall_arrayref("SELECT id, name FROM fielddefs"); - foreach my $row (@$rows) { - $_field_id_cache->{$row->[1]} = $row->[0]; - } + my ($name) = @_; + if (!$_field_id_cache) { + my $rows = Bugzilla->dbh->selectall_arrayref("SELECT id, name FROM fielddefs"); + foreach my $row (@$rows) { + $_field_id_cache->{$row->[1]} = $row->[0]; } - return $_field_id_cache->{$name}; + } + return $_field_id_cache->{$name}; } sub _get_stats { - my ($user_id, $table, $name_field) = @_; - my $result = {}; - my $rows = Bugzilla->dbh->selectall_arrayref( - "SELECT * FROM $table WHERE user_id = ?", - { Slice => {} }, - $user_id, - ); - foreach my $row (@$rows) { - unless (defined $row->{$name_field}) { - print "$user_id $table $name_field\n"; - die; - } - $result->{$row->{$name_field}} = { - id => $row->{id}, - count => $row->{count}, - dirty => 0, - } + my ($user_id, $table, $name_field) = @_; + my $result = {}; + my $rows + = Bugzilla->dbh->selectall_arrayref("SELECT * FROM $table WHERE user_id = ?", + {Slice => {}}, $user_id,); + foreach my $row (@$rows) { + unless (defined $row->{$name_field}) { + print "$user_id $table $name_field\n"; + die; } - return $result; + $result->{$row->{$name_field}} + = {id => $row->{id}, count => $row->{count}, dirty => 0,}; + } + return $result; } sub _set_stats { - my ($statistics, $user_id, $table, $name_field) = @_; - my $dbh = Bugzilla->dbh; - foreach my $name (keys %$statistics) { - next unless $statistics->{$name}->{dirty}; - if ($statistics->{$name}->{id}) { - $dbh->do( - "UPDATE $table SET count = ? WHERE user_id = ? AND $name_field = ?", - undef, - $statistics->{$name}->{count}, $user_id, $name, - ); - } else { - $dbh->do( - "INSERT INTO $table(user_id, $name_field, count) VALUES (?, ?, ?)", - undef, - $user_id, $name, $statistics->{$name}->{count}, - ); - } + my ($statistics, $user_id, $table, $name_field) = @_; + my $dbh = Bugzilla->dbh; + foreach my $name (keys %$statistics) { + next unless $statistics->{$name}->{dirty}; + if ($statistics->{$name}->{id}) { + $dbh->do( + "UPDATE $table SET count = ? WHERE user_id = ? AND $name_field = ?", + undef, $statistics->{$name}->{count}, + $user_id, $name, + ); + } + else { + $dbh->do( + "INSERT INTO $table(user_id, $name_field, count) VALUES (?, ?, ?)", + undef, $user_id, $name, $statistics->{$name}->{count}, + ); } + } } sub _has_dirty { - my ($statistics) = @_; - foreach my $name (keys %$statistics) { - return 1 if $statistics->{$name}->{dirty}; - } - return 0; + my ($statistics) = @_; + foreach my $name (keys %$statistics) { + return 1 if $statistics->{$name}->{dirty}; + } + return 0; } 1; |