論理削除

削除フラグによる論理削除

削除したレコードを後で確認したい時がありました。
物理的に削除してしまうと、登録された形跡もない。
削除フラグが立っていないレコードのみ表示する方法で削除を実現します。
削除フラグの1バイトだけ更新するので、わざわざ全レコードを書込み直す事はしない。


仕様

・フィールドは「,」で区切る。
・第1フィールドはそのレコードのキーとする。
・第2フィールドを削除フィールドとする。
・削除該当レコードは、キーで検索する。
・削除フィールドの更新は、seek で位置を指定し1バイト更新する。


テスト1

ではさっそくテスト
キーの指定は、いろいろ試してみたいのでパラメータにしてみた。

<<ソース>>
#!/usr/bin/perl

$keyno = @ARGV[0];			#更新対象レコードのキー
open(FL,"+<data.txt");
$wk = 0;
while(<FL>){
        if(/^$keyno\,/) {		#該当のレコード
		print $_;
		print "$wk\n";
		seek(FL,($wk+6),0);	#更新位置をセット
		print FL "1";	#削除フラグを書込み
		last;
	}
	$wk = tell(FL);		#次のレコードの先頭位置
}
close(FL);
exit(0);

<<実行してみる>>
naru@KURO-BOX:~/test$ cat data.txt
00001,0,12345
00002,0,aaaaaaaa
00003,0,bbbbbbbbbbb
00004,0,ccccc
00005,0,d

naru@KURO-BOX:~/test$ ./test1.pl 00004
00004,0,ccccc
51
naru@KURO-BOX:~/test$ cat data.txt
00001,0,12345
00002,0,aaaaaaaa
00003,0,bbbbbbbbbbb
00004,1,ccccc
00005,0,d

おおー。ちゃんと更新されているみたい。
あ、キーが5桁超えたらまずい・・・。


テスト2

キーの桁数とカンマの次の位置を更新する様に変更。

<<ソース>>
#!/usr/bin/perl

$keyno = @ARGV[0];			#更新対象レコードのキー
open(FL,"+<data.txt");
$wk = 0;
while(<FL>){
        if(/^$keyno\,/) {		#該当のレコード
		print $_;
		print "$wk\n";
		seek(FL,($wk+length($keyno)+1),0);	#更新位置をセット
		print FL "1";	#削除フラグを書込み
		last;
	}
	$wk = tell(FL);		#次のレコードの先頭位置
}
close(FL);
exit(0);

<<実行してみる>>
naru@KURO-BOX:~/test$ cat data.txt
1,0,AA
2,0,BBBBB
10,0,CCCCCCC
20,0,DD
200,0,EEE
5000,0,FFFFFF

naru@KURO-BOX:~/test$ ./test2.pl 20
20,0,DD
30
naru@KURO-BOX:~/test$ cat data.txt
1,0,AA
2,0,BBBBB
10,0,CCCCCCC
20,1,DD
200,0,EEE
5000,0,FFFFFF

おおー。ちゃんと更新されている。
これでキーの桁数が変わってもOKだね。


応用例

掲示板の1行レス型のレスを削除するのに使えそう。