Subject: | It would be useful (faster) if differences() could accept (and return) cached node data |
I am currently working around this using the very simple
CGI::Wiki::Plugin::Diff wrapper I've attached, but it would be very
useful if CGI::Wiki::Plugin::Diff could work with cached nodes as my
wrapper demonstrates.
Both covered cases, where some or all of the node data has already been
retrieved and where someone using the plugin might want to display some
additional data from the retrieved nodes must be fairly common.
Avoiding the additional DBI lookup is much faster.
I should be releasing a new CGI::Wiki based wiki soon and it would be
nice if I didn't have to distribute such a simple
CGI::Wiki::Plugin::Diff wrapper with it.
Subject: | XimbiotPluginDiff.pm |
package XimbiotPluginDiff;
use strict;
use vars qw($VERSION @ISA);
use CGI::Wiki::Plugin::Diff;
use Params::Validate::Dummy ();
use Module::Optional qw(Params::Validate
validate validate_pos SCALAR SCALARREF ARRAYREF HASHREF UNDEF);
@ISA = qw(CGI::Wiki::Plugin::Diff);
$VERSION = 0.01;
=head1 NAME
XimbiotPluginDiff - Implementation of CGI::Wiki::Plugin::Diff which caches
the retrieved node data for use by the caller.
=head1 REQUIRES
Subclasses CGI::Wiki::Plugin::Diff
=head1 SYNOPSIS
See CGI::Wiki::Plugin::Diff
=head1 METHODS
=over 4
=item B<differences>
Like the parent method of the same name, except if either left_version or
right_version is found to be a reference, it is assumed to be cached
revision information as returned by the CGI::Wiki::Database::retrieve_node
method. Also, two extra fields will be present in the output hash,
left_revision & right_revision, which will contain references to the hashes
returned by retrieve node for each version (the same ones passed into the
function, when such is passed).
=cut
sub differences
{
my $self = shift;
my %args = validate (@_, {node => {type => SCALAR},
left_version => {type => SCALAR | HASHREF},
right_version => {type => SCALAR | HASHREF},
meta_include => {type => ARRAYREF,
optional => 1},
meta_exclude => {type => ARRAYREF,
optional => 1}});
my ($node, $v1, $v2) = @args{qw(node left_version right_version)};
my $store = $self->datastore;
my $fmt = $self->formatter;
$v1 = {$store->retrieve_node (name => $node, version => $v1)}
unless ref $v1;
$v2 = {$store->retrieve_node (name => $node, version => $v2)}
unless ref $v2;
my $verstring1 = "Version " . $v1->{version};
my $verstring2 = "Version " . $v2->{version};
my $el1 = VCS::Lite->new
($verstring1, undef,
$self->content_escape ($v1->{content})
. $self->{metadata_separator}
. $self->serialise_metadata ($v1->{metadata},
@args{qw(meta_include meta_exclude)}));
my $el2 = VCS::Lite->new
($verstring2, undef,
$self->content_escape ($v2->{content})
. $self->{metadata_separator}
. $self->serialise_metadata ($v2->{metadata},
@args{qw(meta_include meta_exclude)}));
my %pag;
$pag{left_version} = $verstring1;
$pag{right_version} = $verstring2;
$pag{left_revision} = $v1;
$pag{right_revision} = $v2;
$pag{content} = $fmt->format ($v1->{content});
my $dlt = $el1->delta ($el2)
or return %pag;
my @out;
for ($dlt->hunks)
{
my ($lin1, $lin2, $out1, $out2);
for (@$_)
{
my ($ind, $line, $text) = @$_;
if ($ind ne '+')
{
$lin1 ||= $line;
$out1 .= $text;
}
if ($ind ne '-')
{
$lin2 ||= $line;
$out2 .= $text;
}
}
push @out, {left => $self->line_number ($lin1),
right => $self->line_number ($lin2)};
my ($text1,$text2) = $self->intradiff ($out1, $out2);
push @out, {left => $text1, right => $text2};
}
$pag{diff} = \@out;
return %pag;
}