/[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.12 by joko, Thu Jan 30 21:46:32 2003 UTC
# Line 1  Line 1 
1  #################################  ##    ------------------------------------------------------------------------
2  #  ##    $Id$
3  #  $Id$  ##    ------------------------------------------------------------------------
4  #  ##    $Log$
5  #  $Log$  ##    Revision 1.12  2003/01/30 21:46:32  joko
6  #  Revision 1.3  2002/11/29 04:58:20  joko  ##    + fixed behaviour of AUTOLOAD-method
7  #  + Storage::Result now uses the same dispatching mechanism like Storage::Handler  ##
8  #  ##    Revision 1.11  2003/01/20 16:43:18  joko
9  #  Revision 1.2  2002/10/17 00:08:07  joko  ##    + better argument-property merging
10  #  + bugfixes regarding "deep recursion" stuff  ##    + debugging-output !!!
11  #  ##    + abstract-dummy 'sub createChildNode'
12  #  Revision 1.1  2002/10/10 03:44:07  cvsjoko  ##
13  #  + new  ##    Revision 1.10  2003/01/19 02:31:51  joko
14  #  ##    + fix to 'sub AUTOLOAD'
15  #  ##
16  #################################  ##    Revision 1.9  2002/12/19 16:30:23  joko
17    ##    + added 'sub dropDb' and 'sub rebuildDb' as croakers for concrete implementations of methods in proper handlers
18    ##
19    ##    Revision 1.8  2002/12/13 21:48:35  joko
20    ##    + sub _abstract_function
21    ##
22    ##    Revision 1.7  2002/12/05 07:57:48  joko
23    ##    + now using Tie::SecureHash as a base for the COREHANDLE
24    ##    + former public COREHANDLE becomes private _COREHANDLE now
25    ##
26    ##    Revision 1.6  2002/12/03 15:52:24  joko
27    ##    + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level
28    ##
29    ##    Revision 1.5  2002/12/01 22:19:33  joko
30    ##    + just disconnect if COREHANDLE exists
31    ##
32    ##    Revision 1.4  2002/12/01 04:45:38  joko
33    ##    + sub eraseAll
34    ##    + sub createDb
35    ##
36    ##    Revision 1.3  2002/11/29 04:58:20  joko
37    ##    + Storage::Result now uses the same dispatching mechanism like Storage::Handler
38    ##
39    ##    Revision 1.2  2002/10/17 00:08:07  joko
40    ##    + bugfixes regarding "deep recursion" stuff
41    ##
42    ##    Revision 1.1  2002/10/10 03:44:07  cvsjoko
43    ##    + new
44    ##    ------------------------------------------------------------------------
45    
46    
47  package Data::Storage::Handler::Abstract;  package Data::Storage::Handler::Abstract;
48    
49  use strict;  use strict;
50  use warnings;  use warnings;
51    
52    use base qw( DesignPattern::Object );
53    
54    
55  use Data::Dumper;  use Data::Dumper;
56    use Tie::SecureHash;
57    #use Data::Storage::Handler;
58    use Data::Transform::Deep qw( merge );
59    
60    
61  # get logger instance  # get logger instance
62  my $logger = Log::Dispatch::Config->instance;  my $logger = Log::Dispatch::Config->instance;
# Line 35  sub new { Line 71  sub new {
71      $logger->debug( "$invocant->new( @_ )" );      $logger->debug( "$invocant->new( @_ )" );
72      #$logger->debug( __PACKAGE__ . "->" . "new()" );      #$logger->debug( __PACKAGE__ . "->" . "new()" );
73    
74    # arguments become properties    # V1 - arguments become properties automagically / normal perl mode blessing
75    =pod
76      # autovivify passed-in arguments as future object attributes into to-be-blessed hash
77    my $self = { @_ };    my $self = { @_ };
78    # create object from blessed hash-reference    # create object from blessed hash-reference
79    bless $self, $class;    bless $self, $class;
80    =cut
81    
82    #=pod
83      # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash...
84      my $self = Tie::SecureHash->new(
85        $class,
86        # that's it:
87          'metainfo' => undef,
88          'lock_info' => undef,
89          '_COREHANDLE' => undef,
90          'meta' => undef,
91          'locator' => undef,
92          'dataStorageLayer' => undef,
93          'dbi' => undef,
94        # tries:
95          #'Data::Storage::Handler::Abstract::metainfo' => undef,
96          #'dataStorageLayer'
97          #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef,
98          #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef,
99          #'Data::Dumper::locator' => undef,
100          #$class . '::locator' => undef,
101          #'Data::Storage::Handler::Tangram::locator' => undef,
102          #'Data::Storage::Handler::DBI::locator' => undef,
103          #_protected => ,
104          #__private => ,
105      );
106    #=cut
107    
108      # merge passed-in arguments to constructor as properties into already blessed secure object
109    
110        # mungle arguments from array into hash - perl does the job  ;)
111        #my %args = @_;
112        #my %args = ();
113    
114    #print Dumper(@_);
115    
116        # merge attributes one-by-one
117        # TODO: deep_copy? / merge_deep?
118        while (my $elemName = shift @_) {
119          #print "elemName: $elemName", "\n";
120          if (my $elemValue = shift @_) {
121            #print Dumper($elemValue);
122            #print "elemName=$elemName, elemValue=$elemValue", "\n";
123            $self->{$elemName} = $elemValue;
124          }
125          #$self->{$_} = $args{$_};
126          #$self->{$_} = $args{$_};
127        }
128      
129      # V3 - rolling our own security (just for {COREHANDLE} - nothing else)  -  nope, Tie::SecureHash works wonderful
130      #my $self = { @_ };
131      #bless $self, $class;
132      
133      
134    
135    # handle meta data    # handle meta data
136      #my $metainfo = $self->getMetaInfo($class);      #my $metainfo = $self->getMetaInfo($class);
# Line 55  sub new { Line 147  sub new {
147  }  }
148    
149    
150    # TODO: use NEXT.pm inside this mechanism (to avoid repetitions...)
151  sub AUTOLOAD {  sub AUTOLOAD {
152    
153    # recursion problem to be avoided here!!!    # recursion problem to be avoided here!!!
# Line 76  sub AUTOLOAD { Line 169  sub AUTOLOAD {
169    # find out methodname    # find out methodname
170    my $methodname = $AUTOLOAD;    my $methodname = $AUTOLOAD;
171    $methodname =~ s/^.*:://;    $methodname =~ s/^.*:://;
172      
173    #print "method: $methodname", "\n";
174      
175      # TODO: document this! handler-private methods listed here will not be triggered (internal use)
176      # in this case, "exists" is a method reserved for Tie::SecureHash,
177      # which encapsulates the perl data structure (HASH) under this object
178      # this is to prevent deep recursion's
179      return if lc $methodname eq 'exists';
180    
181    #print "$methodname - 1", "\n";
182    
183      # TODO: enhance logging/debugging
184      #if (!$self->exists('COREHANDLE')) { return; }
185    
186    # handle locking (hack)    # handle locking (hack)
187    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}) {
188      $self->{lock_info}->{log_lock} = 1;      $self->{lock_info}->{log_lock} = 1;
189    } else {    } else {
190      $self->{lock_info}->{log_lock} = 0;      $self->{lock_info}->{log_lock} = 0;
191    }    }
192    $self->{lock_info}->{last_method} = $methodname;    $self->{lock_info}->{last_method} = $methodname;
193        
194    #print "$methodname - 2", "\n";
195    
196    #print Dumper($self);
197    #exit;
198    
199      # get corehandle instance from underlying handler
200      my $core = $self->getCOREHANDLE();
201    
202    # test for COREHANDLE    # test for COREHANDLE
203    if (!$self->{COREHANDLE}) {    #if (!$self->{_COREHANDLE}) {
204      #print "no COREHANDLE", "\n";  #=pod
205      if (!$self->{lock_info}->{log_lock}) {    #if (!$self->exists('_COREHANDLE')) {
206        $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );    #if (!$self->{_COREHANDLE}) {
207      }    if (!$core) {
208    
209    #print Dumper($self);    
210    #exit;
211    
212        my $handlertype = $self->{metainfo}->{type};
213        $handlertype ||= '';
214    
215        my $err_msg_core = __PACKAGE__ . "[$handlertype]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"";
216    
217    #print $err_msg_core, "\n";
218    
219        #if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
220          $logger->error( $err_msg_core );
221        #}
222    
223      return;      return;
224        
225    }    }
226    #=cut
227    
228    #print "$methodname - 3", "\n";
229    
230    # try to dispatch method-call to Storage::Handler::*    # try to dispatch method-call to Storage::Handler::*
231    #if ($self->can($methodname)) {    #if ($self->can($methodname)) {
# Line 101  sub AUTOLOAD { Line 234  sub AUTOLOAD {
234      #if ($res) { return $res; }      #if ($res) { return $res; }
235    #}    #}
236    
237    #print "$methodname - 4", "\n";
238    
239    # try to dispatch method-call to COREHANDLE    # try to dispatch method-call to COREHANDLE
240    if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {    # was:
241      #my $core = $self->{_COREHANDLE};
242      # is:
243      #my $core = $self->getCOREHANDLE();
244    
245    #print Dumper($core);
246    #exit;
247    
248      # was:
249      #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
250      # is:
251      if ($core->can($methodname) || $core->can("AUTOLOAD")) {
252      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
253      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
254      if (!$self->{lock_info}->{log_lock}) {      if (!$self->{lock_info}->{log_lock}) {
# Line 114  sub AUTOLOAD { Line 260  sub AUTOLOAD {
260      #$lock_AUTOLOAD = 0;      #$lock_AUTOLOAD = 0;
261      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
262            
263      # method calls doing it until here will get dispatched to the proper handler  #print "calling: $methodname", "\n";
264      return $self->{COREHANDLE}->$methodname(@_);      
265        # method calls making it until here will get dispatched to the proper handler
266        return $core->$methodname(@_);
267      
268      } elsif ($self->can($methodname)) {
269        # try to call specified method inside our or inherited module(s) scope(s)
270        return $self->$methodname(@_);
271    }    }
272    
273  }  }
274    
275  sub DESTROY {  sub DESTROY {
276    my $self = shift;    my $self = shift;
277    if ($self->{COREHANDLE}) {    #if ($self->{COREHANDLE}) {
278      if ($self->exists('_COREHANDLE')) {
279      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
280    
281      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
282    
283      # call "disconnect" or alike on COREHANDLE      # call "disconnect" or alike on COREHANDLE
284      # was: $self->{COREHANDLE}->disconnect();      # was: $self->{COREHANDLE}->disconnect();
285      $disconnectMethod && ( $self->{COREHANDLE}->$disconnectMethod() );      $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
286    
287      undef $self->{COREHANDLE};      undef $self->{_COREHANDLE};
288    }    }
289  }  }
290    
291    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 {  
292    my $type = shift;    my $type = shift;
293    print "type: $type";    print "type: $type";
294    eval("use Data::Storage::$type;");    eval("use Data::Storage::$type;");
# Line 159  sub _typeCheck { Line 303  sub _typeCheck {
303      my $self = shift;      my $self = shift;
304      my $nodename = shift;      my $nodename = shift;
305      #$nodename = 'TransactionRoutingTable';      #$nodename = 'TransactionRoutingTable';
306      $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );      $logger->debug( __PACKAGE__ . "->existsChildNode( nodename $nodename )" );
307      $self->getChildNodes() unless $self->{meta}->{childnodes};      $self->getChildNodes() unless $self->{meta}->{childnodes};
308      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!
309      return $result;      return $result;
# Line 182  sub _typeCheck { Line 326  sub _typeCheck {
326    # TODO:    # TODO:
327    #   - abstract "abstract methods" to list/hash to be used in AUTOLOAD    #   - abstract "abstract methods" to list/hash to be used in AUTOLOAD
328    #      e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));    #      e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
329      #      use Class::XYZ (Construct)
330    #   - build them via anonymous subs    #   - build them via anonymous subs
331    #   - introduce them via symbols    #   - introduce them via symbols
332    
333      sub getCOREHANDLE {
334        my $self = shift;
335        $self->_abstract_function('getCOREHANDLE');
336      }
337    
338    sub sendCommand {    sub sendCommand {
339      my $self = shift;      my $self = shift;
340      $self->_abstract_function('sendCommand');      $self->_abstract_function('sendCommand');
341    }    }
342    
343      sub createChildNode {
344        my $self = shift;
345        $self->_abstract_function('createChildNode');
346      }
347    
348      sub existsChildNode_tmp {
349        my $self = shift;
350        $self->_abstract_function('existsChildNode');
351      }
352    
353    sub getChildNodes {    sub getChildNodes {
354      my $self = shift;      my $self = shift;
355      $self->_abstract_function('getChildNodes');      $self->_abstract_function('getChildNodes');
# Line 242  sub _typeCheck { Line 402  sub _typeCheck {
402      return;      return;
403    }    }
404    
405      sub eraseAll {
406        my $self = shift;
407        $self->_abstract_function('eraseAll');
408        return;
409      }
410    
411      sub createDb {
412        my $self = shift;
413        $self->_abstract_function('createDb');
414        return;
415      }
416    
417      sub dropDb {
418        my $self = shift;
419        $self->_abstract_function('dropDb');
420        return;
421      }
422    
423      sub rebuildDb {
424        my $self = shift;
425        $self->_abstract_function('rebuildDb');
426        return;
427      }
428    
429  1;  1;

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

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