[dw-free] move cgi-bin/lj*.pl files into proper modules (in cgi-bin/LJ)
[commit: http://hg.dwscoalition.org/dw-free/rev/5cf79cb7d354]
http://bugs.dwscoalition.org/show_bug.cgi?id=1726
Move some functions in ljdb.pl from the LJ package to the LJ::DB package;
fix all references.
Patch by
kareila.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=1726
Move some functions in ljdb.pl from the LJ package to the LJ::DB package;
fix all references.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/dev/entrydump.pl
- bin/ljubackup.pl
- bin/ljumover.pl
- bin/maint/synsuck.pl
- bin/moveucluster.pl
- bin/renameuser.pl
- bin/worker/paidstatus
- cgi-bin/DW/StatData/ActiveAccounts.pm
- cgi-bin/DW/User/Edges/WatchTrust/Loader.pm
- cgi-bin/LJ/AccessLogSink/DBIProfile.pm
- cgi-bin/LJ/Directory/Constraint/ContactInfo.pm
- cgi-bin/LJ/Entry.pm
- cgi-bin/LJ/Error.pm
- cgi-bin/LJ/Lang.pm
- cgi-bin/LJ/UniqCookie.pm
- cgi-bin/LJ/User.pm
- cgi-bin/ljdb.pl
- cgi-bin/ljlib.pl
- cgi-bin/ljprotocol.pl
- cgi-bin/ljrelation.pl
- t/assertions.t
- t/uniqcookie.t
- t/userloading.t
-------------------------------------------------------------------------------- diff -r e86ea43504da -r 5cf79cb7d354 bin/dev/entrydump.pl --- a/bin/dev/entrydump.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/dev/entrydump.pl Fri Sep 30 00:14:15 2011 +0800 @@ -20,15 +20,15 @@ my $url = shift; -LJ::no_cache(sub { +LJ::DB::no_cache( sub { -my $entry = LJ::Entry->new_from_url($url); + my $entry = LJ::Entry->new_from_url( $url ); -print "entry = $entry\n"; -use Data::Dumper; + print "entry = $entry\n"; + use Data::Dumper; - print Dumper($entry->props, clean($entry->event_orig), clean($entry->event_raw)); -}); + print Dumper( $entry->props, clean($entry->event_orig), clean($entry->event_raw) ); +} ); sub clean { diff -r e86ea43504da -r 5cf79cb7d354 bin/ljubackup.pl --- a/bin/ljubackup.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/ljubackup.pl Fri Sep 30 00:14:15 2011 +0800 @@ -364,7 +364,7 @@ } else { - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); daemonRoutine( $lsock, $id ); exit; } @@ -693,7 +693,7 @@ # :FIXME: Is this necessary? We obviously don't have a # destination cluster... - #LJ::disconnect_dbs(); + #LJ::DB::disconnect_dbs(); #$dbh = LJ::get_db_writer() # or die "Couldn't fetch a writer."; #$dbh->do(q{ @@ -757,7 +757,7 @@ foreach my $thread ( values %{$self->{userThreads}} ) { $thread->unlock; - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); my $dbh = LJ::get_db_writer() or die "Couldn't get a db_writer."; $dbh->do( "DELETE FROM clustermove_inprogress WHERE userid = ?", undef, $thread->user->userid ) @@ -788,7 +788,7 @@ delete $self->{userThreads}{$thread->user->userid}; $thread->unlock; - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); my $dbh = LJ::get_db_writer() or die "Couldn't get a db_writer."; $dbh->do( "DELETE FROM clustermove_inprogress WHERE userid = ?", undef, $thread->user->userid ) @@ -828,7 +828,7 @@ # disconnect_dbs() in the thread's start() method immediately after the # fork(), too. Perhaps I'll revisit this after hacking on DBI::Role for a # bit. - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); $dbh = LJ::get_db_writer() or die "failed to get_db_writer()"; $sql = q{ @@ -1045,7 +1045,7 @@ # Fork and exec a child, keeping the pid unless (( $self->{pid} = fork )) { - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); my ( $user, diff -r e86ea43504da -r 5cf79cb7d354 bin/ljumover.pl --- a/bin/ljumover.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/ljumover.pl Fri Sep 30 00:14:15 2011 +0800 @@ -458,7 +458,7 @@ } else { - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); daemonRoutine( $lsock, $id ); exit; } @@ -879,7 +879,7 @@ # cluster field. :FIXME: This is obviously stupid to disconnect # and reconnect every time, but since the handle is b0rked after # the ->run() below fork()s, this is necessary for it to work. - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); $dbh = LJ::get_db_writer() or die "Couldn't fetch a writer."; $dbh->do(q{ @@ -943,7 +943,7 @@ $self->message( "Unlocking %d remaining users.", values %{$self->{userThreads}} ); foreach my $thread ( values %{$self->{userThreads}} ) { - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); $thread->unlock; my $dbh = LJ::get_db_writer() or die "Couldn't get a db_writer."; $dbh->do( "DELETE FROM clustermove_inprogress WHERE userid = ?", @@ -974,7 +974,7 @@ $self->{fakeMovedUsers}{$thread->userid} = 1 if $thread->testingMode; delete $self->{userThreads}{$thread->userid}; - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); $thread->unlock; my $dbh = LJ::get_db_writer() or die "Couldn't get a db_writer."; $dbh->do( "DELETE FROM clustermove_inprogress WHERE userid = ?", @@ -1028,7 +1028,7 @@ # disconnect_dbs() in the thread's start() method immediately after the # fork(), too. Perhaps I'll revisit this after hacking on DBI::Role for a # bit. - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); $dbh = LJ::get_db_writer() or die "failed to get_db_writer()"; $sql = q{ @@ -1248,7 +1248,7 @@ my ( $user, $userid, $src, $dest ) = @_; # Lock the user - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); LJ::update_user( $userid, {raw => "caps=caps|(1<<$ReadOnlyBit)"} ); return bless { @@ -1270,7 +1270,7 @@ # Fork and exec a child, keeping the pid unless (( $self->{pid} = fork )) { - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); if ( $self->testingMode ) { my $seconds = int(rand 20) + 3; diff -r e86ea43504da -r 5cf79cb7d354 bin/maint/synsuck.pl --- a/bin/maint/synsuck.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/maint/synsuck.pl Fri Sep 30 00:14:15 2011 +0800 @@ -79,7 +79,7 @@ $userct++; } else { # handles won't survive the fork - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); LJ::SynSuck::update_feed($urow, $verbose); exit 0; } diff -r e86ea43504da -r 5cf79cb7d354 bin/moveucluster.pl --- a/bin/moveucluster.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/moveucluster.pl Fri Sep 30 00:14:15 2011 +0800 @@ -202,7 +202,7 @@ print "moveUser($u->{user}/$u->{userid}) = fail: $@\n"; } LJ::end_request(); - LJ::disconnect_dbs(); # end_request could do this, but we want to force it + LJ::DB::disconnect_dbs(); # end_request could do this, but we want to force it } else { die "Unknown response from server: $line\n"; } diff -r e86ea43504da -r 5cf79cb7d354 bin/renameuser.pl --- a/bin/renameuser.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/renameuser.pl Fri Sep 30 00:14:15 2011 +0800 @@ -47,10 +47,10 @@ ### check that emails/passwords match, and that at least one is verified unless ($args{force}) { - my @acct = grep { $_ } LJ::no_cache(sub { - return (LJ::load_user($from), - LJ::load_user($to)); - }); + my @acct = grep { $_ } LJ::DB::no_cache( sub { + return ( LJ::load_user($from), + LJ::load_user($to) ); + } ); unless (@acct == 2) { print "Both accounts aren't valid.\n"; exit 1; diff -r e86ea43504da -r 5cf79cb7d354 bin/worker/paidstatus --- a/bin/worker/paidstatus Thu Sep 29 17:44:58 2011 +0800 +++ b/bin/worker/paidstatus Fri Sep 30 00:14:15 2011 +0800 @@ -95,7 +95,7 @@ sub main_loop { # disconnect dbs - LJ::disconnect_dbs(); + LJ::DB::disconnect_dbs(); LJ::start_request(); # now get a db or die diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/DW/StatData/ActiveAccounts.pm --- a/cgi-bin/DW/StatData/ActiveAccounts.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/DW/StatData/ActiveAccounts.pm Fri Sep 30 00:14:15 2011 +0800 @@ -108,7 +108,7 @@ $data{$k} = 0; } - LJ::foreach_cluster( sub { + LJ::DB::foreach_cluster( sub { my ( $cid, $dbr ) = @_; # $cid isn't used my $sth = $dbr->prepare( qq{ diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/DW/User/Edges/WatchTrust/Loader.pm --- a/cgi-bin/DW/User/Edges/WatchTrust/Loader.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/DW/User/Edges/WatchTrust/Loader.pm Fri Sep 30 00:14:15 2011 +0800 @@ -194,12 +194,12 @@ my $lockname = "get_wt_list:$userid"; my $release_lock = sub { - LJ::release_lock($dbh, "global", $lockname); + LJ::DB::release_lock( $dbh, "global", $lockname ); return $_[0]; }; # get a lock - my $lock = LJ::get_lock($dbh, "global", $lockname); + my $lock = LJ::DB::get_lock( $dbh, "global", $lockname ); return {} unless $lock; # in lock, try memcache first (unless told not to) diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/AccessLogSink/DBIProfile.pm --- a/cgi-bin/LJ/AccessLogSink/DBIProfile.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/AccessLogSink/DBIProfile.pm Fri Sep 30 00:14:15 2011 +0800 @@ -51,7 +51,7 @@ # ] # The leaves are stored as values in the hash keyed by statement - # because LJ::get_dbirole_dbh() sets the profile to + # because LJ::DB::get_dbirole_dbh() sets the profile to # "2/DBI::Profile". The 2 part is the DBI::Profile magic number # which means split the times by statement. my $data = $dbh->{Profile}{Data}; diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/Directory/Constraint/ContactInfo.pm --- a/cgi-bin/LJ/Directory/Constraint/ContactInfo.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/Directory/Constraint/ContactInfo.pm Fri Sep 30 00:14:15 2011 +0800 @@ -55,7 +55,7 @@ push @propids, $p->{upropid}; } - my $bind = LJ::bindstr(@propids); + my $bind = LJ::DB::bindstr( @propids ); my $rows = $dbr->selectcol_arrayref("SELECT userid FROM userprop WHERE upropid IN ($bind) AND value = ?", undef, @propids, $self->screenname); die $dbr->errstr if $dbr->err; diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/Entry.pm --- a/cgi-bin/LJ/Entry.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/Entry.pm Fri Sep 30 00:14:15 2011 +0800 @@ -1743,7 +1743,7 @@ # </LJFUNC> sub load_log_props2 { - my $db = isdb($_[0]) ? shift @_ : undef; + my $db = LJ::DB::isdb( $_[0] ) ? shift @_ : undef; my ($uuserid, $listref, $hashref) = @_; my $userid = want_userid($uuserid); diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/Error.pm --- a/cgi-bin/LJ/Error.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/Error.pm Fri Sep 30 00:14:15 2011 +0800 @@ -73,7 +73,7 @@ my $ref = ref $_[0]; # wrapping a database (or database-like) handle - if (LJ::isdb($_[0]) || $ref eq "LJ::User") { + if ( LJ::DB::isdb( $_[0] ) || $ref eq "LJ::User" ) { return errobj("Database::Failure", db => $_[0]); } @@ -249,7 +249,7 @@ $ins->(); } - $dbl->disconnect if $LJ::DISCONNECT_DB_LOG && LJ::use_diff_db("master", "logs"); + $dbl->disconnect if $LJ::DISCONNECT_DB_LOG && LJ::DB::use_diff_db( "master", "logs" ); } # override this: whether it was user-defined. should return 0 or 1. diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/Lang.pm --- a/cgi-bin/LJ/Lang.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/Lang.pm Fri Sep 30 00:14:15 2011 +0800 @@ -335,12 +335,12 @@ return 0 unless $dbh; # allocate a new id - LJ::get_lock($dbh, 'global', 'mlitem_dmid') || return 0; + LJ::DB::get_lock( $dbh, 'global', 'mlitem_dmid' ) || return 0; $itid = $dbh->selectrow_array("SELECT MAX(itid)+1 FROM ml_items WHERE dmid=?", undef, $dmid); $itid ||= 1; # if the table is empty, NULL+1 == NULL $dbh->do("INSERT INTO ml_items (dmid, itid, itcode, notes) ". "VALUES (?, ?, ?, ?)", undef, $dmid, $itid, $itcode, $opts->{'notes'}); - LJ::release_lock($dbh, 'global', 'mlitem_dmid'); + LJ::DB::release_lock( $dbh, 'global', 'mlitem_dmid' ); if ($dbh->err) { return $dbh->selectrow_array("SELECT itid FROM ml_items WHERE dmid=$dmid AND itcode=?", @@ -400,12 +400,12 @@ # Strip bad characters $text =~ s/\r//; my $qtext = $dbh->quote($text); - LJ::get_lock( $dbh, 'global', 'ml_text_txtid' ) || return 0; + LJ::DB::get_lock( $dbh, 'global', 'ml_text_txtid' ) || return 0; $txtid = $dbh->selectrow_array("SELECT MAX(txtid)+1 FROM ml_text WHERE dmid=?", undef, $dmid); $txtid ||= 1; $dbh->do("INSERT INTO ml_text (dmid, txtid, lnid, itid, text, userid) ". "VALUES ($dmid, $txtid, $lnid, $itid, $qtext, $userid)"); - LJ::release_lock( $dbh, 'global', 'ml_text_txtid' ); + LJ::DB::release_lock( $dbh, 'global', 'ml_text_txtid' ); return set_error("Error inserting ml_text: ".$dbh->errstr) if $dbh->err; } if ($opts->{'txtid'}) { diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/UniqCookie.pm --- a/cgi-bin/LJ/UniqCookie.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/UniqCookie.pm Fri Sep 30 00:14:15 2011 +0800 @@ -197,10 +197,10 @@ # with users who write many rows but for some reason never # load any rows, and are therefore never cleaned if ($class->should_lazy_clean) { - LJ::no_cache(sub { + LJ::DB::no_cache( sub { $class->load_mapping( user => $uid ); # no need for uniq => $uniq case - }); + } ); } return $rv; diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/LJ/User.pm --- a/cgi-bin/LJ/User.pm Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/LJ/User.pm Fri Sep 30 00:14:15 2011 +0800 @@ -1451,7 +1451,7 @@ my $u = shift; if ($u->isa("LJ::User")) { return $u->{_mysql_insertid}; - } elsif (LJ::isdb($u)) { + } elsif ( LJ::DB::isdb( $u ) ) { my $db = $u; return $db->{'mysql_insertid'}; } else { @@ -7998,7 +7998,7 @@ if ($used_raw) { # for a load of userids from the master after update # so we pick up the values set via the 'raw' option - require_master( sub { LJ::load_userid($uid) } ); + LJ::DB::require_master( sub { LJ::load_userid($uid) } ); } else { while ( my ($k, $v) = each %$ref ) { my $cache = $LJ::REQ_CACHE_USER_ID{$uid} or next; diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/ljdb.pl --- a/cgi-bin/ljdb.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/ljdb.pl Fri Sep 30 00:14:15 2011 +0800 @@ -32,12 +32,12 @@ 'sources' => \%LJ::DBINFO, 'default_db' => "livejournal", 'time_check' => 60, - 'time_report' => \&LJ::dbtime_callback, + 'time_report' => \&LJ::DB::dbtime_callback, }; package LJ::DB; -use Carp qw(croak); +use Carp qw(croak); # import croak into package LJ::DB # <LJFUNC> # name: LJ::DB::time_range_to_ids @@ -148,6 +148,9 @@ return ($startid, $endid); } +sub isdb { return ref $_[0] && (ref $_[0] eq "DBI::db" || + ref $_[0] eq "Apache::DBI::db"); } + sub dbh_by_role { return $LJ::DBIRole->get_dbh( @_ ); } @@ -216,9 +219,24 @@ return ($1, $2); } -package LJ; +sub foreach_cluster { + my $coderef = shift; + my $opts = shift || {}; -use Carp qw(croak); + # have to include this via an eval so it doesn't actually get included + # until someone calls foreach cluster. at which point, if they're in web + # context, it will fail. + eval "use LJ::DBUtil; 1;"; + die $@ if $@; + + foreach my $cluster_id (@LJ::CLUSTERS) { + my $dbr = ($LJ::IS_DEV_SERVER) ? + LJ::get_cluster_reader($cluster_id) : LJ::DBUtil->get_inactive_db($cluster_id, $opts->{verbose}); + $coderef->($cluster_id, $dbr); + } +} + +sub bindstr { return join(', ', map { '?' } @_); } # when calling a supported function (currently: LJ::load_user() or LJ::load_userid*) # ignores in-process request cache, memcache, and selects directly @@ -253,6 +271,135 @@ return $sb->(); } +# returns the DBI::Role role name of a cluster master given a clusterid +sub master_role { + my $id = shift; + my $role = "cluster${id}"; + if (my $ab = $LJ::CLUSTER_PAIR_ACTIVE{$id}) { + $ab = lc($ab); + # master-master cluster + $role = "cluster${id}${ab}" if $ab eq "a" || $ab eq "b"; + } + return $role; +} + +sub dbtime_callback { + my ($dsn, $dbtime, $time) = @_; + my $diff = abs($dbtime - $time); + if ($diff > 2) { + $dsn =~ /host=([^:\;\|]*)/; + my $db = $1; + print STDERR "Clock skew of $diff seconds between web($LJ::SERVER_NAME) and db($db)\n"; + } +} + +# <LJFUNC> +# name: LJ::DB::get_dbirole_dbh +# class: db +# des: Internal function for get_dbh(). Uses the DBIRole to fetch a dbh, with +# hooks into db stats-generation if that's turned on. +# info: +# args: opts, role +# des-opts: A hashref of options. +# des-role: The database role. +# returns: A dbh. +# </LJFUNC> +sub get_dbirole_dbh { + my $dbh = $LJ::DBIRole->get_dbh( @_ ) or return undef; + + if ( $LJ::DB_LOG_HOST && $LJ::HAVE_DBI_PROFILE ) { + $LJ::DB_REPORT_HANDLES{ $dbh->{Name} } = $dbh; + + # :TODO: Explain magic number + $dbh->{Profile} ||= "2/DBI::Profile"; + + # And turn off useless (to us) on_destroy() reports, too. + undef $DBI::Profile::ON_DESTROY_DUMP; + } + + return $dbh; +} + +# <LJFUNC> +# name: LJ::DB::get_lock +# des: get a MySQL lock on a given key/dbrole combination. +# returns: undef if called improperly, true on success, die() on failure +# args: db, dbrole, lockname, wait_time? +# des-dbrole: the role this lock should be gotten on, either 'global' or 'user'. +# des-lockname: the name to be used for this lock. +# des-wait_time: an optional timeout argument, defaults to 10 seconds. +# </LJFUNC> +sub get_lock +{ + my ($db, $dbrole, $lockname, $wait_time) = @_; + return undef unless $db && $lockname; + return undef unless $dbrole eq 'global' || $dbrole eq 'user'; + + my $curr_sub = (caller 1)[3]; # caller of current sub + + # die if somebody already has a lock + die "LOCK ERROR: $curr_sub; can't get lock from: $LJ::LOCK_OUT{$dbrole}\n" + if exists $LJ::LOCK_OUT{$dbrole}; + + # get a lock from mysql + $wait_time ||= 10; + $db->do("SELECT GET_LOCK(?,?)", undef, $lockname, $wait_time) + or return undef; + + # successfully got a lock + $LJ::LOCK_OUT{$dbrole} = $curr_sub; + return 1; +} + +# <LJFUNC> +# name: LJ::DB::release_lock +# des: release a MySQL lock on a given key/dbrole combination. +# returns: undef if called improperly, true on success, die() on failure +# args: db, dbrole, lockname +# des-dbrole: role on which to get this lock, either 'global' or 'user'. +# des-lockname: the name to be used for this lock +# </LJFUNC> +sub release_lock +{ + my ($db, $dbrole, $lockname) = @_; + return undef unless $db && $lockname; + return undef unless $dbrole eq 'global' || $dbrole eq 'user'; + + # get a lock from mysql + $db->do("SELECT RELEASE_LOCK(?)", undef, $lockname); + delete $LJ::LOCK_OUT{$dbrole}; + + return 1; +} + +# <LJFUNC> +# name: LJ::DB::disconnect_dbs +# des: Clear cached DB handles +# </LJFUNC> +sub disconnect_dbs { + # clear cached handles + $LJ::DBIRole->disconnect_all( { except => [qw(logs)] }); +} + +# <LJFUNC> +# name: LJ::DB::use_diff_db +# class: +# des: given two DB roles, returns true only if it is certain the two roles are +# served by different database servers. +# info: This is useful for, say, the moveusercluster script: You would not want +# to select something from one DB, copy it into another, and then delete it from the +# source if they were both the same machine. +# args: +# des-: +# returns: +# </LJFUNC> +sub use_diff_db { + $LJ::DBIRole->use_diff_db(@_); +} + + +package LJ; + # <LJFUNC> # name: LJ::get_dbh # class: db @@ -293,7 +440,7 @@ # let site admin turn off global master write access during # maintenance return $nodb->([@_]) if $LJ::DISABLE_MASTER && $role eq "master"; - my $db = LJ::get_dbirole_dbh($opts, $role); + my $db = LJ::DB::get_dbirole_dbh( $opts, $role ); return $db if $db; } return $nodb->([@_]); @@ -347,7 +494,7 @@ my $id = isu($arg) ? $arg->{'clusterid'} : $arg; return LJ::get_cluster_reader(@dbh_opts, $id) if $LJ::DEF_READER_ACTUALLY_SLAVE{$id}; - return LJ::get_dbh(@dbh_opts, LJ::master_role($id)); + return LJ::get_dbh( @dbh_opts, LJ::DB::master_role($id) ); } # <LJFUNC> @@ -365,158 +512,9 @@ my $arg = shift; my $id = isu($arg) ? $arg->{'clusterid'} : $arg; return undef if $LJ::READONLY_CLUSTER{$id}; - return LJ::get_dbh(@dbh_opts, LJ::master_role($id)); + return LJ::get_dbh( @dbh_opts, LJ::DB::master_role($id) ); } -# returns the DBI::Role role name of a cluster master given a clusterid -sub master_role { - my $id = shift; - my $role = "cluster${id}"; - if (my $ab = $LJ::CLUSTER_PAIR_ACTIVE{$id}) { - $ab = lc($ab); - # master-master cluster - $role = "cluster${id}${ab}" if $ab eq "a" || $ab eq "b"; - } - return $role; -} - -# <LJFUNC> -# name: LJ::get_dbirole_dbh -# class: db -# des: Internal function for get_dbh(). Uses the DBIRole to fetch a dbh, with -# hooks into db stats-generation if that's turned on. -# info: -# args: opts, role -# des-opts: A hashref of options. -# des-role: The database role. -# returns: A dbh. -# </LJFUNC> -sub get_dbirole_dbh { - my $dbh = $LJ::DBIRole->get_dbh( @_ ) or return undef; - - if ( $LJ::DB_LOG_HOST && $LJ::HAVE_DBI_PROFILE ) { - $LJ::DB_REPORT_HANDLES{ $dbh->{Name} } = $dbh; - - # :TODO: Explain magic number - $dbh->{Profile} ||= "2/DBI::Profile"; - - # And turn off useless (to us) on_destroy() reports, too. - undef $DBI::Profile::ON_DESTROY_DUMP; - } - - return $dbh; -} - -# <LJFUNC> -# name: LJ::get_lock -# des: get a MySQL lock on a given key/dbrole combination. -# returns: undef if called improperly, true on success, die() on failure -# args: db, dbrole, lockname, wait_time? -# des-dbrole: the role this lock should be gotten on, either 'global' or 'user'. -# des-lockname: the name to be used for this lock. -# des-wait_time: an optional timeout argument, defaults to 10 seconds. -# </LJFUNC> -sub get_lock -{ - my ($db, $dbrole, $lockname, $wait_time) = @_; - return undef unless $db && $lockname; - return undef unless $dbrole eq 'global' || $dbrole eq 'user'; - - my $curr_sub = (caller 1)[3]; # caller of current sub - - # die if somebody already has a lock - die "LOCK ERROR: $curr_sub; can't get lock from: $LJ::LOCK_OUT{$dbrole}\n" - if exists $LJ::LOCK_OUT{$dbrole}; - - # get a lock from mysql - $wait_time ||= 10; - $db->do("SELECT GET_LOCK(?,?)", undef, $lockname, $wait_time) - or return undef; - - # successfully got a lock - $LJ::LOCK_OUT{$dbrole} = $curr_sub; - return 1; -} - -# <LJFUNC> -# name: LJ::release_lock -# des: release a MySQL lock on a given key/dbrole combination. -# returns: undef if called improperly, true on success, die() on failure -# args: db, dbrole, lockname -# des-dbrole: role on which to get this lock, either 'global' or 'user'. -# des-lockname: the name to be used for this lock -# </LJFUNC> -sub release_lock -{ - my ($db, $dbrole, $lockname) = @_; - return undef unless $db && $lockname; - return undef unless $dbrole eq 'global' || $dbrole eq 'user'; - - # get a lock from mysql - $db->do("SELECT RELEASE_LOCK(?)", undef, $lockname); - delete $LJ::LOCK_OUT{$dbrole}; - - return 1; -} - -# <LJFUNC> -# name: LJ::disconnect_dbs -# des: Clear cached DB handles -# </LJFUNC> -sub disconnect_dbs { - # clear cached handles - $LJ::DBIRole->disconnect_all( { except => [qw(logs)] }); -} - -# <LJFUNC> -# name: LJ::use_diff_db -# class: -# des: given two DB roles, returns true only if it is certain the two roles are -# served by different database servers. -# info: This is useful for, say, the moveusercluster script: You would not want -# to select something from one DB, copy it into another, and then delete it from the -# source if they were both the same machine. -# args: -# des-: -# returns: -# </LJFUNC> -sub use_diff_db { - $LJ::DBIRole->use_diff_db(@_); -} - -sub dbtime_callback { - my ($dsn, $dbtime, $time) = @_; - my $diff = abs($dbtime - $time); - if ($diff > 2) { - $dsn =~ /host=([^:\;\|]*)/; - my $db = $1; - print STDERR "Clock skew of $diff seconds between web($LJ::SERVER_NAME) and db($db)\n"; - } -} - -sub foreach_cluster { - my $coderef = shift; - my $opts = shift || {}; - - # have to include this via an eval so it doesn't actually get included - # until someone calls foreach cluster. at which point, if they're in web - # context, it will fail. - eval "use LJ::DBUtil; 1;"; - die $@ if $@; - - foreach my $cluster_id (@LJ::CLUSTERS) { - my $dbr = ($LJ::IS_DEV_SERVER) ? - LJ::get_cluster_reader($cluster_id) : LJ::DBUtil->get_inactive_db($cluster_id, $opts->{verbose}); - $coderef->($cluster_id, $dbr); - } -} - - -sub isdb { return ref $_[0] && (ref $_[0] eq "DBI::db" || - ref $_[0] eq "Apache::DBI::db"); } - - -sub bindstr { return join(', ', map { '?' } @_); } package LJ::Error::Database::Unavailable; sub fields { qw(roles) } # arrayref of roles requested diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/ljlib.pl --- a/cgi-bin/ljlib.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/ljlib.pl Fri Sep 30 00:14:15 2011 +0800 @@ -1388,7 +1388,7 @@ { LJ::work_report_end(); LJ::flush_cleanup_handlers(); - LJ::disconnect_dbs() if $LJ::DISCONNECT_DBS; + LJ::DB::disconnect_dbs() if $LJ::DISCONNECT_DBS; LJ::MemCache::disconnect_all() if $LJ::DISCONNECT_MEMCACHE; return 1; } @@ -1511,7 +1511,7 @@ # </LJFUNC> sub load_talk_props2 { - my $db = isdb($_[0]) ? shift @_ : undef; + my $db = LJ::DB::isdb( $_[0] ) ? shift @_ : undef; my ($uuserid, $listref, $hashref) = @_; my $userid = want_userid($uuserid); @@ -2169,7 +2169,7 @@ sub error { my $err = shift; - if (isdb($err)) { + if ( LJ::DB::isdb( $err ) ) { $LJ::db_error = $err->errstr; $err = "db"; } elsif ($err eq "db") { diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/ljprotocol.pl --- a/cgi-bin/ljprotocol.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/ljprotocol.pl Fri Sep 30 00:14:15 2011 +0800 @@ -2430,9 +2430,9 @@ } ## load the text - my $text = LJ::cond_no_cache($use_master, sub { - return LJ::get_logtext2($uowner, @itemids); - }); + my $text = LJ::DB::cond_no_cache( $use_master, sub { + return LJ::get_logtext2( $uowner, @itemids ); + } ); foreach my $i (@itemids) { diff -r e86ea43504da -r 5cf79cb7d354 cgi-bin/ljrelation.pl --- a/cgi-bin/ljrelation.pl Thu Sep 29 17:44:58 2011 +0800 +++ b/cgi-bin/ljrelation.pl Fri Sep 30 00:14:15 2011 +0800 @@ -50,7 +50,7 @@ # </LJFUNC> sub load_rel_user { - my $db = isdb($_[0]) ? shift : undef; + my $db = LJ::DB::isdb( $_[0] ) ? shift : undef; my ($userid, $type) = @_; return undef unless $type and $userid; my $u = LJ::want_user($userid); @@ -114,7 +114,7 @@ # </LJFUNC> sub load_rel_target { - my $db = isdb($_[0]) ? shift : undef; + my $db = LJ::DB::isdb( $_[0] ) ? shift : undef; my ($targetid, $type) = @_; return undef unless $type and $targetid; my $u = LJ::want_user($targetid); diff -r e86ea43504da -r 5cf79cb7d354 t/assertions.t --- a/t/assertions.t Thu Sep 29 17:44:58 2011 +0800 +++ b/t/assertions.t Fri Sep 30 00:14:15 2011 +0800 @@ -25,7 +25,7 @@ { local $u->{user} = "systemNOT"; eval { - my $u2 = LJ::require_master(sub { LJ::load_userid($u->{userid}) }); + my $u2 = LJ::DB::require_master( sub { LJ::load_userid($u->{userid}) } ); }; like($@, qr/AssertIs/); } diff -r e86ea43504da -r 5cf79cb7d354 t/uniqcookie.t --- a/t/uniqcookie.t Thu Sep 29 17:44:58 2011 +0800 +++ b/t/uniqcookie.t Fri Sep 30 00:14:15 2011 +0800 @@ -121,10 +121,10 @@ ok($last_delete_ct == 15, "deleted correct number of rows by user"); # shouldn't clean this time around - LJ::no_cache(sub { + LJ::DB::no_cache( sub { $class->clear_request_cache; $class->load_mapping( user => $u ); - }); + } ); ok($last_delete_ct == 0, "loaded by user without redundant cleaning"); @@ -148,10 +148,10 @@ ok($last_delete_ct == 15, "deleted correct number of rows by uniq"); # shouldn't clean this time around - LJ::no_cache(sub { + LJ::DB::no_cache( sub { $class->clear_request_cache; $class->load_mapping( uniq => $uniq ); - }); + } ); ok($last_delete_ct == 0, "loaded by uniq without redundant cleaning"); } diff -r e86ea43504da -r 5cf79cb7d354 t/userloading.t --- a/t/userloading.t Thu Sep 29 17:44:58 2011 +0800 +++ b/t/userloading.t Fri Sep 30 00:14:15 2011 +0800 @@ -54,19 +54,19 @@ $name = "My name is " . rand(); $dbh->do("UPDATE user SET name=? WHERE userid=?", undef, $name, $u->{userid}); - $u = LJ::require_master(sub { LJ::load_user($u->{user}) }); + $u = LJ::DB::require_master( sub { LJ::load_user($u->{user}) } ); is($u->{name}, $name, "name correct after change + load_user"); $name = "My name is " . rand(); $dbh->do("UPDATE user SET name=? WHERE userid=?", undef, $name, $u->{userid}); - $u = LJ::require_master(sub { LJ::load_userid($u->{userid}) }); + $u = LJ::DB::require_master( sub { LJ::load_userid($u->{userid}) } ); is($u->{name}, $name, "name correct after change + load_user"); $name = "My name is " . rand(); $dbh->do("UPDATE user SET name=? WHERE userid=?", undef, $name, $u->{userid}); - my $users = LJ::require_master(sub { LJ::load_userids($u->{userid}) }); + my $users = LJ::DB::require_master( sub { LJ::load_userids($u->{userid}) } ); $u = $users->{$u->{userid}}; is($u->{name}, $name, "name correct after change + load_user"); } --------------------------------------------------------------------------------