--- nfo/perl/libs/Data/Storage/Handler/Abstract.pm 2002/12/03 15:52:24 1.6 +++ nfo/perl/libs/Data/Storage/Handler/Abstract.pm 2002/12/05 07:57:48 1.7 @@ -1,29 +1,31 @@ -################################# -# -# $Id: Abstract.pm,v 1.6 2002/12/03 15:52:24 joko Exp $ -# -# $Log: Abstract.pm,v $ -# 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 -# -# -################################# +## -------------------------------------------------------------------------------- +## $Id: Abstract.pm,v 1.7 2002/12/05 07:57:48 joko Exp $ +## -------------------------------------------------------------------------------- +## $Log: Abstract.pm,v $ +## 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; @@ -31,6 +33,8 @@ use warnings; use Data::Dumper; +use Tie::SecureHash; +#use Data::Storage::Handler; # get logger instance my $logger = Log::Dispatch::Config->instance; @@ -45,10 +49,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); @@ -86,23 +137,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)) { @@ -111,8 +191,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}) { @@ -124,8 +217,10 @@ #$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(@_); @@ -135,16 +230,17 @@ 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} && ( $self->{COREHANDLE}->$disconnectMethod() ); + $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() ); - undef $self->{COREHANDLE}; + undef $self->{_COREHANDLE}; } } @@ -153,11 +249,14 @@ my $self = shift; my $fName = shift; my $class = ref($self); - $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\""); + # was: + # $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\""); + # is: + die( __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;"); @@ -199,11 +298,21 @@ # - 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');