From c19dc4ffe98074bedb780652af581a1f0edb3b2d Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 12 Aug 2014 14:05:32 +0800 Subject: Bug 993926: Bugzilla::User::Setting::get_all_settings() should use memcached r=sgreen,a=glob --- Bugzilla/Memcached.pm | 14 +++++++++++++- Bugzilla/User/Setting.pm | 41 +++++++++++++++++++++++++++++++---------- editsettings.cgi | 1 + userprefs.cgi | 2 ++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm index 1464b6c00..df90fef93 100644 --- a/Bugzilla/Memcached.pm +++ b/Bugzilla/Memcached.pm @@ -254,10 +254,13 @@ sub _get { elsif (ref($value) eq 'ARRAY') { foreach my $value (@$value) { next unless defined $value; - # arrays of hashes are common + # arrays of hashes and arrays are common if (ref($value) eq 'HASH') { _detaint_hashref($value); } + elsif (ref($value) eq 'ARRAY') { + _detaint_arrayref($value); + } elsif (!ref($value)) { trick_taint($value); } @@ -278,6 +281,15 @@ sub _detaint_hashref { } } +sub _detaint_arrayref { + my ($arrayref) = @_; + foreach my $value (@$arrayref) { + if (defined($value) && !ref($value)) { + trick_taint($value); + } + } +} + sub _delete { my ($self, $key) = @_; $key = $self->_encode_key($key) diff --git a/Bugzilla/User/Setting.pm b/Bugzilla/User/Setting.pm index 451e946f7..5b518da65 100644 --- a/Bugzilla/User/Setting.pm +++ b/Bugzilla/User/Setting.pm @@ -15,8 +15,12 @@ use parent qw(Exporter); # Module stuff -@Bugzilla::User::Setting::EXPORT = qw(get_all_settings get_defaults - add_setting); +@Bugzilla::User::Setting::EXPORT = qw( + get_all_settings + get_defaults + add_setting + clear_settings_cache +); use Bugzilla::Error; use Bugzilla::Util qw(trick_taint get_text); @@ -159,15 +163,20 @@ sub get_all_settings { my $settings = {}; my $dbh = Bugzilla->dbh; - my $rows = $dbh->selectall_arrayref( - q{SELECT name, default_value, is_enabled, setting_value, subclass - FROM setting - LEFT JOIN profile_setting - ON setting.name = profile_setting.setting_name - AND profile_setting.user_id = ?}, undef, ($user_id)); + my $cache_key = "user_settings.$user_id"; + my $rows = Bugzilla->memcached->get_config({ key => $cache_key }); + if (!$rows) { + $rows = $dbh->selectall_arrayref( + q{SELECT name, default_value, is_enabled, setting_value, subclass + FROM setting + LEFT JOIN profile_setting + ON setting.name = profile_setting.setting_name + AND profile_setting.user_id = ?}, undef, ($user_id)); + Bugzilla->memcached->set_config({ key => $cache_key, data => $rows }); + } foreach my $row (@$rows) { - my ($name, $default_value, $is_enabled, $value, $subclass) = @$row; + my ($name, $default_value, $is_enabled, $value, $subclass) = @$row; my $is_default; @@ -179,13 +188,18 @@ sub get_all_settings { } $settings->{$name} = new Bugzilla::User::Setting( - $name, $user_id, $is_enabled, + $name, $user_id, $is_enabled, $default_value, $value, $is_default, $subclass); } return $settings; } +sub clear_settings_cache { + my ($user_id) = @_; + Bugzilla->memcached->clear_config({ key => "user_settings.$user_id" }); +} + sub get_defaults { my ($user_id) = @_; my $dbh = Bugzilla->dbh; @@ -368,6 +382,13 @@ Params: C<$setting_name> - string - the name of the setting C<$is_enabled> - boolean - if false, all users must use the global default Returns: nothing +=item C + +Description: Clears cached settings data for the specified user. Must be + called after updating any user's setting. +Params: C<$user_id> - integer - the user id. +Returns: nothing + =begin private =item C<_setting_exists> diff --git a/editsettings.cgi b/editsettings.cgi index bf5e2025b..f2c6e2cc3 100755 --- a/editsettings.cgi +++ b/editsettings.cgi @@ -53,6 +53,7 @@ if ($action eq 'update') { } $vars->{'message'} = 'default_settings_updated'; $vars->{'changes_saved'} = $changed; + Bugzilla->memcached->clear_config(); delete_token($token); } diff --git a/userprefs.cgi b/userprefs.cgi index 13f817d53..f798d4c76 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -19,6 +19,7 @@ use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::User; use Bugzilla::User::APIKey; +use Bugzilla::User::Setting qw(clear_settings_cache); use Bugzilla::Token; my $template = Bugzilla->template; @@ -170,6 +171,7 @@ sub SaveSettings { } } $vars->{'settings'} = $user->settings(1); + clear_settings_cache($user->id); } sub DoEmail { -- cgit v1.2.3-24-g4f1b