/[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.6 by joko, Tue Dec 3 15:52:24 2002 UTC revision 1.16 by joko, Fri Apr 18 16:07:53 2003 UTC
# Line 1  Line 1 
1  #################################  ##    ------------------------------------------------------------------------
2  #  ##    $Id$
3  #  $Id$  ##    ------------------------------------------------------------------------
4  #  ##    $Log$
5  #  $Log$  ##    Revision 1.16  2003/04/18 16:07:53  joko
6  #  Revision 1.6  2002/12/03 15:52:24  joko  ##    just use logger if instantiation successed
7  #  + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level  ##
8  #  ##    Revision 1.15  2003/02/20 20:19:13  joko
9  #  Revision 1.5  2002/12/01 22:19:33  joko  ##    tried to get auto-disconnect working again - failed with that
10  #  + just disconnect if COREHANDLE exists  ##
11  #  ##    Revision 1.14  2003/02/09 05:12:28  joko
12  #  Revision 1.4  2002/12/01 04:45:38  joko  ##    + quoting of strings used in sql-queries!
13  #  + sub eraseAll  ##
14  #  + sub createDb  ##    Revision 1.13  2003/01/30 22:27:05  joko
15  #  ##    + added new abstract methods
16  #  Revision 1.3  2002/11/29 04:58:20  joko  ##
17  #  + Storage::Result now uses the same dispatching mechanism like Storage::Handler  ##    Revision 1.12  2003/01/30 21:46:32  joko
18  #  ##    + fixed behaviour of AUTOLOAD-method
19  #  Revision 1.2  2002/10/17 00:08:07  joko  ##
20  #  + bugfixes regarding "deep recursion" stuff  ##    Revision 1.11  2003/01/20 16:43:18  joko
21  #  ##    + better argument-property merging
22  #  Revision 1.1  2002/10/10 03:44:07  cvsjoko  ##    + debugging-output !!!
23  #  + new  ##    + abstract-dummy 'sub createChildNode'
24  #  ##
25  #  ##    Revision 1.10  2003/01/19 02:31:51  joko
26  #################################  ##    + fix to 'sub AUTOLOAD'
27    ##
28    ##    Revision 1.9  2002/12/19 16:30:23  joko
29    ##    + added 'sub dropDb' and 'sub rebuildDb' as croakers for concrete implementations of methods in proper handlers
30    ##
31    ##    Revision 1.8  2002/12/13 21:48:35  joko
32    ##    + sub _abstract_function
33    ##
34    ##    Revision 1.7  2002/12/05 07:57:48  joko
35    ##    + now using Tie::SecureHash as a base for the COREHANDLE
36    ##    + former public COREHANDLE becomes private _COREHANDLE now
37    ##
38    ##    Revision 1.6  2002/12/03 15:52:24  joko
39    ##    + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level
40    ##
41    ##    Revision 1.5  2002/12/01 22:19:33  joko
42    ##    + just disconnect if COREHANDLE exists
43    ##
44    ##    Revision 1.4  2002/12/01 04:45:38  joko
45    ##    + sub eraseAll
46    ##    + sub createDb
47    ##
48    ##    Revision 1.3  2002/11/29 04:58:20  joko
49    ##    + Storage::Result now uses the same dispatching mechanism like Storage::Handler
50    ##
51    ##    Revision 1.2  2002/10/17 00:08:07  joko
52    ##    + bugfixes regarding "deep recursion" stuff
53    ##
54    ##    Revision 1.1  2002/10/10 03:44:07  cvsjoko
55    ##    + new
56    ##    ------------------------------------------------------------------------
57    
58    
59  package Data::Storage::Handler::Abstract;  package Data::Storage::Handler::Abstract;
60    
61  use strict;  use strict;
62  use warnings;  use warnings;
63    
64    use base qw( DesignPattern::Object );
65    
66    
67  use Data::Dumper;  use Data::Dumper;
68    use Tie::SecureHash;
69    #use Data::Storage::Handler;
70    use Hash::Merge qw( merge );
71    
72    #use Log::Dispatch::Config;
73    #Log::Dispatch::Config->configure();
74    
75  # get logger instance  # get logger instance
76  my $logger = Log::Dispatch::Config->instance;  my $logger;
77    eval('$logger = Log::Dispatch::Config->instance;');
78    
79  #our $lock_info;  #our $lock_info;
80    
# Line 42  sub new { Line 83  sub new {
83    my $class = ref($invocant) || $invocant;    my $class = ref($invocant) || $invocant;
84        
85    # logging info about the actual handler called    # logging info about the actual handler called
86      $logger->debug( "$invocant->new( @_ )" );      $logger->debug( "$invocant->new( @_ )" ) if $logger;
87      #$logger->debug( __PACKAGE__ . "->" . "new()" );      #$logger->debug( __PACKAGE__ . "->" . "new()" );
88    
89    # arguments become properties    # V1 - arguments become properties automagically / normal perl mode blessing
90    =pod
91      # autovivify passed-in arguments as future object attributes into to-be-blessed hash
92    my $self = { @_ };    my $self = { @_ };
93    # create object from blessed hash-reference    # create object from blessed hash-reference
94    bless $self, $class;    bless $self, $class;
95    =cut
96    
97    #=pod
98      # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash...
99      my $self = Tie::SecureHash->new(
100        $class,
101        # that's it:
102          'metainfo' => undef,
103          'lock_info' => undef,
104          '_COREHANDLE' => undef,
105          'meta' => undef,
106          'locator' => undef,
107          'dataStorageLayer' => undef,
108          'dbi' => undef,
109        # tries:
110          #'Data::Storage::Handler::Abstract::metainfo' => undef,
111          #'dataStorageLayer'
112          #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef,
113          #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef,
114          #'Data::Dumper::locator' => undef,
115          #$class . '::locator' => undef,
116          #'Data::Storage::Handler::Tangram::locator' => undef,
117          #'Data::Storage::Handler::DBI::locator' => undef,
118          #_protected => ,
119          #__private => ,
120      );
121    #=cut
122    
123      # merge passed-in arguments to constructor as properties into already blessed secure object
124    
125        # mungle arguments from array into hash - perl does the job  ;)
126        #my %args = @_;
127        #my %args = ();
128    
129    #print Dumper(@_);
130    
131        # merge attributes one-by-one
132        # TODO: deep_copy? / merge_deep?
133        while (my $elemName = shift @_) {
134          #print "elemName: $elemName", "\n";
135          if (my $elemValue = shift @_) {
136            #print Dumper($elemValue);
137            #print "elemName=$elemName, elemValue=$elemValue", "\n";
138            $self->{$elemName} = $elemValue;
139          }
140          #$self->{$_} = $args{$_};
141          #$self->{$_} = $args{$_};
142        }
143      
144      # V3 - rolling our own security (just for {COREHANDLE} - nothing else)  -  nope, Tie::SecureHash works wonderful
145      #my $self = { @_ };
146      #bless $self, $class;
147      
148      
149    
150    # handle meta data    # handle meta data
151      #my $metainfo = $self->getMetaInfo($class);      #my $metainfo = $self->getMetaInfo($class);
# Line 65  sub new { Line 162  sub new {
162  }  }
163    
164    
165    # TODO: use NEXT.pm inside this mechanism (to avoid repetitions...)
166  sub AUTOLOAD {  sub AUTOLOAD {
167    
168    # recursion problem to be avoided here!!!    # recursion problem to be avoided here!!!
# Line 86  sub AUTOLOAD { Line 184  sub AUTOLOAD {
184    # find out methodname    # find out methodname
185    my $methodname = $AUTOLOAD;    my $methodname = $AUTOLOAD;
186    $methodname =~ s/^.*:://;    $methodname =~ s/^.*:://;
187      
188    #print "method: $methodname", "\n";
189      
190      # TODO: document this! handler-private methods listed here will not be triggered (internal use)
191      # in this case, "exists" is a method reserved for Tie::SecureHash,
192      # which encapsulates the perl data structure (HASH) under this object
193      # this is to prevent deep recursion's
194      return if lc $methodname eq 'exists';
195    
196    #print "$methodname - 1", "\n";
197    
198      # TODO: enhance logging/debugging
199      #if (!$self->exists('COREHANDLE')) { return; }
200    
201    # handle locking (hack)    # handle locking (hack)
202    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}) {
203      $self->{lock_info}->{log_lock} = 1;      $self->{lock_info}->{log_lock} = 1;
204    } else {    } else {
205      $self->{lock_info}->{log_lock} = 0;      $self->{lock_info}->{log_lock} = 0;
206    }    }
207    $self->{lock_info}->{last_method} = $methodname;    $self->{lock_info}->{last_method} = $methodname;
208        
209    #print "$methodname - 2", "\n";
210    
211    #print Dumper($self);
212    #exit;
213    
214      # get corehandle instance from underlying handler
215      my $core = $self->getCOREHANDLE();
216    
217    # test for COREHANDLE    # test for COREHANDLE
218    if (!$self->{COREHANDLE}) {    #if (!$self->{_COREHANDLE}) {
219      #print "no COREHANDLE", "\n";  #=pod
220      if (!$self->{lock_info}->{log_lock}) {    #if (!$self->exists('_COREHANDLE')) {
221        $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );    #if (!$self->{_COREHANDLE}) {
222      }    if (!$core) {
223    
224    #print Dumper($self);    
225    #exit;
226    
227        my $handlertype = $self->{metainfo}->{type};
228        $handlertype ||= '';
229    
230        my $err_msg_core = __PACKAGE__ . "[$handlertype]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"";
231    
232    #print $err_msg_core, "\n";
233    
234        #if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
235          $logger->error( $err_msg_core );
236        #}
237    
238      return;      return;
239        
240    }    }
241    #=cut
242    
243    #print "$methodname - 3", "\n";
244    
245    # try to dispatch method-call to Storage::Handler::*    # try to dispatch method-call to Storage::Handler::*
246    #if ($self->can($methodname)) {    #if ($self->can($methodname)) {
# Line 111  sub AUTOLOAD { Line 249  sub AUTOLOAD {
249      #if ($res) { return $res; }      #if ($res) { return $res; }
250    #}    #}
251    
252    #print "$methodname - 4", "\n";
253    
254    # try to dispatch method-call to COREHANDLE    # try to dispatch method-call to COREHANDLE
255    if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {    # was:
256      #my $core = $self->{_COREHANDLE};
257      # is:
258      #my $core = $self->getCOREHANDLE();
259    
260    #print Dumper($core);
261    #exit;
262    
263      # was:
264      #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
265      # is:
266      if ($core->can($methodname) || $core->can("AUTOLOAD")) {
267      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
268      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
269      if (!$self->{lock_info}->{log_lock}) {      if (!$self->{lock_info}->{log_lock}) {
# Line 124  sub AUTOLOAD { Line 275  sub AUTOLOAD {
275      #$lock_AUTOLOAD = 0;      #$lock_AUTOLOAD = 0;
276      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
277            
278      # method calls doing it until here will get dispatched to the proper handler  #print "calling: $methodname", "\n";
279      return $self->{COREHANDLE}->$methodname(@_);      
280        # method calls making it until here will get dispatched to the proper handler
281        return $core->$methodname(@_);
282        
283    } elsif ($self->can($methodname)) {    } elsif ($self->can($methodname)) {
284        # try to call specified method inside our or inherited module(s) scope(s)
285      return $self->$methodname(@_);      return $self->$methodname(@_);
286    }    }
287    
# Line 135  sub AUTOLOAD { Line 289  sub AUTOLOAD {
289    
290  sub DESTROY {  sub DESTROY {
291    my $self = shift;    my $self = shift;
292    if ($self->{COREHANDLE}) {  
293    return;
294    
295      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
296    
297      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
298      print "meth: ", $disconnectMethod, "\n";
299      
300      #$disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
301      $self->{_COREHANDLE}->$disconnectMethod();
302      #$self->$disconnectMethod();
303    
304      #my $core1 = $self->getCOREHANDLE() if $self->can('getCOREHANDLE');
305      #$core1->$disconnectMethod();
306    
307    return;
308    
309      print "DESTROY-1", "\n";
310      #if ($self->{__COREHANDLE}) {
311      #if ($self->exists('_COREHANDLE')) {
312    
313      # get corehandle instance from underlying handler
314      my $core;
315      $core = $self->getCOREHANDLE() if $self->can('getCOREHANDLE');
316    
317      #if ($self->{STORAGEHANDLE}) {
318      if ($core) {
319        print "DESTROY-2", "\n";
320      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
321    
322      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
323    
324      # call "disconnect" or alike on COREHANDLE      # call "disconnect" or alike on COREHANDLE
325      # was: $self->{COREHANDLE}->disconnect();      # was: $self->{COREHANDLE}->disconnect();
326      $disconnectMethod && $self->{COREHANDLE} && ( $self->{COREHANDLE}->$disconnectMethod() );      $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
327    
328      undef $self->{COREHANDLE};      undef $self->{_COREHANDLE};
329    }    }
330  }  }
331    
332    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 {  
333    my $type = shift;    my $type = shift;
334    print "type: $type";    print "type: $type";
335    eval("use Data::Storage::$type;");    eval("use Data::Storage::$type;");
# Line 171  sub _typeCheck { Line 343  sub _typeCheck {
343    sub existsChildNode {    sub existsChildNode {
344      my $self = shift;      my $self = shift;
345      my $nodename = shift;      my $nodename = shift;
346      #$nodename = 'TransactionRoutingTable';  
347      $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );      # TODO: don't use $self->{meta}->{childnodes} directly in here
348        # get it returned from $self->getChildNodes()!!!
349    
350        $logger->debug( __PACKAGE__ . "->existsChildNode( nodename=$nodename )" );
351      $self->getChildNodes() unless $self->{meta}->{childnodes};      $self->getChildNodes() unless $self->{meta}->{childnodes};
352      my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});     # TODO: use "/i" only on win32-systems!  
353        # quote this, it might contain meta characters which don't work in a regex
354          $nodename = quotemeta($nodename);
355    
356        # trace
357          #print Dumper($self->{meta});
358          #print "nodename: $nodename", "\n";
359        
360        # FIXME: use "/i" only on win32-systems!
361        my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});
362        
363      return $result;      return $result;
364    }    }
365    
# Line 199  sub _typeCheck { Line 384  sub _typeCheck {
384    #   - build them via anonymous subs    #   - build them via anonymous subs
385    #   - introduce them via symbols    #   - introduce them via symbols
386    
387      sub getCOREHANDLE {
388        my $self = shift;
389        $self->_abstract_function('getCOREHANDLE');
390      }
391    
392    sub sendCommand {    sub sendCommand {
393      my $self = shift;      my $self = shift;
394      $self->_abstract_function('sendCommand');      $self->_abstract_function('sendCommand');
395    }    }
396    
397      sub createChildNode {
398        my $self = shift;
399        $self->_abstract_function('createChildNode');
400      }
401    
402      sub existsChildNode_tmp {
403        my $self = shift;
404        $self->_abstract_function('existsChildNode');
405      }
406    
407    sub getChildNodes {    sub getChildNodes {
408      my $self = shift;      my $self = shift;
409      $self->_abstract_function('getChildNodes');      $self->_abstract_function('getChildNodes');
# Line 268  sub _typeCheck { Line 468  sub _typeCheck {
468      return;      return;
469    }    }
470    
471      sub dropDb {
472        my $self = shift;
473        $self->_abstract_function('dropDb');
474        return;
475      }
476    
477      sub rebuildDb {
478        my $self = shift;
479        $self->_abstract_function('rebuildDb');
480        return;
481      }
482    
483      sub getDbName {
484        my $self = shift;
485        $self->_abstract_function('getDbName');
486        return;
487      }
488    
489      sub testAvailability {
490        my $self = shift;
491        $self->_abstract_function('testAvailability');
492        return;
493      }
494    
495      sub isConnected {
496        my $self = shift;
497        $self->_abstract_function('isConnected');
498        return;
499      }
500    
501      sub testDsn {
502        my $self = shift;
503        $self->_abstract_function('testDsn');
504        return;
505      }
506    
507  1;  1;

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.16

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