Parent Directory
|
Revision Log
Expires bug fixed
| 1 | wakaba | 1.1 | |
| 2 | =head1 NAME | ||
| 3 | |||
| 4 | SuikaWiki::DB::FileSystem::SuikaWikiMetaInfo09 --- SuikaWiki WikiDatabase: SuikaWikiMetaInfo/0.9 one-file meta properties database | ||
| 5 | |||
| 6 | =head1 DESCRIPTION | ||
| 7 | |||
| 8 | This module provides SuikaWiki WikiDatabase interface to SuikaWikiMetaInfo/0.9 | ||
| 9 | format of database. It can keep keys with multiple properties into | ||
| 10 | one file. It is originally implemented as supplemental database of | ||
| 11 | Yuki::YukiWikiDBMeta. | ||
| 12 | |||
| 13 | This module is part of SuikaWiki. | ||
| 14 | |||
| 15 | =cut | ||
| 16 | |||
| 17 | package SuikaWiki::DB::FileSystem::SuikaWikiMetaInfo09; | ||
| 18 | wakaba | 1.2 | use strict; |
| 19 | wakaba | 1.7 | our $VERSION=do{my @r=(q$Revision: 1.6 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
| 20 | wakaba | 1.1 | require SuikaWiki::DB::Util; |
| 21 | wakaba | 1.6 | push our @ISA, 'SuikaWiki::DB::Util::template'; |
| 22 | wakaba | 1.1 | my $Sep = '//'; |
| 23 | my $Self = '.'; | ||
| 24 | my $Parent = '..'; | ||
| 25 | |||
| 26 | sub new ($%) { | ||
| 27 | wakaba | 1.6 | my $self = shift->SUPER::new (@_); |
| 28 | my %opt = @_; | ||
| 29 | $self->{directory} = $opt{directory} | ||
| 30 | or report SuikaWiki::DB::Util::Error | ||
| 31 | -type => 'DB_METHOD_PARAMETER_REQUIRED', | ||
| 32 | -object => $self, method => 'new', | ||
| 33 | parameter => 'directory'; | ||
| 34 | wakaba | 1.3 | $self->{directory} .= '/' unless substr ($self->{directory}, -1, 1) eq '/'; |
| 35 | wakaba | 1.6 | $self->{prefix} = $opt{prefix} || 'mt--'; |
| 36 | $self->{suffix} = $opt{suffix} || '.dat'; | ||
| 37 | wakaba | 1.1 | $self; |
| 38 | } | ||
| 39 | |||
| 40 | sub __encode_base16 ($$) { | ||
| 41 | my ($self, $s) = @_; | ||
| 42 | wakaba | 1.3 | $s =~ s/(.)/sprintf '%02X', ord $1/ges; |
| 43 | wakaba | 1.1 | $s; |
| 44 | } | ||
| 45 | sub __decode_base16 ($$) { | ||
| 46 | my ($self, $s) = @_; | ||
| 47 | wakaba | 1.3 | $s =~ s/([0-9A-Fa-f]{2})/chr hex $1/ge; |
| 48 | wakaba | 1.1 | $s; |
| 49 | } | ||
| 50 | |||
| 51 | wakaba | 1.6 | sub ___open_prop ($$) { |
| 52 | my ($self, $opt) = @_; | ||
| 53 | local $Error::Depth = $Error::Depth + 1; | ||
| 54 | my $file = $self->{directory} | ||
| 55 | .$self->{prefix} | ||
| 56 | .$self->__encode_base16 ($opt->{prop}) | ||
| 57 | .$self->{suffix}; | ||
| 58 | wakaba | 1.1 | unless (-e $file) { |
| 59 | wakaba | 1.6 | $self->{db_hash}->{$opt->{prop}} = {}; |
| 60 | wakaba | 1.1 | } else { |
| 61 | wakaba | 1.6 | CORE::open DB, '<', $file |
| 62 | or report SuikaWiki::DB::Util::Error | ||
| 63 | -type => 'STOP_DB_PROP_CANT_OPEN', file => $file, | ||
| 64 | msg => $!, prop => $opt->{prop}, | ||
| 65 | -object => $self, method => '__read_meta'; | ||
| 66 | wakaba | 1.1 | binmode DB; |
| 67 | local $/ = undef; | ||
| 68 | my $val = <DB>; | ||
| 69 | wakaba | 1.6 | CORE::close DB; |
| 70 | wakaba | 1.1 | |
| 71 | if ($val =~ s!^\#\?SuikaWikiMetaInfo/0.9[^\x02]*\x02!!s) { | ||
| 72 | wakaba | 1.6 | $self->{db_hash}->{$opt->{prop}} = {map {split /\x1F/, $_, 2} |
| 73 | split /\x1E/, $val}; | ||
| 74 | wakaba | 1.1 | } elsif (length $val) { |
| 75 | wakaba | 1.6 | report SuikaWiki::DB::Util::Error |
| 76 | -type => 'DB_UNSUPPORTED_FORMAT', file => $file, | ||
| 77 | method => '__read_meta', -object => $self, | ||
| 78 | prop => $opt->{prop}; | ||
| 79 | wakaba | 1.1 | } else { ## Blank file |
| 80 | wakaba | 1.6 | $self->{db_hash}->{$opt->{prop}} = {}; |
| 81 | wakaba | 1.1 | } |
| 82 | } | ||
| 83 | wakaba |