--- nfo/perl/libs/Data/Storage/Handler/Abstract.pm 2002/11/29 04:58:20 1.3 +++ nfo/perl/libs/Data/Storage/Handler/Abstract.pm 2002/12/19 16:30:23 1.9 @@ -1,26 +1,48 @@ -################################# -# -# $Id: Abstract.pm,v 1.3 2002/11/29 04:58:20 joko Exp $ -# -# $Log: Abstract.pm,v $ -# Revision 1.3 2002/11/29 04:58:20 joko -# + Storage::Result now uses the same dispatching mechanism like Storage::Handler -# -# Revision 1.2 2002/10/17 00:08:07 joko -# + bugfixes regarding "deep recursion" stuff -# -# Revision 1.1 2002/10/10 03:44:07 cvsjoko -# + new -# -# -################################# +## -------------------------------------------------------------------------------- +## $Id: Abstract.pm,v 1.9 2002/12/19 16:30:23 joko Exp $ +## -------------------------------------------------------------------------------- +## $Log: Abstract.pm,v $ +## Revision 1.9 2002/12/19 16:30:23 joko +## + added 'sub dropDb' and 'sub rebuildDb' as croakers for concrete implementations of methods in proper handlers +## +## Revision 1.8 2002/12/13 21:48:35 joko +## + sub _abstract_function +## +## Revision 1.7 2002/12/05 07:57:48 joko +## + now using Tie::SecureHash as a base for the COREHANDLE +## + former public COREHANDLE becomes private _COREHANDLE now +## +## Revision 1.6 2002/12/03 15:52:24 joko +## + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level +## +## Revision 1.5 2002/12/01 22:19:33 joko +## + just disconnect if COREHANDLE exists +## +## Revision 1.4 2002/12/01 04:45:38 joko +## + sub eraseAll +## + sub createDb +## +## Revision 1.3 2002/11/29 04:58:20 joko +## + Storage::Result now uses the same dispatching mechanism like Storage::Handler +## +## Revision 1.2 2002/10/17 00:08:07 joko +## + bugfixes regarding "deep recursion" stuff +## +## Revision 1.1 2002/10/10 03:44:07 cvsjoko +## + new +## -------------------------------------------------------------------------------- + package Data::Storage::Handler::Abstract; use strict; use warnings; +use base qw( DesignPattern::Object ); + use Data::Dumper; +use Tie::SecureHash; +#use Data::Storage::Handler; # get logger instance my $logger = Log::Dispatch::Config->instance; @@ -35,10 +57,57 @@ $logger->debug( "$invocant->new( @_ )" ); #$logger->debug( __PACKAGE__ . "->" . "new()" ); - # arguments become properties + # V1 - arguments become properties automagically / normal perl mode blessing +=pod + # autovivify passed-in arguments as future object attributes into to-be-blessed hash my $self = { @_ }; # create object from blessed hash-reference bless $self, $class; +=cut + + + # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash... + my $self = Tie::SecureHash->new( + $class, + # that's it: + 'metainfo' => undef, + 'lock_info' => undef, + '_COREHANDLE' => undef, + 'meta' => undef, + 'locator' => undef, + 'dataStorageLayer' => undef, + 'dbi' => undef, + # tries: + #'Data::Storage::Handler::Abstract::metainfo' => undef, + #'dataStorageLayer' + #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef, + #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef, + #'Data::Dumper::locator' => undef, + #$class . '::locator' => undef, + #'Data::Storage::Handler::Tangram::locator' => undef, + #'Data::Storage::Handler::DBI::locator' => undef, + #_protected => , + #__private => , + ); + + + # merge passed-in arguments to constructor as properties into already blessed secure object + + # mungle arguments from array into hash - perl does the job ;) + my %args = @_; + + # merge attributes one-by-one + # TODO: deep_copy? / merge_deep? + foreach (keys %args) { + #print "key: $_", "\n"; + $self->{$_} = $args{$_}; + } + + # V3 - rolling our own security (just for {COREHANDLE} - nothing else) - nope, Tie::SecureHash works wonderful + #my $self = { @_ }; + #bless $self, $class; + + # handle meta data #my $metainfo = $self->getMetaInfo($class); @@ -76,23 +145,52 @@ # find out methodname my $methodname = $AUTOLOAD; $methodname =~ s/^.*:://; + +#print "method: $methodname", "\n"; + + # TODO: document this! handler-private methods listed here will not be triggered (internal use) + # in this case, "exists" is a method reserved for Tie::SecureHash, + # which encapsulates the perl data structure (HASH) under this object + # this is to prevent deep recursion's + return if lc $methodname eq 'exists'; + +#print "$methodname - 1", "\n"; + + # TODO: enhance logging/debugging + #if (!$self->exists('COREHANDLE')) { return; } # handle locking (hack) - if ($self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) { + if ($self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) { $self->{lock_info}->{log_lock} = 1; } else { $self->{lock_info}->{log_lock} = 0; } $self->{lock_info}->{last_method} = $methodname; +#print "$methodname - 2", "\n"; + +#print Dumper($self); +#exit; + + # get corehandle instance from underlying handler + my $core = $self->getCOREHANDLE(); + # test for COREHANDLE - if (!$self->{COREHANDLE}) { - #print "no COREHANDLE", "\n"; - if (!$self->{lock_info}->{log_lock}) { - $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" ); + #if (!$self->{_COREHANDLE}) { +#=pod + #if (!$self->exists('_COREHANDLE')) { + #if (!$self->{_COREHANDLE}) { + if (!$core) { + my $err_msg_core = __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\""; +print $err_msg_core, "\n"; + if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) { + $logger->error( $err_msg_core ); } return; } +#=cut + +#print "$methodname - 3", "\n"; # try to dispatch method-call to Storage::Handler::* #if ($self->can($methodname)) { @@ -101,8 +199,21 @@ #if ($res) { return $res; } #} +#print "$methodname - 4", "\n"; + # try to dispatch method-call to COREHANDLE - if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) { + # was: + #my $core = $self->{_COREHANDLE}; + # is: + #my $core = $self->getCOREHANDLE(); + +#print Dumper($core); +#exit; + + # was: + #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) { + # is: + if ($core->can($methodname) || $core->can("AUTOLOAD")) { #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" ); #$lock_AUTOLOAD = 1 if ($methodname eq 'insert'); if (!$self->{lock_info}->{log_lock}) { @@ -114,37 +225,34 @@ #$lock_AUTOLOAD = 0; #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" ); +#print "calling: $methodname", "\n"; + # method calls doing it until here will get dispatched to the proper handler - return $self->{COREHANDLE}->$methodname(@_); + return $core->$methodname(@_); + + } elsif ($self->can($methodname)) { + return $self->$methodname(@_); } } sub DESTROY { my $self = shift; - if ($self->{COREHANDLE}) { + #if ($self->{COREHANDLE}) { + if ($self->exists('_COREHANDLE')) { $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" ); my $disconnectMethod = $self->{metainfo}->{disconnectMethod}; # call "disconnect" or alike on COREHANDLE # was: $self->{COREHANDLE}->disconnect(); - $disconnectMethod && ( $self->{COREHANDLE}->$disconnectMethod() ); + $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() ); - undef $self->{COREHANDLE}; + undef $self->{_COREHANDLE}; } } - -sub _abstract_function { - my $self = shift; - my $fName = shift; - my $class = ref($self); - $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\""); - #exit; -} - -sub _typeCheck { +sub _typeCheck2 { my $type = shift; print "type: $type"; eval("use Data::Storage::$type;"); @@ -182,14 +290,25 @@ # TODO: # - abstract "abstract methods" to list/hash to be used in AUTOLOAD # e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes )); + # use Class::XYZ (Construct) # - build them via anonymous subs # - introduce them via symbols + sub getCOREHANDLE { + my $self = shift; + $self->_abstract_function('getCOREHANDLE'); + } + sub sendCommand { my $self = shift; $self->_abstract_function('sendCommand'); } + sub existsChildNode_tmp { + my $self = shift; + $self->_abstract_function('existsChildNode'); + } + sub getChildNodes { my $self = shift; $self->_abstract_function('getChildNodes'); @@ -242,4 +361,28 @@ return; } + sub eraseAll { + my $self = shift; + $self->_abstract_function('eraseAll'); + return; + } + + sub createDb { + my $self = shift; + $self->_abstract_function('createDb'); + return; + } + + sub dropDb { + my $self = shift; + $self->_abstract_function('dropDb'); + return; + } + + sub rebuildDb { + my $self = shift; + $self->_abstract_function('rebuildDb'); + return; + } + 1;