/[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.2 by joko, Thu Oct 17 00:08:07 2002 UTC revision 1.9 by joko, Thu Dec 19 16:30:23 2002 UTC
# Line 1  Line 1 
1  #################################  ##    --------------------------------------------------------------------------------
2  #  ##    $Id$
3  #  $Id$  ##    --------------------------------------------------------------------------------
4  #  ##    $Log$
5  #  $Log$  ##    Revision 1.9  2002/12/19 16:30:23  joko
6  #  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
7  #  + bugfixes regarding "deep recursion" stuff  ##
8  #  ##    Revision 1.8  2002/12/13 21:48:35  joko
9  #  Revision 1.1  2002/10/10 03:44:07  cvsjoko  ##    + sub _abstract_function
10  #  + new  ##
11  #  ##    Revision 1.7  2002/12/05 07:57:48  joko
12  #  ##    + now using Tie::SecureHash as a base for the COREHANDLE
13  #################################  ##    + former public COREHANDLE becomes private _COREHANDLE now
14    ##
15    ##    Revision 1.6  2002/12/03 15:52:24  joko
16    ##    + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level
17    ##
18    ##    Revision 1.5  2002/12/01 22:19:33  joko
19    ##    + just disconnect if COREHANDLE exists
20    ##
21    ##    Revision 1.4  2002/12/01 04:45:38  joko
22    ##    + sub eraseAll
23    ##    + sub createDb
24    ##
25    ##    Revision 1.3  2002/11/29 04:58:20  joko
26    ##    + Storage::Result now uses the same dispatching mechanism like Storage::Handler
27    ##
28    ##    Revision 1.2  2002/10/17 00:08:07  joko
29    ##    + bugfixes regarding "deep recursion" stuff
30    ##
31    ##    Revision 1.1  2002/10/10 03:44:07  cvsjoko
32    ##    + new
33    ##    --------------------------------------------------------------------------------
34    
35    
36  package Data::Storage::Handler::Abstract;  package Data::Storage::Handler::Abstract;
37    
38  use strict;  use strict;
39  use warnings;  use warnings;
40    
41    use base qw( DesignPattern::Object );
42    
43  use Data::Dumper;  use Data::Dumper;
44    use Tie::SecureHash;
45    #use Data::Storage::Handler;
46    
47  # get logger instance  # get logger instance
48  my $logger = Log::Dispatch::Config->instance;  my $logger = Log::Dispatch::Config->instance;
# Line 32  sub new { Line 57  sub new {
57      $logger->debug( "$invocant->new( @_ )" );      $logger->debug( "$invocant->new( @_ )" );
58      #$logger->debug( __PACKAGE__ . "->" . "new()" );      #$logger->debug( __PACKAGE__ . "->" . "new()" );
59    
60      # V1 - arguments become properties automagically / normal perl mode blessing
61    =pod
62      # autovivify passed-in arguments as future object attributes into to-be-blessed hash
63      my $self = { @_ };
64      # create object from blessed hash-reference
65      bless $self, $class;
66    =cut
67    
68    
69      # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash...
70      my $self = Tie::SecureHash->new(
71        $class,
72        # that's it:
73          'metainfo' => undef,
74          'lock_info' => undef,
75          '_COREHANDLE' => undef,
76          'meta' => undef,
77          'locator' => undef,
78          'dataStorageLayer' => undef,
79          'dbi' => undef,
80        # tries:
81          #'Data::Storage::Handler::Abstract::metainfo' => undef,
82          #'dataStorageLayer'
83          #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef,
84          #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef,
85          #'Data::Dumper::locator' => undef,
86          #$class . '::locator' => undef,
87          #'Data::Storage::Handler::Tangram::locator' => undef,
88          #'Data::Storage::Handler::DBI::locator' => undef,
89          #_protected => ,
90          #__private => ,
91      );
92    
93    
94      # merge passed-in arguments to constructor as properties into already blessed secure object
95        
96        # mungle arguments from array into hash - perl does the job  ;)
97        my %args = @_;
98      
99        # merge attributes one-by-one
100        # TODO: deep_copy? / merge_deep?
101        foreach (keys %args) {
102          #print "key: $_", "\n";
103          $self->{$_} = $args{$_};
104        }
105      
106      # V3 - rolling our own security (just for {COREHANDLE} - nothing else)  -  nope, Tie::SecureHash works wonderful
107      #my $self = { @_ };
108      #bless $self, $class;
109      
110      
111    
112    # handle meta data    # handle meta data
113      my $metainfo = _getMetaInfo($class);      #my $metainfo = $self->getMetaInfo($class);
114        my $metainfo = $self->getMetaInfo();
115      if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }      if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
116      # type?      # type?
117      $invocant =~ s/Data::Storage::Handler:://;      $invocant =~ s/Data::Storage::Handler:://;
118      $metainfo->{type} = $invocant;      $metainfo->{type} = $invocant;
119    
   # create object from blessed hash-reference  
120      # direct accessible (non-protected) properties         ( was: my $self = { }; )      # direct accessible (non-protected) properties         ( was: my $self = { }; )
121      my $self = { metainfo => $metainfo, @_ };      $self->{metainfo} = $metainfo;
     bless $self, $class;  
122    
123    return $self;    return $self;
124  }  }
# Line 69  sub AUTOLOAD { Line 145  sub AUTOLOAD {
145    # find out methodname    # find out methodname
146    my $methodname = $AUTOLOAD;    my $methodname = $AUTOLOAD;
147    $methodname =~ s/^.*:://;    $methodname =~ s/^.*:://;
148      
149    #print "method: $methodname", "\n";
150      
151      # TODO: document this! handler-private methods listed here will not be triggered (internal use)
152      # in this case, "exists" is a method reserved for Tie::SecureHash,
153      # which encapsulates the perl data structure (HASH) under this object
154      # this is to prevent deep recursion's
155      return if lc $methodname eq 'exists';
156    
157    #print "$methodname - 1", "\n";
158    
159      # TODO: enhance logging/debugging
160      #if (!$self->exists('COREHANDLE')) { return; }
161    
162    # handle locking (hack)    # handle locking (hack)
163    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}) {
164      $self->{lock_info}->{log_lock} = 1;      $self->{lock_info}->{log_lock} = 1;
165    } else {    } else {
166      $self->{lock_info}->{log_lock} = 0;      $self->{lock_info}->{log_lock} = 0;
167    }    }
168    $self->{lock_info}->{last_method} = $methodname;    $self->{lock_info}->{last_method} = $methodname;
169        
170    #print "$methodname - 2", "\n";
171    
172    #print Dumper($self);
173    #exit;
174    
175      # get corehandle instance from underlying handler
176      my $core = $self->getCOREHANDLE();
177    
178    # test for COREHANDLE    # test for COREHANDLE
179    if (!$self->{COREHANDLE}) {    #if (!$self->{_COREHANDLE}) {
180      #print "no COREHANDLE", "\n";  #=pod
181      if (!$self->{lock_info}->{log_lock}) {    #if (!$self->exists('_COREHANDLE')) {
182        $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );    #if (!$self->{_COREHANDLE}) {
183      if (!$core) {
184        my $err_msg_core = __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"";
185    print $err_msg_core, "\n";
186        if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
187          $logger->error( $err_msg_core );
188      }      }
189      return;      return;
190    }    }
191    #=cut
192    
193    #print "$methodname - 3", "\n";
194    
195    # try to dispatch method-call to Storage::Handler::*    # try to dispatch method-call to Storage::Handler::*
196    #if ($self->can($methodname)) {    #if ($self->can($methodname)) {
# Line 94  sub AUTOLOAD { Line 199  sub AUTOLOAD {
199      #if ($res) { return $res; }      #if ($res) { return $res; }
200    #}    #}
201    
202    #print "$methodname - 4", "\n";
203    
204    # try to dispatch method-call to COREHANDLE    # try to dispatch method-call to COREHANDLE
205    if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {    # was:
206      #my $core = $self->{_COREHANDLE};
207      # is:
208      #my $core = $self->getCOREHANDLE();
209    
210    #print Dumper($core);
211    #exit;
212    
213      # was:
214      #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
215      # is:
216      if ($core->can($methodname) || $core->can("AUTOLOAD")) {
217      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
218      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');      #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
219      if (!$self->{lock_info}->{log_lock}) {      if (!$self->{lock_info}->{log_lock}) {
# Line 106  sub AUTOLOAD { Line 224  sub AUTOLOAD {
224      }      }
225      #$lock_AUTOLOAD = 0;      #$lock_AUTOLOAD = 0;
226      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );      #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
227      return $self->{COREHANDLE}->$methodname(@_);      
228    #print "calling: $methodname", "\n";
229        
230        # method calls doing it until here will get dispatched to the proper handler
231        return $core->$methodname(@_);
232      
233      } elsif ($self->can($methodname)) {
234        return $self->$methodname(@_);
235    }    }
236    
237  }  }
238    
239  sub DESTROY {  sub DESTROY {
240    my $self = shift;    my $self = shift;
241    if ($self->{COREHANDLE}) {    #if ($self->{COREHANDLE}) {
242      if ($self->exists('_COREHANDLE')) {
243      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );      $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
244    
245      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};      my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
246    
247      # call "disconnect" or alike on COREHANDLE      # call "disconnect" or alike on COREHANDLE
248      # was: $self->{COREHANDLE}->disconnect();      # was: $self->{COREHANDLE}->disconnect();
249      $disconnectMethod && ( $self->{COREHANDLE}->$disconnectMethod() );      $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
250    
251      undef $self->{COREHANDLE};      undef $self->{_COREHANDLE};
252    }    }
253  }  }
254    
255    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 {  
256    my $type = shift;    my $type = shift;
257    print "type: $type";    print "type: $type";
258    eval("use Data::Storage::$type;");    eval("use Data::Storage::$type;");
259  }  }
260    
 sub _getMetaInfo {  
   my $packagename = shift;  
   #return $self->$metainfo;  
   
   my $ns = '$' . $packagename . "::metainfo";  
   $logger->debug( __PACKAGE__ . "->" . "_getMetaInfo()" . "   " . "[$ns]" );  
   return eval($ns);  
 }  
   
261    
262  # ====================================================  # ====================================================
263  #   PUBLIC METHODS  #   PUBLIC METHODS
264  # ====================================================  # ====================================================
265    
266    # TODO: abstract "abstract methods" to list/hash to be used in AUTOLOAD    sub existsChildNode {
   # e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));  
   
   sub connect {  
       
267      my $self = shift;      my $self = shift;
268      $self->_abstract_function('connect');      my $nodename = shift;
269      return;      #$nodename = 'TransactionRoutingTable';
270            $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );
271      $logger->debug( "\"connect\" has to be implemented by handler!" );      $self->getChildNodes() unless $self->{meta}->{childnodes};
272      return;      my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});     # TODO: use "/i" only on win32-systems!
273        return $result;
274      }
275    
276      sub connect_tmp {
277            
278  #    my $self = shift;  #    my $self = shift;
279  #    my $connectionString = shift;  #    my $connectionString = shift;
# Line 174  sub _getMetaInfo { Line 282  sub _getMetaInfo {
282    
283    }    }
284        
285    
286    # ====================================================
287    #   CONCRETE METHOD DUMMIES (croaking via "$logger" by calling "_abstract_function")
288    # ====================================================
289    
290      # TODO:
291      #   - abstract "abstract methods" to list/hash to be used in AUTOLOAD
292      #      e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
293      #      use Class::XYZ (Construct)
294      #   - build them via anonymous subs
295      #   - introduce them via symbols
296    
297      sub getCOREHANDLE {
298        my $self = shift;
299        $self->_abstract_function('getCOREHANDLE');
300      }
301    
302    sub sendCommand {    sub sendCommand {
303      my $self = shift;      my $self = shift;
304      $self->_abstract_function('sendCommand');      $self->_abstract_function('sendCommand');
305    }    }
306    
307      sub existsChildNode_tmp {
308        my $self = shift;
309        $self->_abstract_function('existsChildNode');
310      }
311    
312    sub getChildNodes {    sub getChildNodes {
313      my $self = shift;      my $self = shift;
314      $self->_abstract_function('getChildNodes');      $self->_abstract_function('getChildNodes');
# Line 189  sub _getMetaInfo { Line 319  sub _getMetaInfo {
319      $self->_abstract_function('configureCOREHANDLE');      $self->_abstract_function('configureCOREHANDLE');
320    }    }
321    
 1;  
322      sub getMetaInfo {
323        my $self = shift;
324        $self->_abstract_function('getMetaInfo');
325        return;
326      }
327    
328      sub getListUnfiltered {
329        my $self = shift;
330        $self->_abstract_function('getListUnfiltered');
331        return;
332      }
333    
334      sub getListFiltered {
335        my $self = shift;
336        $self->_abstract_function('getListFiltered');
337        return;
338      }
339    
340      sub sendQuery {
341        my $self = shift;
342        $self->_abstract_function('sendQuery');
343        return;
344      }
345    
346      sub connect {
347        my $self = shift;
348        $self->_abstract_function('connect');
349        return;
350      }
351    
352      sub testIntegrity {
353        my $self = shift;
354        $self->_abstract_function('testIntegrity');
355        return;
356      }
357    
358      sub quoteSql {
359        my $self = shift;
360        $self->_abstract_function('quoteSql');
361        return;
362      }
363    
364      sub eraseAll {
365        my $self = shift;
366        $self->_abstract_function('eraseAll');
367        return;
368      }
369    
370      sub createDb {
371        my $self = shift;
372        $self->_abstract_function('createDb');
373        return;
374      }
375    
376      sub dropDb {
377        my $self = shift;
378        $self->_abstract_function('dropDb');
379        return;
380      }
381    
382      sub rebuildDb {
383        my $self = shift;
384        $self->_abstract_function('rebuildDb');
385        return;
386      }
387    
388    1;

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.9

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