=head1 NAME SuikaWiki::DB::Util --- SuikaWiki WikiDatabase: WikiDatabase modules common utilities =head1 DESCRIPTION This module provides some functions expected to be useful for most WikiDatabase implememtation modules. This module is part of SuikaWiki. =cut package SuikaWiki::DB::Util; use strict; our $VERSION=do{my @r=(q$Revision: 1.9 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; our $Err; require SuikaWiki::DB::Util::Error; =head1 FUNCTIONS =over 4 =item $locker = SuikaWiki::DB::Util->new_lock ($options) Returns new locker object (SuikaWiki::DB::Util::Lock instance). =cut sub new_lock ($$) { eval qq{ require $_[1]->{-module} } or die $@; return $_[1]->{-module}->new (%{$_[1]}); } =back =cut ## Template for SuikaWiki::DB::* WikiDatabase modules package SuikaWiki::DB::Util::template; sub new ($;%) { my ($class, %opt) = @_; my $self = bless {}, $class; $self->___init (%opt); if ($opt{-lock}) { $self->{lock} = SuikaWiki::DB::Util->new_lock ($opt{-lock}); } $self->{event}->{error} = [sub { my ($self, $event) = @_; if ( $event->{error}->{-def}->{level} eq 'fatal' or $event->{error}->{-def}->{level} eq 'stop') { # no-op } elsif ($event->{error}->{-def}->{level} eq 'warn') { warn $event->{error}->stringify; $event->{cancel} = 1; } else { #warn $event->{error}->stringify; ## DEBUG $event->{cancel} = 1; } }]; $self; } sub ___init ($%) {} sub DESTROY ($) { my $self = shift; local $Error::Depth = $Error::Depth + 1; $self->close if $self->{opened}; } sub open ($;%) { shift->{opened} ? "0 but true" : 0; } sub open_prop ($;%) { my ($self, %opt) = @_; return "0 but true" if $self->{opened}->{$opt{prop}}; if ($self->{lock} and not $self->{lock}->locked) { $self->{lock}->lock or report SuikaWiki::DB::Util::Error -type => 'LOCK_START', -object => $self, method => 'open_prop'; } $self->___open_prop (\%opt); $self->{opened}->{$opt{prop}} = 1; report SuikaWiki::DB::Util::Error -type => 'INFO_DB_PROP_OPENED', -object => $self, method => 'open_prop', prop => $opt{prop}; 1; } sub ___open_prop ($$) { my ($self, $opt) = @_; local $Error::Depth = $Error::Depth + 1; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => '___open_prop', -object => $self, prop => $opt->{prop}; } sub close_prop ($;%) { my ($self, %opt) = @_; return "0 but true" unless $self->{opened}->{$opt{prop}}; $self->___close_prop (\%opt); $self->{opened}->{$opt{prop}} = 0; report SuikaWiki::DB::Util::Error -type => 'INFO_DB_PROP_CLOSED', -object => $self, method => 'close_prop', prop => $opt{prop}; 1; } sub ___close_prop ($$) { my ($self, $opt) = @_; local $Error::Depth = $Error::Depth + 1; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => '___close_prop', -object => $self, prop => $opt->{prop}; } sub close ($;%) { my ($self, %opt) = @_; {local $Error::Depth = $Error::Depth + 1; for (CORE::keys %{$self->{opened}||{}}) { $self->close_prop (prop => $_); }} delete $self->{opened}; $self->{lock}->unlock if $self->{lock}; report SuikaWiki::DB::Util::Error -type => 'DB_CLOSED', method => 'close', -object => $self; } sub get ($$$;%) { my ($self, $prop, $key, %opt) = @_; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => 'get', -object => $self; } sub set ($$$$;%) { my ($self, $prop, $key => $value, %opt) = @_; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => 'set', -object => $self; } sub exist ($$$;%) { my ($self, $prop, $key, %opt) = @_; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => 'exist', -object => $self; } sub delete ($$$;%) { my ($self, $prop, $key, %opt) = @_; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => 'delete', -object => $self; } sub keys ($$;%) { my ($self, $prop, %opt) = @_; report SuikaWiki::DB::Util::Error -type => 'DB_METHOD_NOT_IMPLEMENTED', method => 'delete', -object => $self; } sub ___report_error ($$) { my ($self, $err) = @_; my $event = {cancel => 0, name => 'error', error => $err}; for (@{$self->{event}->{error}}) { $_->($self, $event); return if $event->{cancel}; } $err->throw; } =head1 SEE ALSO L, L =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 1; # $Date: 2004/04/02 04:30:37 $