diff --git a/docs/changelog/6.x.x.txt b/docs/changelog/6.x.x.txt index d6b30d05b..371577c8c 100644 --- a/docs/changelog/6.x.x.txt +++ b/docs/changelog/6.x.x.txt @@ -20,6 +20,12 @@ - fix [ 1281516 ] Undefined subroutine &WebGUI::Asset::File::quote runHourly - fix [ 1281430 ] www_restoreList should be in AssetTrash.pm - fix help links on the Asset add/edit forms + - Added cache to settings which increased performance by .02 seconds per + page. + - Added user cache which increased performance by more than .1 seconds per + page. + - Added some new indicies to make asset queries .01 to .1 seconds faster per query. + - fix [ 1274488 ] Visitors language not recognized 6.7.2 6.7.3 diff --git a/docs/upgrades/upgrade_6.7.3-6.7.4.pl b/docs/upgrades/upgrade_6.7.3-6.7.4.pl index 840004a69..fb47d19a9 100644 --- a/docs/upgrades/upgrade_6.7.3-6.7.4.pl +++ b/docs/upgrades/upgrade_6.7.3-6.7.4.pl @@ -4,6 +4,7 @@ use Getopt::Long; use WebGUI::Session; use WebGUI::SQL; use WebGUI::Asset; +use WebGUI::Setting; my $toVersion = "6.7.4"; my $configFile; @@ -14,10 +15,18 @@ start(); updatePageTemplates(); addDebug(); fixFutureDates(); +makeQueriesFaster(); finish(); +#------------------------------------------------- +sub makeQueriesFaster { + print "\tMaking queries a little faster.\n" unless ($quiet); + WebGUI::SQL->write("alter table assetData add index assetId_url_revisionDate_status_tagId (assetId,url,revisionDate,status,tagId)"); + WebGUI::SQL->write("alter table asset add index className_assetId_state (className,assetId,state)"); +} + #------------------------------------------------- sub fixFutureDates { print "\tFixing end dates which appear too far in the future.\n" unless ($quiet); @@ -27,8 +36,8 @@ sub fixFutureDates { #------------------------------------------------- sub addDebug { print "\tAdding more debug options.\n" unless ($quiet); - WebGUI::SQL->write("insert into settings values ('debugIp','')"); - WebGUI::SQL->write("insert into settings values ('showPerformanceIndicators','0')"); + WebGUI::Setting::add("debugIp",""); + WebGUI::Setting::add("showPerformanceIndicators","0"); } #------------------------------------------------- diff --git a/lib/WebGUI/Cache.pm b/lib/WebGUI/Cache.pm index ce33c01ed..210eb2acc 100644 --- a/lib/WebGUI/Cache.pm +++ b/lib/WebGUI/Cache.pm @@ -77,7 +77,7 @@ Flushes the caching system. Must be overridden. =cut sub flush { - rmtree($session{config}{uploadsPath}.$session{os}{slash}."temp"); + rmtree($WebGUI::Session::session{config}{uploadsPath}.$WebGUI::Session::session{os}{slash}."temp"); } #------------------------------------------------------------------- @@ -112,7 +112,7 @@ A subdivider to store this cache under. When building your own cache plug-in def sub new { my $cache; my $class = shift; - if($session{config}{memcached_servers}) { + if($WebGUI::Session::session{config}{memcached_servers}) { require WebGUI::Cache::Memcached; return WebGUI::Cache::Memcached->new(@_); } else { @@ -197,7 +197,7 @@ sub setByHTTP { $userAgent->agent("WebGUI/".$WebGUI::VERSION); $userAgent->timeout(30); my $header = new HTTP::Headers; - my $referer = "http://webgui.http.request/".$session{env}{SERVER_NAME}.$session{env}{REQUEST_URI}; + my $referer = "http://webgui.http.request/".$WebGUI::Session::session{env}{SERVER_NAME}.$WebGUI::Session::session{env}{REQUEST_URI}; chomp $referer; $header->referer($referer); my $request = new HTTP::Request (GET => $url, $header); diff --git a/lib/WebGUI/Cache/FileCache.pm b/lib/WebGUI/Cache/FileCache.pm index f942e4386..688e9c4cd 100644 --- a/lib/WebGUI/Cache/FileCache.pm +++ b/lib/WebGUI/Cache/FileCache.pm @@ -97,7 +97,7 @@ Retrieve content from the filesystem cache. sub get { my $self = shift; - return undef if ($session{config}{disableCache}); + return undef if ($WebGUI::Session::session{config}{disableCache}); if (open(FILE,"<".$self->getFolder()."/expires")) { my $expires = ; close(FILE); @@ -136,10 +136,10 @@ Figures out what the cache root for this namespace should be. A class method. sub getNamespaceRoot { my $self = shift; - my $root = $session{config}{fileCacheRoot}; + my $root = $WebGUI::Session::session{config}{fileCacheRoot}; unless ($root) { - if ($session{os}{windowsish}) { - $root = $session{env}{TEMP} || $session{env}{TMP} || "/temp"; + if ($WebGUI::Session::session{os}{windowsish}) { + $root = $WebGUI::Session::session{env}{TEMP} || $WebGUI::Session::session{env}{TMP} || "/temp"; } else { $root = "/tmp"; } @@ -205,7 +205,7 @@ sub new { my $cache; my $class = shift; my $key = $class->parseKey(shift); - my $namespace = shift || $session{config}{configFile}; + my $namespace = shift || $WebGUI::Session::session{config}{configFile}; bless {_key=>$key, _namespace=>$namespace}, $class; } diff --git a/lib/WebGUI/Cache/Memcached.pm b/lib/WebGUI/Cache/Memcached.pm index 278458a65..50a469477 100644 --- a/lib/WebGUI/Cache/Memcached.pm +++ b/lib/WebGUI/Cache/Memcached.pm @@ -89,7 +89,7 @@ Retrieve content from the filesystem cache. =cut sub get { - return undef if ($session{config}{disableCache}); + return undef if ($WebGUI::Session::session{config}{disableCache}); return $_[0]->{_cache}->get($_[0]->{_key}); } @@ -113,14 +113,14 @@ sub new { my $cache; my $class = shift; my $key = $class->parseKey(shift); - my $namespace = shift || $session{config}{configFile}; + my $namespace = shift || $WebGUI::Session::session{config}{configFile}; # Overcome maximum key length of 255 characters if(length($key.$namespace) > 255) { $key = Digest::MD5::md5_base64($key); } - my $servers = $session{config}{memcached_servers}; + my $servers = $WebGUI::Session::session{config}{memcached_servers}; $servers = [ $servers ] unless (ref $servers); my %options = ( diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 9e1ed9f2f..e34c606bc 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -20,6 +20,7 @@ use WebGUI::Icon; use WebGUI::International; use WebGUI::Privilege; use WebGUI::Session; +use WebGUI::Setting; use WebGUI::Style; use WebGUI::SQL; use WebGUI::URL; @@ -279,8 +280,7 @@ sub www_saveSettings { next; } unless ($key eq "op") { - $session{setting}{$key} = $value; - WebGUI::SQL->write("update settings set value=".quote($value)." where name='$key'"); + WebGUI::Setting::set($key,$value); } } return www_editSettings(); diff --git a/lib/WebGUI/Operation/WebGUI.pm b/lib/WebGUI/Operation/WebGUI.pm index d5b7050d3..54fac04df 100644 --- a/lib/WebGUI/Operation/WebGUI.pm +++ b/lib/WebGUI/Operation/WebGUI.pm @@ -16,7 +16,7 @@ use WebGUI::FormProcessor; use WebGUI::HTMLForm; use WebGUI::HTTP; use WebGUI::Session; -use WebGUI::SQL; +use WebGUI::Setting; use WebGUI::Style; use WebGUI::User; @@ -91,10 +91,10 @@ sub www_setup { $f->submit; $output .= $f->print; } elsif ($session{form}{step} eq "3") { - WebGUI::SQL->write("update settings set value=".quote(WebGUI::FormProcessor::text("companyName"))." where name='companyName'"); - WebGUI::SQL->write("update settings set value=".quote(WebGUI::FormProcessor::url("companyURL"))." where name='companyURL'"); - WebGUI::SQL->write("update settings set value=".quote(WebGUI::FormProcessor::email("companyEmail"))." where name='companyEmail'"); - WebGUI::SQL->write("delete from settings where name='specialState'"); + WebGUI::Setting::set('companyName',WebGUI::FormProcessor::text("companyName")); + WebGUI::Setting::set('companyURL',WebGUI::FormProcessor::url("companyURL")); + WebGUI::Setting::set('companyEmail',WebGUI::FormProcessor::email("companyEmail")); + WebGUI::Setting::remove('specialState'); WebGUI::HTTP::setRedirect($session{env}{SCRIPT_NAME}); return ""; } else { diff --git a/lib/WebGUI/Session.pm b/lib/WebGUI/Session.pm index a49f86ff3..78d69fa8b 100644 --- a/lib/WebGUI/Session.pm +++ b/lib/WebGUI/Session.pm @@ -24,7 +24,9 @@ use Tie::CPHash; use WebGUI::Config; use WebGUI::ErrorHandler; use WebGUI::Id; +use WebGUI::Setting; use WebGUI::SQL; +use WebGUI::User; use WebGUI::Utility; use URI::Escape; @@ -93,44 +95,20 @@ sub _setupSessionVars { #------------------------------------------------------------------- sub _setupUserInfo { - my (%default, $key, %user, $uid, %profile, $value); - tie %user, 'Tie::CPHash'; - $uid = $_[0] || 1; - %user = WebGUI::SQL->quickHash("select * from users where userId=".quote($uid)); - if ($user{userId} eq "") { - _setupUserInfo("1"); - } else { - %profile = WebGUI::SQL->buildHash("select userProfileField.fieldName, userProfileData.fieldData - from userProfileData, userProfileField where userProfileData.fieldName=userProfileField.fieldName - and userProfileData.userId=".quote($user{userId})); - %user = (%user, %profile); - $user{language} = $session{page}{languageId} if ($user{userId} eq '1' || $user{language} eq ''); - %default = WebGUI::SQL->buildHash("select fieldName, dataDefault from userProfileField where profileCategoryId='4'"); - foreach $key (keys %default) { - if ($user{$key} eq "") { - $value = eval($default{$key}); - if (ref $value eq "ARRAY") { - $user{$key} = $$value[0]; - } else { - $user{$key} = $value; - } - } - } - $session{user} = \%user; - if ($session{env}{MOD_PERL}) { - my $r; - if ($mod_perl::VERSION >= 1.999023) { - $r = Apache2::RequestUtil->request; - } else { - $r = Apache->request; - } - if(defined($r)) { - $r->user($session{user}{username}); - } - } - $session{user}{alias} = $session{user}{username} if ($session{user}{alias} =~ /^\W+$/); - $session{user}{alias} = $session{user}{username} if ($session{user}{alias} eq ""); - } + my $u = WebGUI::User->new(shift); + %{$session{user}} = (%{$u->{_profile}}, %{$u->{_user}}); + if ($session{env}{MOD_PERL}) { + my $r; + if ($mod_perl::VERSION >= 1.999023) { + $r = Apache2::RequestUtil->request; + } else { + $r = Apache->request; + } + if(defined($r)) { + $r->user($session{user}{username}); + } + } + $session{user}{alias} = $session{user}{username} if ($session{user}{alias} =~ /^\W+$/ || $session{user}{alias} eq ""); } #------------------------------------------------------------------- @@ -342,8 +320,15 @@ sub open { } } ###---------------------------- + ### evironment variables from web server + $session{env} = \%ENV; + ### check to see if client is proxied and adjust remote_addr as necessary + if ($ENV{HTTP_X_FORWARDED_FOR} ne "") { + $session{env}{REMOTE_ADDR} = $ENV{HTTP_X_FORWARDED_FOR}; + } + ###---------------------------- ### global system settings (from settings table) - $session{setting} = WebGUI::SQL->buildHashRef("select name,value from settings"); + $session{setting} = WebGUI::Setting::get(); ###---------------------------- ### CGI object $CGI::POST_MAX=1024 * $session{setting}{maxAttachmentSize}; @@ -355,13 +340,6 @@ sub open { $session{cgi} = CGI->new(); } ###---------------------------- - ### evironment variables from web server - $session{env} = \%ENV; - ### check to see if client is proxied and adjust remote_addr as necessary - if ($ENV{HTTP_X_FORWARDED_FOR} ne "") { - $session{env}{REMOTE_ADDR} = $ENV{HTTP_X_FORWARDED_FOR}; - } - ###---------------------------- ### form variables foreach ($session{cgi}->param) { $session{form}{$_} = $session{cgi}->param($_); diff --git a/lib/WebGUI/Setting.pm b/lib/WebGUI/Setting.pm new file mode 100644 index 000000000..2053de8e5 --- /dev/null +++ b/lib/WebGUI/Setting.pm @@ -0,0 +1,134 @@ +package WebGUI::Setting; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2005 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use WebGUI::Session; +use WebGUI::SQL; + +=head1 NAME + +Package WebGUI::Setting; + +=head1 DESCRIPTION + +This package stores and retrieves settings. It is generally only used internally by WebGUI and not by external scripts. + +=head1 SYNOPSIS + + use WebGUI::Setting; + + WebGUI::Setting::set($name,$value); + $hashRef = WebGUI::Setting::get(); + +=head1 FUNCTIONS + +These subroutines are available from this package: + +=cut + + + +#------------------------------------------------------------------- + +=head2 add ( name, value ) + +Creates a new setting. + +=head3 name + +The name of the setting to add. + +=head3 value + +The initial value of the setting. + +=cut + +sub add { + my $name = shift; + my $value = shift; + $WebGUI::Session::session{setting}{$name} = $value; + WebGUI::SQL->write("insert into settings values (".quote($name).",".quote($value).")"); + WebGUI::Cache->new("settings")->delete; +} + + +#------------------------------------------------------------------- + +=head2 get ( ) + +Returns a hash reference containing all the settings. + +=cut + +sub get { + my $cache = WebGUI::Cache->new("settings"); + my $settings = $cache->get; + unless (defined $settings) { + $settings = WebGUI::SQL->buildHashRef("select * from settings"); + $cache->set($settings,60*60*24); + } + return $settings; +} + + +#------------------------------------------------------------------- + +=head2 remove ( name ) + +Removes a setting permanently. + +=head3 name + +The name of the setting to set. + +=cut + +sub remove { + my $name = shift; + WebGUI::SQL->write("delete from settings where name=".quote($name)); + WebGUI::Cache->new("settings")->delete; +} + + +#------------------------------------------------------------------- + +=head2 set ( name, value ) + +Sets the value of a setting. + +=head3 name + +The name of the setting to set. + +=head3 value + +The value of the setting. + +=cut + +sub set { + my $name = shift; + my $value = shift; + $WebGUI::Session::session{setting}{$name} = $value; + WebGUI::SQL->write("update settings set value=".quote($value)." where name=".quote($name)); + WebGUI::Cache->new("settings")->delete; +} + + + +1; + diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index e821ab13c..6078fc48a 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -15,14 +15,11 @@ package WebGUI::User; =cut use strict; -use WebGUI::DateTime; -use WebGUI::Grouping; +use WebGUI::Cache; use WebGUI::Id; -use WebGUI::International; use WebGUI::Session; use WebGUI::SQL; -use WebGUI::URL; -use WebGUI::Operation::Auth; + =head1 NAME @@ -60,6 +57,7 @@ These methods are available from this class: sub _create { my $userId = shift || WebGUI::Id::generate(); WebGUI::SQL->write("insert into users (userId,dateCreated) values (".quote($userId).",".time().")"); + require WebGUI::Grouping; WebGUI::Grouping::addUsersToGroups([$userId],[2,7]); return $userId; } @@ -81,6 +79,7 @@ An override for the default offset of the grouping. Specified in seconds. =cut sub addToGroups { + require WebGUI::Grouping; WebGUI::Grouping::addUsersToGroups([$_[0]->{_userId}],$_[1],$_[2]); } @@ -130,8 +129,10 @@ Deletes this user. sub delete { my $class = shift; + require WebGUI::Operation::Auth; WebGUI::SQL->write("delete from users where userId=".quote($class->{_userId})); WebGUI::SQL->write("delete from userProfileData where userId=".quote($class->{_userId})); + require WebGUI::Grouping; WebGUI::Grouping::deleteUsersFromGroups([$class->{_userId}],WebGUI::Grouping::getGroupsForUser($class->{_userId})); WebGUI::SQL->write("delete from messageLog where userId=".quote($class->{_userId})); @@ -157,6 +158,7 @@ An array reference containing a list of groups. =cut sub deleteFromGroups { + require WebGUI::Grouping; WebGUI::Grouping::deleteUsersFromGroups([$_[0]->{_userId}],$_[1]); } @@ -231,28 +233,39 @@ A unique ID to use instead of the ID that WebGUI will generate for you. It must =cut sub new { - my ($class, $userId, %default, $value, $key, %user, %profile); - tie %user, 'Tie::CPHash'; - $class = shift; - $userId = shift || 1; + my $class = shift; + my $userId = shift || 1; my $overrideId = shift; $userId = _create($overrideId) if ($userId eq "new"); - %user = WebGUI::SQL->quickHash("select * from users where userId=".quote($userId)); - %profile = WebGUI::SQL->buildHash("select userProfileField.fieldName, userProfileData.fieldData - from userProfileField, userProfileData where userProfileField.fieldName=userProfileData.fieldName and - userProfileData.userId=".quote($user{userId})); - %default = WebGUI::SQL->buildHash("select fieldName, dataDefault from userProfileField where profileCategoryId=4"); - foreach $key (keys %default) { - if ($profile{$key} eq "") { - $value = eval($default{$key}); - if (ref $value eq "ARRAY") { + my $cache = WebGUI::Cache->new(["user",$userId]); + my $userData = $cache->get; + unless ($userData->{_userId}) { + my %user; + tie %user, 'Tie::CPHash'; + %user = WebGUI::SQL->quickHash("select * from users where userId=".quote($userId)); + my %profile = WebGUI::SQL->buildHash("select userProfileField.fieldName, userProfileData.fieldData + from userProfileField, userProfileData where userProfileField.fieldName=userProfileData.fieldName and + userProfileData.userId=".quote($user{userId})); + my %default = WebGUI::SQL->buildHash("select fieldName, dataDefault from userProfileField where profileCategoryId=4"); + foreach my $key (keys %default) { + my $value; + if ($profile{$key} eq "") { + $value = eval($default{$key}); + if (ref $value eq "ARRAY") { $profile{$key} = $$value[0]; - } else { - $profile{$key} = $value; - } - } + } else { + $profile{$key} = $value; + } + } + } + $userData = { + _userId => $userId, + _user => \%user, + _profile => \%profile + }; + $cache->set($userData, 60*60*24); } - bless {_userId => $userId, _user => \%user, _profile =>\%profile }, $class; + bless $userData, $class; } #------------------------------------------------------------------- diff --git a/sbin/preload.perl b/sbin/preload.perl index 82060828d..bbb419683 100644 --- a/sbin/preload.perl +++ b/sbin/preload.perl @@ -101,6 +101,7 @@ use WebGUI::Operation (); use WebGUI::Paginator (); use WebGUI::Privilege (); use WebGUI::Session (); +use WebGUI::Setting (); use WebGUI::SQL (); use WebGUI::Storage (); use WebGUI::Style ();