[Fswiki-dev] 世代バックアップ実装

Back to archive index

typer typer_jp****@yahoo*****
2003年 11月 20日 (木) 02:36:11 JST


ども。tyepr.加藤です。
世代バックアップモジュールを作って忘れてました。話題に上がったので送ります。
とりあえず世代数は有限で、ソース頭の$gen_numで指定します。
configファイル中で指定/変更できるようにすれば子Wiki毎に変更可能になりますね。

ページを消したあと、同じページ名で新規作成しても前の履歴は消えたように見えます。
しかし、ファイルとしては残っていますので手動での復帰もできます。

実装はDefaultStrage.pmを継承し、最低限の部分だけ変更しています。
方法は単純にリネームでファイルを"ずらして"いくやりかたです。
最大100世代の指定だと(実際にはなくとも)100回リネームを試みます。
保存場所もすべてbackupディレクトリにフラットにおきますので、
多量のページがある場合に多量の世代を残す設定にすると負荷が大きくなると
おもいます。この辺り、改善の余地があるかもしれません。

一応、完全ではないですが、簡単なファイルロック機構をつけています。
これは同じタイミングで同じページを更新すると、1世代消え、履歴が消えたよ
うに見える可能性があるためです。
ファイルロック機構によりこの可能性を低くします。

ソースは以下です。煮るなり焼くなり好きにして下さい。
lib/Wiki/HistoricalStorage.pmとして保存して下さい。
ここから->
###############################################################################
#
# 複数世代バックアップ付きストレージプラグイン
#
###############################################################################
package Wiki::HistoricalStorage;
#use strict;
use Wiki::DefaultStorage;
use vars qw(@ISA);
@ISA=qw(Wiki::DefaultStorage);
#==============================================================================
# 保存するバックアップの世代数(必ず2以上)を指定
#==============================================================================
use vars qw($gen_num);
$gen_num=10;
#==============================================================================
# ページを保存
#==============================================================================
sub save_page {
	my $self = shift;
	my $page = shift;
	my $content = shift;

	# 世代交替
	my $count = $gen_num-1;
	my $backup_dir = $self->{wiki}->config('backup_dir');
	my $enc_page = &Util::url_encode($page);
	my $new = &Util::make_filename($backup_dir,$enc_page,"0");
	my $old = &Util::make_filename($backup_dir,$enc_page,"bak");
	rename $old,$new
	# ファイルロックもどき。下をコメントアウトすれば無効になる。
	# ただし、履歴が消える可能性が高くなる。
	  or -e $new and die "Conflict error: now locking!"
	;
	while($count > 0){
		$new = &Util::make_filename($backup_dir,$enc_page,$count);
		$old = &Util::make_filename($backup_dir,$enc_page,--$count);
		rename $old,$new;
	}
	# 元のメソッドを呼び出す
	$self->SUPER::save_page($page,$content);
}

#==============================================================================
# バックアップタイプを取得(single|all)
#==============================================================================
sub backup_type {
	return "all";
}

#==============================================================================
# バックアップ時刻の一覧を取得します。
#==============================================================================
sub get_backup_list {
	my $self = shift;
	my $page = shift;
	my $backup_dir = $self->{wiki}->config('backup_dir');
	my $enc_page = &Util::url_encode($page);
	my @result;
	foreach my $filename ("bak",1..$gen_num-1){
		$_ = &Util::make_filename($backup_dir,$enc_page,$filename);
		-f or last;
		push @result,&Util::format_date((stat _)[9]);
	}
	return @result;
}

#==============================================================================
# バックアップを取得します。
# ※backup_type=allの場合は第二引数で世代(0〜)を指定します。
#==============================================================================
sub get_backup {
	my $self = shift;
	my $page = shift;
	my $gen  = shift;
	my $content = "";
	my $ext;

	if($gen > 0){
		$ext = $gen-0;
	} else {
		$ext = "bak";
	}
	my $filename = &Util::make_filename($self->{wiki}->config('backup_dir'),&Util::url_encode($page),$ext);
	if(-e $filename){
		open(DATA,$filename) or die $!;
		binmode(DATA);
		while(<DATA>){
			$content = $content.$_;
		}
		close(DATA);
	}
	return $content;
}

1;
->ここまで
-- 
typer        typer_jp****@yahoo***** 
Noboru Katoh typer****@goenn*****
gpg fingerprint = 836E BAC6 9050 EEC7 01F7  9F1E EC1C 3259 2ED0 9FB2



Fswiki-dev メーリングリストの案内
Back to archive index