madeon (madeon) wrote in changelog,
madeon
madeon
changelog

[livejournal] r20540: LJSUP-9907: Navigation bar on daleyed en...

Committer: sbelyaev
LJSUP-9907: Navigation bar on daleyed entry pag
U   trunk/cgi-bin/LJ/DelayedEntry.pm
U   trunk/cgi-bin/LJ/Talk.pm
U   trunk/htdocs/go.bml
Modified: trunk/cgi-bin/LJ/DelayedEntry.pm
===================================================================
--- trunk/cgi-bin/LJ/DelayedEntry.pm	2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/cgi-bin/LJ/DelayedEntry.pm	2011-11-15 12:10:16 UTC (rev 20540)
@@ -951,6 +951,60 @@
                                      "ORDER BY is_sticky DESC, revptime $sql_limit");
 }
 
+sub get_first_entry {
+    my ( $journal, $userid ) = @_;
+    __assert($journal, "no journal");
+
+    my $dbcr = LJ::get_cluster_def_reader($journal)
+        or die "get cluster for journal failed";
+
+    my $u;
+    my $sql_poster = '';
+
+    unless ($userid) {
+        $u = LJ::get_remote();
+    } else {
+        $u = LJ::want_user($userid);
+    }
+
+    return 0 unless $u;
+    if (!__delayed_entry_can_see( $journal, $u ) ){
+        $sql_poster = 'AND posterid = ' . $u->userid . " ";
+    }
+
+    my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+                                      "FROM delayedlog2 WHERE journalid=?  $sql_poster".
+                                      "ORDER BY is_sticky ASC, revptime DESC LIMIT 1", undef, $journal->userid);
+    return $id || 0;
+}
+
+sub get_last_entry {
+    my ( $journal, $userid ) = @_;
+    __assert($journal, "no journal");
+
+    my $dbcr = LJ::get_cluster_def_reader($journal)
+        or die "get cluster for journal failed";
+
+    my $u;
+    my $sql_poster = '';
+    unless ($userid) {
+        $u = LJ::get_remote();
+    } else {
+        $u = LJ::want_user($userid);
+    }
+
+    return 0 unless $u;
+    if (!__delayed_entry_can_see( $journal, $u ) ){
+        $sql_poster = 'AND posterid = ' . $u->userid . " ";
+    }
+
+    my ($id) = $dbcr->selectrow_array("SELECT delayedid " .
+                                      "FROM delayedlog2 WHERE journalid=?  $sql_poster".
+                                      "ORDER BY is_sticky DESC, revptime ASC LIMIT 1", undef, $journal->userid);
+    return $id || 0;
+}
+
+
 sub get_daycount_query {
     my ($class, $journal, $list, $secwhere) = @_;
     my $dbcr = LJ::get_cluster_def_reader($journal);
@@ -1148,12 +1202,16 @@
 
 sub get_itemid_near2 {
     my ($u, $delayedid, $after_before) = @_;
-    
-    my ($order, $cmp1, $cmp2, $cmp3, $cmp4);
+
+    my $jid    = $u->userid;
+    my $remote = LJ::get_remote();
+    return 0 unless $remote;
+
+    my ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4);
     if ($after_before eq "after") {
-        ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
+        ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("DESC", "ASC", "<=", ">", sub {$a->[0] <=> $b->[0]}, sub {$b->[1] <=> $a->[1]} );
     } elsif ($after_before eq "before") {
-        ($order, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC",  ">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
+        ($order, $order_sticky, $cmp1, $cmp2, $cmp3, $cmp4) = ("ASC", "DESC",">=", "<", sub {$b->[0] <=> $a->[0]}, sub {$a->[1] <=> $b->[1]} );
     } else {
         return 0;
     }
@@ -1163,77 +1221,43 @@
         warn "Can't connect to cluster reader. Cluster: " . $u->clusterid;
         return 0;
     }
-
-    my $jid     = $u->userid;
-    my $field   = $u->is_person() ? "revptime" : "rlogtime";
-
-    my ($stime) = $dbr->selectrow_array(  "SELECT $field FROM delayedlog2 WHERE ".
-                                          "journalid=$jid AND delayedid=$delayedid");
+    
+    my ($stime, $is_current_sticky) = $dbr->selectrow_array( "SELECT revptime, is_sticky FROM delayedlog2 WHERE ".
+                                        "journalid=$jid AND delayedid=$delayedid");
     return 0 unless $stime;
 
-    my $secwhere = "AND security='public'";
-    my $remote   = LJ::get_remote();
-
-    if ($remote) {
-        if ($remote->userid == $jid) {
-            $secwhere = "";   # see everything
-        } elsif ($remote->is_person() || $remote->is_identity) {
-            my $gmask = LJ::get_groupmask($u, $remote);
-            $secwhere = "AND (security='public' OR (security='usemask' AND allowmask & $gmask))"
-            if $gmask;
-        }
+    my $sql_poster = '';
+    if (!__delayed_entry_can_see( $u, $remote ) ){
+        $sql_poster = 'AND posterid = ' . $remote->userid . " ";
     }
 
-    ##
-    ## We need a next/prev record in journal before/after a given time
-    ## Since several records may have the same time (time is rounded to 1 minute),
-    ## we're ordering them by jitemid. So, the SQL we need is
-    ##      SELECT * FROM log2
-    ##      WHERE journalid=? AND rlogtime>? AND jitmemid<?
-    ##      ORDER BY rlogtime, jitemid DESC
-    ##      LIMIT 1
-    ## Alas, MySQL tries to do filesort for the query.
-    ## So, we sort by rlogtime only and fetch all (2, 10, 50) records
-    ## with the same rlogtime (we skip records if rlogtime is different from the first one).
-    ## If rlogtime of all fetched records is the same, increase the LIMIT and retry.
-    ## Then we sort them in Perl by jitemid and takes just one.
-    ##
-    my $result_ref;
-    foreach my $limit (2, 10, 50, 100) {
-        $result_ref = $dbr->selectall_arrayref( "SELECT delayedid, $field FROM delayedlog2 use index (rlogtime,revptime) ".
-                                                "WHERE journalid=? AND $field $cmp1 ? AND delayedid <> ? ".
-                                                $secwhere. " ".
-                                                "ORDER BY $field $order LIMIT $limit",
-                                                undef, $jid, $stime, $delayedid
-        );
-
-        my %hash_times = ();
-        map {$hash_times{$_->[1]} = 1} @$result_ref;
-
-        # If we has one the only 'time' in $limit fetched rows,
-        # may be $limit cuts off our record. Increase the limit and repeat.
-        if (((scalar keys %hash_times) > 1) || (scalar @$result_ref) < $limit) {
-            my @result;
-
-            # Remove results with the same time but the jitemid is too high or low
-            if ($after_before eq "after") {
-                @result = grep { $_->[1] != $stime || $_->[0] > $delayedid } @$result_ref;
-            } elsif ($after_before eq "before") {
-                @result = grep { $_->[1] != $stime || $_->[0] < $delayedid } @$result_ref;
+    my $sql_item_rule = ''; 
+    if ($after_before eq "after") {
+        $sql_item_rule =  $is_current_sticky ? "(revptime $cmp1 ? AND is_sticky = 1 )" : 
+                                               "(revptime $cmp1 ? OR is_sticky = 1 )";
+    } else {
+        if ($is_current_sticky) {
+            my ($new_stime) = $dbr->selectrow_array("SELECT revptime " .
+                                                    "FROM delayedlog2 WHERE journalid=? $sql_poster AND is_sticky = 0 ".
+                                                    "ORDER BY revptime LIMIT 1", undef, $jid); 
+            if ($new_stime < $stime) {
+                $stime = $new_stime;
             }
-
-            # Sort result by jitemid and get our id from a top.
-            @result =  sort $cmp3 @result;
-
-            # Sort result by revttime
-            @result =  sort $cmp4 @result;
-
-            my $id = $result[0]->[0];
-            return 0 unless $id;
-            return $id;
+ 
+            $sql_item_rule = "(revptime $cmp1 ? )";
+        } else {
+            $sql_item_rule = "(revptime $cmp1 ? AND is_sticky = 0 )";
         }
+         
     }
-    return 0;
+
+    my $result_ref = $dbr->selectcol_arrayref(  "SELECT delayedid FROM delayedlog2 use index (rlogtime,revptime) ".
+                                                "WHERE journalid=? AND $sql_item_rule AND delayedid <> ? ".
+                                                $sql_poster. " ".
+                                                "ORDER BY is_sticky $order_sticky, revptime $order LIMIT 2",
+                                                undef, $jid, $stime, $delayedid);
+    return 0 unless $result_ref;
+    return $result_ref->[0];
 }
 
 sub handle_prefetched_props {

Modified: trunk/cgi-bin/LJ/Talk.pm
===================================================================
--- trunk/cgi-bin/LJ/Talk.pm	2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/cgi-bin/LJ/Talk.pm	2011-11-15 12:10:16 UTC (rev 20540)
@@ -128,11 +128,12 @@
         $entry = LJ::Entry->new($u, ditemid => $itemid);
     }
 
+    my $itemlnk = $entry->is_delayed ? "delayedid=" . $opts->{delayedid} :
+                                       "itemid=$itemid";
+
     # << Previous
-    if (!$entry->is_delayed) {
-        push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=prev", "prev_entry");
-        $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=prev' rel='Previous' />\n";
-    }
+    push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=prev", "prev_entry");
+    $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=prev' rel='Previous' />\n";
 
     # memories
     unless ($LJ::DISABLED{'memories'} || $entry->is_delayed) {
@@ -181,11 +182,8 @@
     }
 
     ## Next
-    if (!$entry->is_delayed)
-    {
-        push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=next", "next_entry");
-        $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}itemid=$itemid&amp;dir=next' rel='Next' />\n";
-    }
+    push @linkele, $mlink->("$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=next", "next_entry");
+    $$headref .= "<link href='$LJ::SITEROOT/go.bml?${jargent}$itemlnk&amp;dir=next' rel='Next' />\n";
 
     if (@linkele) {
         $ret .= BML::fill_template("standout", {

Modified: trunk/htdocs/go.bml
===================================================================
--- trunk/htdocs/go.bml	2011-11-15 11:12:11 UTC (rev 20539)
+++ trunk/htdocs/go.bml	2011-11-15 12:10:16 UTC (rev 20540)
@@ -22,7 +22,8 @@
 
  # prev/next talkread links
  my $itemid = $GET{'itemid'}+0;
- if ($GET{'journal'} && $itemid) 
+ my $delayedid = $GET{'delayedid'}+0;
+ if ($GET{'journal'} && ($itemid || $delayedid))  
  {
      my $journal = $GET{'journal'};
      my $u = LJ::load_user($journal);
@@ -36,19 +37,24 @@
 
      $itemid = int($itemid / 256);
      
-     my $jumpid = 0;
+     my $jumplink;
      $title = $ML{'.error.noentrytitle'};
+
+     my $options = { 'itemid'     => $itemid,
+                     'delayedid'  => $delayedid,
+                     'use_sticky' => 1 };
      
      if ($GET{'dir'} eq "next") {
-         $jumpid = LJ::get_itemid_after2($u, $itemid);
+         warn "itemid = " . LJ::get_itemid_after2($u, $itemid);
+         $jumplink = LJ::get_after_item_link($u, $options);
          $body = $ML{'.error.noentry.next'};
      } elsif ($GET{'dir'} eq "prev") {
-         $jumpid = LJ::get_itemid_before2($u, $itemid);
+         $jumplink = LJ::get_before_item_link($u, $options);
          $body = $ML{'.error.noentry.prev'};
      }
 
-     if ($jumpid) {
-         return BML::redirect(LJ::journal_base($u) . "/$jumpid.html");
+     if ($jumplink) {
+         return BML::redirect($jumplink);
      }
  }
 

Tags: bml, livejournal, madeon, pm, sbelyaev
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments