/usr/local/CPAN/CGI-Kwiki/CGI/Kwiki/Backup/SVNPerl.pm
package CGI::Kwiki::Backup::SVNPerl;
$VERSION = '0.01';
use strict;
use base 'CGI::Kwiki::Backup::SVN';
use File::Spec;
use SVN::Core '0.28';
use SVN::Repos;
use SVN::Fs;
use SVN::Delta;
use SVN::Simple::Edit;
use Text::Diff ();
use constant SVN_DIR => 'metabase/svn';
my $user_name = '';
my ($repos, $fs, $pool, $init);
sub init {
my $self = shift;
$pool = SVN::Pool->new_default;
if (-d SVN_DIR) {
$repos = SVN::Repos::open (SVN_DIR);
}
else {
$repos = SVN::Repos::create(SVN_DIR, undef, undef,
undef, undef);
my $edit = $self->_get_edit ('kwiki-install', 'kwiki install');
$edit->open_root (0);
for my $page_id ($self->database->pages) {
$edit->add_file ($page_id);
open my $fh, $self->database->file_path($page_id);
$edit->modify_file ($page_id, $fh)
}
$edit->close_edit;
}
$fs = $repos->fs;
++$init;
}
sub new {
my ($class) = shift;
my $self = $class->SUPER::new(@_);
$self->init unless $init;
$self->{pool} = SVN::Pool->new_default_sub();
$self->{headrev} = $fs->youngest_rev;
return $self;
}
sub _get_edit {
my ($self, $author, $comment, $pool) = @_;
SVN::Simple::Edit->new (_editor => [SVN::Repos::get_commit_editor
($repos, '', '/', $author,
$comment, sub {})],
pool => $pool || SVN::Pool->new ($pool));
}
sub commit {
my ($self, $page_id) = @_;
my $edit = $self->_get_edit ($user_name || $self->metadata->edit_by, '',
$self->{pool});
$edit->open_root ($self->{headrev});
if ($self->database->exists ($page_id)) {
open my $fh, $self->database->file_path ($page_id);
$edit->modify_file ($self->has_history ($page_id) ?
$edit->open_file ($page_id) :
$edit->add_file ($page_id),
$fh);
}
else {
$edit->delete_entry ($page_id);
}
$edit->close_edit();
}
sub has_history {
my ($self, $page_id) = @_;
$page_id ||= $self->cgi->page_id;
my $root = $fs->revision_root($self->{headrev});
SVN::Fs::check_path($root, $page_id) == $SVN::Core::node_file;
}
sub history {
my ($self, $page_id) = @_;
$page_id ||= $self->cgi->page_id;
return [] unless $page_id;
my $revs = SVN::Repos::revisions_changed ($fs, $page_id, 0,
$self->{headrev}, 0);
my $history = [map {
{ revision => $_,
edit_by => $fs->revision_prop($_, 'svn:author'),
date => $fs->revision_prop($_, 'svn:date')}} @$revs];
return $self->_build_history($history);
}
sub fetch {
my ($self, $page_id, $revision) = @_;
my $root = $fs->revision_root($revision || $self->{headrev});
my $stream = SVN::Fs::file_contents($root, $page_id);
local $/;
return <$stream>;
}
sub diff {
my ($self, $page_id, $r1, $r2, $context) = @_;
my $root1 = $fs->revision_root ($r1);
my $root2 = $fs->revision_root ($r2);
Text::Diff::diff(SVN::Fs::file_contents($root1, $page_id),
SVN::Fs::file_contents($root2, $page_id),
{ STYLE => "Unified" });
}
1;