/[cvs]/nfo/perl/libs/Data/Storage/Handler/Abstract.pm
ViewVC logotype

Diff of /nfo/perl/libs/Data/Storage/Handler/Abstract.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by joko, Fri Nov 29 04:58:20 2002 UTC revision 1.10 by joko, Sun Jan 19 02:31:51 2003 UTC
# Line 1  Line 1 
1  #################################  ##    --------------------------------------------------------------------------------
2  #  ##    $Id$
3  #  $Id$  ##    --------------------------------------------------------------------------------
4  #  ##    $Log$
5  #  $Log$  ##    Revision 1.10  2003/01/19 02:31:51  joko
6  #  Revision 1.3  2002/11/29 04:58:20  joko  ##    + fix to 'sub AUTOLOAD'
7  #  + Storage::Result now uses the same dispatching mechanism like Storage::Handler  ##
8  #  ##    Revision 1.9  2002/12/19 16:30:23  joko
9  #  Revision 1.2  2002/10/17 00:08:07  joko  ##    + added 'sub dropDb' and 'sub rebuildDb' as croakers for concrete implementations of methods in proper handlers
10  #  + bugfixes regarding "deep recursion" stuff  ##
11  #  ##    Revision 1.8  2002/12/13 21:48:35  joko
12  #  Revision 1.1  2002/10/10 03:44:07  cvsjoko  ##    + sub _abstract_function
13  #  + new  ##
14  #  ##    Revision 1.7  2002/12/05 07:57:48  joko
15  #  ##    + now using Tie::SecureHash as a base for the COREHANDLE
16  #################################  ##    + former public COREHANDLE becomes private _COREHANDLE now
17    ##
18    ##    Revision 1.6  2002/12/03 15:52:24  joko
19    ##    + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level
20    ##
21    ##    Revision 1.5  2002/12/01 22:19:33  joko
22    ##    + just disconnect if COREHANDLE exists
23    ##
24    ##    Revision 1.4  2002/12/01 04:45:38  joko
25    ##    + sub eraseAll
26    ##    + sub createDb
27    ##
28    ##    Revision 1.3  2002/11/29 04:58:20  joko
29    ##    + Storage::Result now uses the same dispatching mechanism like Storage::Handler
30    ##
31    ##    Revision 1.2  2002/10/17 00:08:07  joko
32    ##    + bugfixes regarding "deep recursion" stuff
33    ##
34    ##    Revision 1.1  2002/10/10 03:44:07  cvsjoko
35    ##    + new
36    ##    --------------------------------------------------------------------------------
37    
38    
39  package Data::Storage::Handler::Abstract;  package Data::Storage::Handler::Abstract;
40    
41  use strict;  use strict;
42  use warnings;  use warnings;
43    
44    use base qw( DesignPattern::Object );
45    
46  use Data::Dumper;  use Data::Dumper;
47    use Tie::SecureHash;
48    #use Data::Storage::Handler;
49    
50  # get logger instance  # get logger instance
51  my $logger = Log::Dispatch::Config->instance;  my $logger = Log::Dispatch::Config->instance;
# Line 35  sub new { Line 60  sub new {
60      $logger->debug( "$invocant->new( @_ )" );      $logger->debug( "$invocant->new( @_ )" );
61      #$logger->debug( __PACKAGE__ . "->" . "new()" );      #$logger->debug( __PACKAGE__ . "->" . "new()" );
62    
63    # arguments become properties    # V1 - arguments become properties automagically / normal perl mode blessing
64    =pod
65      # autovivify passed-in arguments as future object attributes into to-be-blessed hash
66    my $self = { @_ };    my $self = { @_ };
67    # create object from blessed hash-reference    # create object from blessed hash-reference
68    bless $self, $class;    bless $self, $class;
69    =cut
70    
71    #=pod
72      # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash...
73      my $self = Tie::SecureHash->new(
74        $class,
75        # that's it:
76          'metainfo' => undef,
77          'lock_info' => undef,
78          '_COREHANDLE' => undef,
79          'meta' => undef,
80          'locator' => undef,
81          'dataStorageLayer' => undef,
82          'dbi' => undef,
83        # tries:
84          #'Data::Storage::Handler::Abstract::metainfo' => undef,
85          #'dataStorageLayer'
86          #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef,
87          #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef,
88          #'Data::Dumper::locator' => undef,
89          #$class . '::locator' => undef,
90          #'Data::Storage::Handler::Tangram::locator' => undef,
91          #'Data::Storage::Handler::DBI::locator' => undef,
92          #_protected => ,
93          #__private => ,
94      );
95    #=cut
96    
97      # merge passed-in arguments to constructor as properties into already blessed secure object
98        
99        # mungle arguments from array into hash - perl does the job  ;)
100        my %args = @_;
101      
102        # merge attributes one-by-one
103        # TODO: deep_copy? / merge_deep?
104        foreach (keys %args) {
105          #print "key: $_", "\n";
106          $self->{$_} = $args{$_};
107        }
108      
109      # V3 - rolling our own security (just for {COREHANDLE} - nothing else)  -  nope, Tie::SecureHash works wonderful
110      #my $self = { @_ };
111      #bless $self, $class;
112      
113      
114    
115    # handle meta data    # handle meta data
116      #my $metainfo = $self->getMetaInfo($class);      #my $metainfo = $self->getMetaInfo($class);
# Line 55  sub new { Line 127  sub new {
127  }  }
128    
129    
130    # TODO: use NEXT.pm inside this mechanism (to avoid repetitions...)
131  sub AUTOLOAD {  sub AUTOLOAD {
132    
133    # recursion problem to be avoided here!!!    # recursion problem to be avoided here!!!
# Line 76  sub AUTOLOAD { Line 149  sub AUTOLOAD {
149    # find out methodname    # find out methodname
150    my $methodname = $AUTOLOAD;    my $methodname = $AUTOLOAD;
151    $methodname =~ s/^.*:://;    $methodname =~ s/^.*:://;
152      
153    #print "method: $methodname", "\n";
154      
155      # TODO: document this! handler-private methods listed here will not be triggered (internal use)
156      # in this case, "exists" is a method reserved for Tie::SecureHash,
157      # which encapsulates the perl data structure (HASH) under this object
158      # this is to prevent deep recursion's
159      return if lc $methodname eq 'exists';
160    
161    #print "$methodname - 1", "\n";
162    
163      # TODO: enhance logging/debugging
164      #if (!$self->exists('COREHANDLE')) { return; }
165    
166    # handle locking (hack)    # handle locking (hack)
167    if ($self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {    if ($self->can('exists') && $self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
168      $self->{lock_info}->{log_lock} = 1;      $self->{lock_info}->{log_lock} = 1;
169    } else {    } else {
170      $self->{lock_info}->{log_lock} = 0;      $self->{lock_info}->{log_lock} = 0;
171    }    }
172    $self->{lock_info}->{last_method} = $methodname;    $self->{lock_info}->{last_method} = $methodname;
173        
174    #print "$methodname - 2", "\n";
175    
176    #print Dumper($self);
177    #exit;
178    
179      # get corehandle instance from underlying handler
180      my $core = $self->getCOREHANDLE();
181    
182    # test for COREHANDLE    # test for COREHANDLE
183    if (!$self->{COREHANDLE}) {    #if (!$self->{_COREHANDLE}) {
184      #print "no COREHANDLE", "\n";  #=pod
185      if (!$self->{lock_info}->{log_lock}) {    #if (!$self->exists('_COREHANDLE')) {
186        $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );    #if (!$self->{_COREHANDLE}) {
187      if (!$core) {
188    
189    #print Dumper($self);    
190    #exit;
191    
192        my $handlertype = $self->{metainfo}->{type};
193        $handlertype ||= '';
194    
195        my $err_msg_core = __PACKAGE__ . "[$handlertype]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"";
196    print $err_msg_core, "\n";
197        if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
198          $logger->error( $err_msg_core );
199      }      }
200      return;      return;
201    }    }
202    #=cut
203    
204    #print "$methodname - 3", "\n";
205    
206    # try to dispatch method-call to Storage::Handler::*    # try to dispatch method-call to Storage::Handler::*
207    #if ($self->can($methodname)) {    #if ($self->can($methodname)) {
# Line 101  sub AUTOLOAD { Line 210  sub AUTOLOAD {
210      #if ($res) { return $res; }      #if ($res) { return $res; }
211    #}    #}
212    
213    #print "$methodname - 4", "\n";
214    
215    # try to dispatch method-call to COREHANDLE    # try to dispatch method-call to COREHANDLE
216    if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {    # was:
217      #my $core = $self->{_COREHANDLE};
218      # is:
219      #my $core = $self->getCOREHANDLE();
220    
221    #print Dumper($core);
222    #exit;
223    
224      # was:
225      #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
226      # is:
227      if ($core->can($methodname) || $core->can("AUTOLOAD")) {
228      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
229      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
230      if (!$self->{lock_info}->{log_lock}) {      if (!$self->{lock_info}->{log_lock}) {
# Line 114  sub AUTOLOAD { Line 236  sub AUTOLOAD {
236      #$lock_AUTOLOAD = 0;      #$lock_AUTOLOAD = 0;
237      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
238            
239      # method calls doing it until here will get dispatched to the proper handler  #print "calling: $methodname", "\n";
240      return $self->{COREHANDLE}->$methodname(@_);      
241        # method calls making it until here will get dispatched to the proper handler
242        return $core->$methodname(@_);
243      
244      } elsif ($self->can($methodname)) {
245        # try to call specified method inside our or inherited module(s) scope(s)
246        return $self->$methodname(@_);
247    }    }
248    
249  }  }
250    
251  sub DESTROY {  sub DESTROY {
252    my $self = shift;    my $self = shift;
253    if ($self->{COREHANDLE}) {    #if ($self->{COREHANDLE}) {
254      if ($self->exists('_COREHANDLE')) {
255      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
256    
257      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
258    
259      # call "disconnect" or alike on COREHANDLE      # call "disconnect" or alike on COREHANDLE
260      # was: $self->{COREHANDLE}->disconnect();      # was: $self->{COREHANDLE}->disconnect();
261      $disconnectMethod && ( $self->{COREHANDLE}->$disconnectMethod() );      $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
262    
263      undef $self->{COREHANDLE};      undef $self->{_COREHANDLE};
264    }    }
265  }  }
266    
267    sub _typeCheck2 {
 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 {  
268    my $type = shift;    my $type = shift;
269    print "type: $type";    print "type: $type";
270    eval("use Data::Storage::$type;");    eval("use Data::Storage::$type;");
# Line 159  sub _typeCheck { Line 279  sub _typeCheck {
279      my $self = shift;      my $self = shift;
280      my $nodename = shift;      my $nodename = shift;
281      #$nodename = 'TransactionRoutingTable';      #$nodename = 'TransactionRoutingTable';
282      $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );      $logger->debug( __PACKAGE__ . "->existsChildNode( nodename $nodename )" );
283      $self->getChildNodes() unless $self->{meta}->{childnodes};      $self->getChildNodes() unless $self->{meta}->{childnodes};
284      my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});     # TODO: use "/i" only on win32-systems!      my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});     # TODO: use "/i" only on win32-systems!
285      return $result;      return $result;
# Line 182  sub _typeCheck { Line 302  sub _typeCheck {
302    # TODO:    # TODO:
303    #   - abstract "abstract methods" to list/hash to be used in AUTOLOAD    #   - abstract "abstract methods" to list/hash to be used in AUTOLOAD
304    #      e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));    #      e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
305      #      use Class::XYZ (Construct)
306    #   - build them via anonymous subs    #   - build them via anonymous subs
307    #   - introduce them via symbols    #   - introduce them via symbols
308    
309      sub getCOREHANDLE {
310        my $self = shift;
311        $self->_abstract_function('getCOREHANDLE');
312      }
313    
314    sub sendCommand {    sub sendCommand {
315      my $self = shift;      my $self = shift;
316      $self->_abstract_function('sendCommand');      $self->_abstract_function('sendCommand');
317    }    }
318    
319      sub existsChildNode_tmp {
320        my $self = shift;
321        $self->_abstract_function('existsChildNode');
322      }
323    
324    sub getChildNodes {    sub getChildNodes {
325      my $self = shift;      my $self = shift;
326      $self->_abstract_function('getChildNodes');      $self->_abstract_function('getChildNodes');
# Line 242  sub _typeCheck { Line 373  sub _typeCheck {
373      return;      return;
374    }    }
375    
376      sub eraseAll {
377        my $self = shift;
378        $self->_abstract_function('eraseAll');
379        return;
380      }
381    
382      sub createDb {
383        my $self = shift;
384        $self->_abstract_function('createDb');
385        return;
386      }
387    
388      sub dropDb {
389        my $self = shift;
390        $self->_abstract_function('dropDb');
391        return;
392      }
393    
394      sub rebuildDb {
395        my $self = shift;
396        $self->_abstract_function('rebuildDb');
397        return;
398      }
399    
400  1;  1;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.10

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed