package Yuki::YukiWikiDBMeta; use strict; use Yuki::YukiWikiDBNS; our @ISA; push @ISA, q(Yuki::YukiWikiDBNS); our $VERSION = do{my @r=(q$Revision: 1.7 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; sub _write_meta ($$) { my ($self, $key) = @_; $self->_die (qq{_write_meta : method not allowd, mode="$self->{-mode}"}) if $self->{-mode} == 1; my $file=$key;&{$self->{-encode}}($file);$file=$self->{-dir}.'mt--'.$file.'.dat'; my $temp = $file.".".time; open (FILE, '>', $temp) or $self->_die(qq{_write_meta : Open "$temp" : $!}); binmode FILE; print FILE "#?SuikaWikiMetaInfo/0.9\n\x02".join "\x1E", map {$_."\x1F".$self->{-metainfo}->{$key}->{$_}} grep {length $self->{-metainfo}->{$key}->{$_}} keys %{$self->{-metainfo}->{$key}}; close FILE; if (-e $file) { unlink $file or $self->_die (qq{_write_meta : Remove "$file" : $!}); } #$self->_warn (qq(Temporary "$temp" => real "$file")); rename ($temp => $file) or $self->_die(qq{_write_meta : Rename "$temp" => "$file": $!}); } sub _read_meta ($$) { my ($self, $key) = @_; return if ref $self->{-metainfo}->{$key}; my $file=$key;&{$self->{-encode}}($file);$file=$self->{-dir}.'mt--'.$file.'.dat'; if (-e $file) { open (FILE, $file) or $self->_die (qq{_read_meta : $! "$file"}); binmode FILE; local $/ = undef; my $val = ; close FILE; if ($val =~ s!^\#\?SuikaWikiMetaInfo/0.9[^\x02]*\x02!!s) { $self->{-metainfo}->{$key} = {map {split /\x1F/, $_, 2} split /\x1E/, $val}; } else { $self->{-metainfo}->{$key} = {}; } } else { $self->{-metainfo}->{$key} = {}; } } sub STORE { my $self = shift; my ($key, $val, %option) = @_; $self->SUPER::STORE (@_); if (!exists $option{-touch} || $option{-touch}) { $self->_read_meta ('LastModified'); $self->{-metainfo}->{LastModified}->{$key} = time; $self->{-metainfo}->{-changed}->{LastModified} = 1; } $val; } sub UNTIE { my $self = shift; for (keys %{$self->{-metainfo}->{-changed}}) { $self->_write_meta ($_); } $self->SUPER::UNTIE (@_); } sub sort_by_mtime{ my ($self, $option) = (shift, shift || {}); my $dbname = $self->{-dir}; my @key = @_; if(not @key){ @key = $self->list_items ({%$option, type => 'key'}); } $self->_read_meta ('LastModified'); return map {$_->[1]} sort {$b->[0] <=> $a->[0] or $b->[1] cmp $a->[1]} map {[$self->{-metainfo}->{LastModified}->{$_},$_]} @key; } sub mtime ($$;$) { my ($self, $key, $val) = @_; $self->_read_meta ('LastModified'); if (defined $val) { $self->{-metainfo}->{LastModified}->{$key} = $val; $self->{-metainfo}->{-changed}->{LastModified} = 1; } $self->{-metainfo}->{LastModified}->{$key}; } sub meta ($$$;$) { my ($self, $metakey, $key, $val) = @_; $self->_read_meta ($metakey); if (defined $val) { $self->{-metainfo}->{$metakey}->{$key} = $val; $self->{-metainfo}->{-changed}->{$metakey} = 1; } $self->{-metainfo}->{$metakey}->{$key}; } 1; __END__ =head1 NAME Yuki::YukiWikiDBMeta --- SuikaWiki: YukiWikiDB2 with meta information extension =head1 LICENSE Copyright 2003 Wakaba This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut # $Date: 2004/02/01 12:31:51 $