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

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.8

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