[dw-free] migrate LJ::load_user_props -> $u->preload_props
[commit: http://hg.dwscoalition.org/dw-free/rev/1f2c86efdd95]
http://bugs.dwscoalition.org/show_bug.cgi?id=2653
Remove the LJ::load_user_props function. That code is now in the
preload_props method.
Patch by
kareila.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2653
Remove the LJ::load_user_props function. That code is now in the
preload_props method.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/LJ/User.pm
-------------------------------------------------------------------------------- diff -r 1ecf2cc492d5 -r 1f2c86efdd95 cgi-bin/LJ/User.pm --- a/cgi-bin/LJ/User.pm Fri Jun 11 19:48:57 2010 +0800 +++ b/cgi-bin/LJ/User.pm Fri Jun 11 14:21:39 2010 -0500 @@ -776,8 +776,155 @@ sub load_random_user { } +# des: Given a user hashref, loads the values of the given named properties +# into that user hashref. +# args: u, opts?, propname* +# des-opts: hashref of opts. set key 'use_master' to use cluster master. +# des-propname: the name of a property from the [dbtable[userproplist]] table. +# leave undef to preload all userprops sub preload_props { - LJ::load_user_props( @_ ); + my $u = shift; + return unless LJ::isu($u); + return if $u->is_expunged; + + my $opts = ref $_[0] ? shift : {}; + my (@props) = @_; + + my ($sql, $sth); + LJ::load_props("user"); + + ## user reference + my $uid = $u->userid + 0; + $uid = LJ::get_userid( $u->user ) unless $uid; + + my $mem = {}; + my $use_master = 0; + my $used_slave = 0; # set later if we ended up using a slave + + if (@LJ::MEMCACHE_SERVERS) { + my @keys; + foreach (@props) { + next if exists $u->{$_}; + my $p = LJ::get_prop("user", $_); + die "Invalid userprop $_ passed to preload_props." unless $p; + push @keys, [$uid,"uprop:$uid:$p->{'id'}"]; + } + $mem = LJ::MemCache::get_multi(@keys) || {}; + $use_master = 1; + } + + $use_master = 1 if $opts->{'use_master'}; + + my @needwrite; # [propid, propname] entries we need to save to memcache later + + my %loadfrom; + my %multihomed; # ( $propid => 0/1 ) # 0 if we haven't loaded it, 1 if we have + unless (@props) { + # case 1: load all props for a given user. + # multihomed props are stored on userprop and userproplite2, but since they + # should always be in sync, it doesn't matter which gets loaded first, the + # net results should be the same. see doc/server/lj.int.multihomed_userprops.html + # for more information. + $loadfrom{'userprop'} = 1; + $loadfrom{'userproplite'} = 1; + $loadfrom{'userproplite2'} = 1; + $loadfrom{'userpropblob'} = 1; + } else { + # case 2: load only certain things + foreach (@props) { + next if exists $u->{$_}; + my $p = LJ::get_prop("user", $_); + die "Invalid userprop $_ passed to preload_props." unless $p; + if (defined $mem->{"uprop:$uid:$p->{'id'}"}) { + $u->{$_} = $mem->{"uprop:$uid:$p->{'id'}"}; + next; + } + push @needwrite, [ $p->{'id'}, $_ ]; + my $source = $p->{'indexed'} ? "userprop" : "userproplite"; + if ($p->{datatype} eq 'blobchar') { + $source = "userpropblob"; # clustered blob + } + elsif ( $p->{'cldversion'} && $u->dversion >= $p->{'cldversion'} ) { + $source = "userproplite2"; # clustered + } + elsif ($p->{multihomed}) { + $multihomed{$p->{id}} = 0; + $source = "userproplite2"; + } + push @{$loadfrom{$source}}, $p->{'id'}; + } + } + + foreach my $table (qw{userproplite userproplite2 userpropblob userprop}) { + next unless exists $loadfrom{$table}; + my $db; + if ($use_master) { + $db = ($table =~ m{userprop(lite2|blob)}) ? + LJ::get_cluster_master($u) : + LJ::get_db_writer(); + } + unless ($db) { + $db = ($table =~ m{userprop(lite2|blob)}) ? + LJ::get_cluster_reader($u) : + LJ::get_db_reader(); + $used_slave = 1; + } + $sql = "SELECT upropid, value FROM $table WHERE userid=$uid"; + if (ref $loadfrom{$table}) { + $sql .= " AND upropid IN (" . join(",", @{$loadfrom{$table}}) . ")"; + } + $sth = $db->prepare($sql); + $sth->execute; + while (my ($id, $v) = $sth->fetchrow_array) { + delete $multihomed{$id} if $table eq 'userproplite2'; + $u->{$LJ::CACHE_PROPID{'user'}->{$id}->{'name'}} = $v; + } + + # push back multihomed if necessary + if ($table eq 'userproplite2') { + push @{$loadfrom{userprop}}, $_ foreach keys %multihomed; + } + } + + # see if we failed to get anything above and need to hit the master. + # this usually happens the first time a multihomed prop is hit. this + # code will propagate that prop down to the cluster. + if (%multihomed) { + + # verify that we got the database handle before we try propagating data + if ($u->writer) { + my @values; + foreach my $id (keys %multihomed) { + my $pname = $LJ::CACHE_PROPID{user}{$id}{name}; + if (defined $u->{$pname} && $u->{$pname}) { + push @values, "($uid, $id, " . $u->quote($u->{$pname}) . ")"; + } else { + push @values, "($uid, $id, '')"; + } + } + $u->do("REPLACE INTO userproplite2 VALUES " . join ',', @values); + } + } + + # Add defaults to user object. + + # If this was called with no @props, then the function tried + # to load all metadata. but we don't know what's missing, so + # try to apply all defaults. + unless (@props) { @props = keys %LJ::USERPROP_DEF; } + + foreach my $prop (@props) { + next if (defined $u->{$prop}); + $u->{$prop} = $LJ::USERPROP_DEF{$prop}; + } + + unless ($used_slave) { + my $expire = time() + 3600*24; + foreach my $wr (@needwrite) { + my ($id, $name) = ($wr->[0], $wr->[1]); + LJ::MemCache::set([$uid,"uprop:$uid:$id"], $u->{$name} || "", $expire); + } + } } @@ -7155,163 +7302,6 @@ sub get_bio { # <LJFUNC> -# name: LJ::load_user_props -# des: Given a user hashref, loads the values of the given named properties -# into that user hashref. -# args: dbarg?, u, opts?, propname* -# des-opts: hashref of opts. set key 'cache' to use memcache. -# des-propname: the name of a property from the [dbtable[userproplist]] table. -# </LJFUNC> -sub load_user_props -{ - &nodb; - - my $u = shift; - return unless isu($u); - return if $u->is_expunged; - - my $opts = ref $_[0] ? shift : {}; - my (@props) = @_; - - my ($sql, $sth); - LJ::load_props("user"); - - ## user reference - my $uid = $u->userid + 0; - $uid = LJ::get_userid( $u->user ) unless $uid; - - my $mem = {}; - my $use_master = 0; - my $used_slave = 0; # set later if we ended up using a slave - - if (@LJ::MEMCACHE_SERVERS) { - my @keys; - foreach (@props) { - next if exists $u->{$_}; - my $p = LJ::get_prop("user", $_); - die "Invalid userprop $_ passed to LJ::load_user_props." unless $p; - push @keys, [$uid,"uprop:$uid:$p->{'id'}"]; - } - $mem = LJ::MemCache::get_multi(@keys) || {}; - $use_master = 1; - } - - $use_master = 1 if $opts->{'use_master'}; - - my @needwrite; # [propid, propname] entries we need to save to memcache later - - my %loadfrom; - my %multihomed; # ( $propid => 0/1 ) # 0 if we haven't loaded it, 1 if we have - unless (@props) { - # case 1: load all props for a given user. - # multihomed props are stored on userprop and userproplite2, but since they - # should always be in sync, it doesn't matter which gets loaded first, the - # net results should be the same. see doc/server/lj.int.multihomed_userprops.html - # for more information. - $loadfrom{'userprop'} = 1; - $loadfrom{'userproplite'} = 1; - $loadfrom{'userproplite2'} = 1; - $loadfrom{'userpropblob'} = 1; - } else { - # case 2: load only certain things - foreach (@props) { - next if exists $u->{$_}; - my $p = LJ::get_prop("user", $_); - die "Invalid userprop $_ passed to LJ::load_user_props." unless $p; - if (defined $mem->{"uprop:$uid:$p->{'id'}"}) { - $u->{$_} = $mem->{"uprop:$uid:$p->{'id'}"}; - next; - } - push @needwrite, [ $p->{'id'}, $_ ]; - my $source = $p->{'indexed'} ? "userprop" : "userproplite"; - if ($p->{datatype} eq 'blobchar') { - $source = "userpropblob"; # clustered blob - } - elsif ( $p->{'cldversion'} && $u->dversion >= $p->{'cldversion'} ) { - $source = "userproplite2"; # clustered - } - elsif ($p->{multihomed}) { - $multihomed{$p->{id}} = 0; - $source = "userproplite2"; - } - push @{$loadfrom{$source}}, $p->{'id'}; - } - } - - foreach my $table (qw{userproplite userproplite2 userpropblob userprop}) { - next unless exists $loadfrom{$table}; - my $db; - if ($use_master) { - $db = ($table =~ m{userprop(lite2|blob)}) ? - LJ::get_cluster_master($u) : - LJ::get_db_writer(); - } - unless ($db) { - $db = ($table =~ m{userprop(lite2|blob)}) ? - LJ::get_cluster_reader($u) : - LJ::get_db_reader(); - $used_slave = 1; - } - $sql = "SELECT upropid, value FROM $table WHERE userid=$uid"; - if (ref $loadfrom{$table}) { - $sql .= " AND upropid IN (" . join(",", @{$loadfrom{$table}}) . ")"; - } - $sth = $db->prepare($sql); - $sth->execute; - while (my ($id, $v) = $sth->fetchrow_array) { - delete $multihomed{$id} if $table eq 'userproplite2'; - $u->{$LJ::CACHE_PROPID{'user'}->{$id}->{'name'}} = $v; - } - - # push back multihomed if necessary - if ($table eq 'userproplite2') { - push @{$loadfrom{userprop}}, $_ foreach keys %multihomed; - } - } - - # see if we failed to get anything above and need to hit the master. - # this usually happens the first time a multihomed prop is hit. this - # code will propagate that prop down to the cluster. - if (%multihomed) { - - # verify that we got the database handle before we try propagating data - if ($u->writer) { - my @values; - foreach my $id (keys %multihomed) { - my $pname = $LJ::CACHE_PROPID{user}{$id}{name}; - if (defined $u->{$pname} && $u->{$pname}) { - push @values, "($uid, $id, " . $u->quote($u->{$pname}) . ")"; - } else { - push @values, "($uid, $id, '')"; - } - } - $u->do("REPLACE INTO userproplite2 VALUES " . join ',', @values); - } - } - - # Add defaults to user object. - - # If this was called with no @props, then the function tried - # to load all metadata. but we don't know what's missing, so - # try to apply all defaults. - unless (@props) { @props = keys %LJ::USERPROP_DEF; } - - foreach my $prop (@props) { - next if (defined $u->{$prop}); - $u->{$prop} = $LJ::USERPROP_DEF{$prop}; - } - - unless ($used_slave) { - my $expire = time() + 3600*24; - foreach my $wr (@needwrite) { - my ($id, $name) = ($wr->[0], $wr->[1]); - LJ::MemCache::set([$uid,"uprop:$uid:$id"], $u->{$name} || "", $expire); - } - } -} - - -# <LJFUNC> # name: LJ::modify_caps # des: Given a list of caps to add and caps to remove, updates a user's caps. # args: uuid, cap_add, cap_del, res --------------------------------------------------------------------------------