From b4eccdb413df6e434f04426759a5cfb40912424c Mon Sep 17 00:00:00 2001 From: Alex Schroeder Date: Sat, 26 Jun 2004 00:00:31 +0000 Subject: [PATCH] (WriteLinkDb): Removed lock. (DoLinkDb): Added Lock. (RefreshLinkDb): Rewrite. It was full of bugs. (NewNotFoundHandlerSave): Rewrite. (NotFoundHandlerCacheUpdate): Rewrite. --- modules/not-found-handler.pl | 54 ++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/modules/not-found-handler.pl b/modules/not-found-handler.pl index bcdd852e..e649a561 100644 --- a/modules/not-found-handler.pl +++ b/modules/not-found-handler.pl @@ -16,7 +16,7 @@ # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA -$ModulesDescription .= '

$Id: not-found-handler.pl,v 1.5 2004/06/13 14:46:50 as Exp $

'; +$ModulesDescription .= '

$Id: not-found-handler.pl,v 1.6 2004/06/26 00:00:31 as Exp $

'; use vars qw($NotFoundHandlerDir, $LinkFile, %LinkDb, $LinkDbInit); @@ -39,15 +39,14 @@ sub DoClearCache { sub ReadLinkDb { return if $LinkDbInit; $LinkDbInit = 1; + return if not -f $LinkFile; my $data = ReadFileOrDie($LinkFile); map { my ($id, @links) = split; $LinkDb{$id} = \@links } split(/\n/, $data); } -sub WriteLinkDb { +sub WriteLinkDb { # call within the main lock! my $str = join("\n", map { join(' ', $_, @{$LinkDb{$_}}) } keys %LinkDb); - RequestLockOrError(); # fatal WriteStringToFile($LinkFile, $str); - ReleaseLock(); return $str; } @@ -55,17 +54,36 @@ sub WriteLinkDb { sub DoLinkDb { print GetHeader('', QuoteHtml(T('Generating Link Database')), ''); + RequestLockOrError(); # fatal %LinkDb = %{GetFullLinkList(1, 0, 0, 1)}; print $q->pre(WriteLinkDb()); + ReleaseLock(); PrintFooter(); } # refresh link database with data from the current open page sub RefreshLinkDb { + if (not defined(&GetLinkList)) { + ReportError(T('The 404 handler extension requires the link data extension (links.pl).')); + return; + } + if ($Page{revision} > 0 and not ($Page{blocks} && $Page{flags})) { # + # make sure we have a cache! We just discard this output, because + # in a multilingual setting we would need to determine the correct + # filename in which to store it in order to get headers + # etc. right. + *P = STDOUT; + PrintWikiToHTML($Page{text}, 1, 0, 1); # revision 0, is already locked + *STDOUT = *P; + } + my @links = GetLinkList(1, 0, 0, 1); # works on cached blocks... ReadLinkDb(); - my @links = GetLinkList(1, 0, 0, 1); - $LinkDb{$OpenPageName} = \@links; + if (@links) { + $LinkDb{$OpenPageName} = \@links; + } else { + delete $LinkDb{$OpenPageName}; + } WriteLinkDb(); } @@ -79,8 +97,9 @@ sub NewNotFoundHandlerSave { my $id = $args[0]; OldNotFoundHandlerSave(@args); RefreshLinkDb(); # for the open page - mkdir($NotFoundHandlerDir) unless -d $NotFoundHandlerDir; - if ($Page{revision} == 1) { + if (not -d $NotFoundHandlerDir) { + mkdir($NotFoundHandlerDir); + } elsif ($Page{revision} == 1) { NotFoundHandlerCacheUpdate($id); } else { # unlink PageName, PageName.en, PageName.de, etc. @@ -93,14 +112,25 @@ sub NotFoundHandlerCacheUpdate { # new or deleted page: regenerate all pages that link to this page, # or to the permanent anchors defined on this page. ReadLinkDb(); - my @pages = @{$LinkDb{$id}}; + # we will check for the current page, and for all the anchors defined on it. + my @targets = ($id); if ($PermanentAnchors) { foreach ($Page{text} =~ m/\[::$FreeLinkPattern\]/g) { - push(@pages, @{$LinkDb{$1}}); # harmless: potentially adds duplicates + push(@targets, $1); # harmless: potentially adds duplicates } } - foreach my $page (@pages) { - unlink("$NotFoundHandlerDir/$page", glob("$NotFoundHandlerDir/$page.[a-z][a-z]")); + # if any of the potential targets is the target of a link in the + # link database, then the source page must be rendered anew. in + # other words, delete the cached version of the source page. + my $target = '^(' . join('|', @targets) . ')$'; + warn "Unlinking pages pointing to $target\n"; + $target = qr($target); + foreach my $source (keys %LinkDb) { + warn "Examining $source\n"; + if (grep(/$target/, @{$LinkDb{$source}})) { + unlink("$NotFoundHandlerDir/$source", glob("$NotFoundHandlerDir/$source.[a-z][a-z]")); + warn "Unlinking $source\n"; + } } }