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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (hide annotations)
Tue May 13 07:58:49 2003 UTC (21 years, 1 month ago) by joko
Branch: MAIN
Changes since 1.16: +14 -2 lines
fix: die if methodname is empty
fixes to log-string

1 joko 1.11 ## ------------------------------------------------------------------------
2 joko 1.17 ## $Id: Abstract.pm,v 1.16 2003/04/18 16:07:53 joko Exp $
3 joko 1.11 ## ------------------------------------------------------------------------
4 joko 1.7 ## $Log: Abstract.pm,v $
5 joko 1.17 ## Revision 1.16 2003/04/18 16:07:53 joko
6     ## just use logger if instantiation successed
7     ##
8 joko 1.16 ## Revision 1.15 2003/02/20 20:19:13 joko
9     ## tried to get auto-disconnect working again - failed with that
10     ##
11 joko 1.15 ## Revision 1.14 2003/02/09 05:12:28 joko
12     ## + quoting of strings used in sql-queries!
13     ##
14 joko 1.14 ## Revision 1.13 2003/01/30 22:27:05 joko
15     ## + added new abstract methods
16     ##
17 joko 1.13 ## Revision 1.12 2003/01/30 21:46:32 joko
18     ## + fixed behaviour of AUTOLOAD-method
19     ##
20 joko 1.12 ## Revision 1.11 2003/01/20 16:43:18 joko
21     ## + better argument-property merging
22     ## + debugging-output !!!
23     ## + abstract-dummy 'sub createChildNode'
24     ##
25 joko 1.11 ## Revision 1.10 2003/01/19 02:31:51 joko
26     ## + fix to 'sub AUTOLOAD'
27     ##
28 joko 1.10 ## 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 joko 1.9 ## Revision 1.8 2002/12/13 21:48:35 joko
32     ## + sub _abstract_function
33     ##
34 joko 1.8 ## 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 joko 1.7 ## 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 joko 1.11 ## ------------------------------------------------------------------------
57 joko 1.7
58 cvsjoko 1.1
59     package Data::Storage::Handler::Abstract;
60    
61     use strict;
62     use warnings;
63    
64 joko 1.8 use base qw( DesignPattern::Object );
65    
66 joko 1.11
67 cvsjoko 1.1 use Data::Dumper;
68 joko 1.7 use Tie::SecureHash;
69     #use Data::Storage::Handler;
70 joko 1.15 use Hash::Merge qw( merge );
71 joko 1.11
72 joko 1.16 #use Log::Dispatch::Config;
73     #Log::Dispatch::Config->configure();
74 cvsjoko 1.1
75     # get logger instance
76 joko 1.16 my $logger;
77     eval('$logger = Log::Dispatch::Config->instance;');
78 cvsjoko 1.1
79     #our $lock_info;
80    
81     sub new {
82     my $invocant = shift;
83     my $class = ref($invocant) || $invocant;
84    
85     # logging info about the actual handler called
86 joko 1.16 $logger->debug( "$invocant->new( @_ )" ) if $logger;
87 joko 1.2 #$logger->debug( __PACKAGE__ . "->" . "new()" );
88 cvsjoko 1.1
89 joko 1.7 # 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 joko 1.3 my $self = { @_ };
93     # create object from blessed hash-reference
94     bless $self, $class;
95 joko 1.7 =cut
96    
97 joko 1.10 #=pod
98 joko 1.7 # 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 joko 1.10 #=cut
122 joko 1.7
123     # merge passed-in arguments to constructor as properties into already blessed secure object
124 joko 1.11
125 joko 1.7 # mungle arguments from array into hash - perl does the job ;)
126 joko 1.11 #my %args = @_;
127     #my %args = ();
128    
129     #print Dumper(@_);
130    
131 joko 1.7 # merge attributes one-by-one
132     # TODO: deep_copy? / merge_deep?
133 joko 1.11 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 joko 1.7 }
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 joko 1.3
150 cvsjoko 1.1 # handle meta data
151 joko 1.3 #my $metainfo = $self->getMetaInfo($class);
152     my $metainfo = $self->getMetaInfo();
153 cvsjoko 1.1 if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
154     # type?
155     $invocant =~ s/Data::Storage::Handler:://;
156     $metainfo->{type} = $invocant;
157    
158     # direct accessible (non-protected) properties ( was: my $self = { }; )
159 joko 1.3 $self->{metainfo} = $metainfo;
160 cvsjoko 1.1
161     return $self;
162     }
163    
164    
165 joko 1.10 # TODO: use NEXT.pm inside this mechanism (to avoid repetitions...)
166 cvsjoko 1.1 sub AUTOLOAD {
167    
168     # recursion problem to be avoided here!!!
169    
170     # - problem: we get recursion-hangs!!! => perl stops with ...
171     # "Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD" at [...]/libs/Data/Storage.pm line 38."
172    
173     # - when: if we log to ourselves as a storage-implementation (e.g. via Log::Dispatch::Tangram)
174     # - why: debug-messages are on a very low level including every data-operation to "Data::Storage(::Handler::X)",
175     # so e.g. a "$storage->insert" would trigger another "$storage->insert" itself
176     # which leads to a infinite recursion loop (deep recursion)
177 joko 1.2 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
178 cvsjoko 1.1
179     my $self = shift;
180    
181     our $AUTOLOAD;
182     #return if $AUTOLOAD =~ m/::DESTROY$/;
183    
184     # find out methodname
185     my $methodname = $AUTOLOAD;
186     $methodname =~ s/^.*:://;
187 joko 1.7
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 joko 1.12 #print "$methodname - 1", "\n";
197 joko 1.7
198     # TODO: enhance logging/debugging
199     #if (!$self->exists('COREHANDLE')) { return; }
200 cvsjoko 1.1
201     # handle locking (hack)
202 joko 1.10 if ($self->can('exists') && $self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
203 cvsjoko 1.1 $self->{lock_info}->{log_lock} = 1;
204     } else {
205     $self->{lock_info}->{log_lock} = 0;
206     }
207     $self->{lock_info}->{last_method} = $methodname;
208    
209 joko 1.12 #print "$methodname - 2", "\n";
210 joko 1.7
211     #print Dumper($self);
212     #exit;
213    
214     # get corehandle instance from underlying handler
215     my $core = $self->getCOREHANDLE();
216    
217 cvsjoko 1.1 # test for COREHANDLE
218 joko 1.7 #if (!$self->{_COREHANDLE}) {
219     #=pod
220     #if (!$self->exists('_COREHANDLE')) {
221     #if (!$self->{_COREHANDLE}) {
222     if (!$core) {
223 joko 1.10
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 joko 1.12
232     #print $err_msg_core, "\n";
233    
234     #if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
235 joko 1.7 $logger->error( $err_msg_core );
236 joko 1.12 #}
237    
238 cvsjoko 1.1 return;
239 joko 1.12
240 cvsjoko 1.1 }
241 joko 1.7 #=cut
242    
243 joko 1.17 if (!$methodname) {
244     die("Methodname is not defined!");
245     return;
246     }
247    
248 joko 1.7 #print "$methodname - 3", "\n";
249 cvsjoko 1.1
250     # try to dispatch method-call to Storage::Handler::*
251     #if ($self->can($methodname)) {
252     #$logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
253     #my $res = $self->$methodname(@_);
254     #if ($res) { return $res; }
255     #}
256    
257 joko 1.7 #print "$methodname - 4", "\n";
258    
259 cvsjoko 1.1 # try to dispatch method-call to COREHANDLE
260 joko 1.7 # was:
261     #my $core = $self->{_COREHANDLE};
262     # is:
263     #my $core = $self->getCOREHANDLE();
264    
265     #print Dumper($core);
266     #exit;
267    
268     # was:
269     #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
270     # is:
271     if ($core->can($methodname) || $core->can("AUTOLOAD")) {
272 cvsjoko 1.1 #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
273     #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
274     if (!$self->{lock_info}->{log_lock}) {
275     #print "method: $methodname", "\n";
276 joko 1.17 my $type = $self->{metainfo}->{type};
277     $type ||= '';
278     # FIXME!
279     #$logger->debug( __PACKAGE__ . "[$type]" . "->" . $methodname . "(@_)" );
280     $logger->debug( __PACKAGE__ . "[$type]" . "->" . $methodname );
281 cvsjoko 1.1 } else {
282     # AUTOLOAD - sub is locked to prevent deep recursions if (e.g.) db-inserts cause log-actions to same db itself
283     }
284     #$lock_AUTOLOAD = 0;
285     #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
286 joko 1.3
287 joko 1.7 #print "calling: $methodname", "\n";
288    
289 joko 1.10 # method calls making it until here will get dispatched to the proper handler
290 joko 1.7 return $core->$methodname(@_);
291 joko 1.6
292     } elsif ($self->can($methodname)) {
293 joko 1.10 # try to call specified method inside our or inherited module(s) scope(s)
294 joko 1.6 return $self->$methodname(@_);
295 cvsjoko 1.1 }
296    
297     }
298    
299     sub DESTROY {
300     my $self = shift;
301 joko 1.15
302     return;
303    
304     $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
305    
306     my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
307     print "meth: ", $disconnectMethod, "\n";
308    
309     #$disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
310     $self->{_COREHANDLE}->$disconnectMethod();
311     #$self->$disconnectMethod();
312    
313     #my $core1 = $self->getCOREHANDLE() if $self->can('getCOREHANDLE');
314     #$core1->$disconnectMethod();
315    
316     return;
317    
318     print "DESTROY-1", "\n";
319     #if ($self->{__COREHANDLE}) {
320     #if ($self->exists('_COREHANDLE')) {
321    
322     # get corehandle instance from underlying handler
323     my $core;
324     $core = $self->getCOREHANDLE() if $self->can('getCOREHANDLE');
325    
326     #if ($self->{STORAGEHANDLE}) {
327     if ($core) {
328     print "DESTROY-2", "\n";
329 cvsjoko 1.1 $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
330    
331     my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
332    
333     # call "disconnect" or alike on COREHANDLE
334     # was: $self->{COREHANDLE}->disconnect();
335 joko 1.7 $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
336 cvsjoko 1.1
337 joko 1.7 undef $self->{_COREHANDLE};
338 cvsjoko 1.1 }
339     }
340    
341 joko 1.7 sub _typeCheck2 {
342 cvsjoko 1.1 my $type = shift;
343     print "type: $type";
344     eval("use Data::Storage::$type;");
345     }
346    
347    
348     # ====================================================
349     # PUBLIC METHODS
350     # ====================================================
351    
352 joko 1.3 sub existsChildNode {
353     my $self = shift;
354     my $nodename = shift;
355 joko 1.14
356     # TODO: don't use $self->{meta}->{childnodes} directly in here
357     # get it returned from $self->getChildNodes()!!!
358    
359     $logger->debug( __PACKAGE__ . "->existsChildNode( nodename=$nodename )" );
360 joko 1.3 $self->getChildNodes() unless $self->{meta}->{childnodes};
361 joko 1.14
362     # quote this, it might contain meta characters which don't work in a regex
363     $nodename = quotemeta($nodename);
364    
365     # trace
366     #print Dumper($self->{meta});
367     #print "nodename: $nodename", "\n";
368    
369     # FIXME: use "/i" only on win32-systems!
370     my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}});
371    
372 joko 1.3 return $result;
373     }
374 cvsjoko 1.1
375 joko 1.3 sub connect_tmp {
376 cvsjoko 1.1
377     # my $self = shift;
378     # my $connectionString = shift;
379     # # todo: patch connectionString to $args
380     # _typeCheck($self->{args}{type});
381    
382     }
383    
384 joko 1.3
385     # ====================================================
386     # CONCRETE METHOD DUMMIES (croaking via "$logger" by calling "_abstract_function")
387     # ====================================================
388    
389     # TODO:
390     # - abstract "abstract methods" to list/hash to be used in AUTOLOAD
391     # e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
392 joko 1.4 # use Class::XYZ (Construct)
393 joko 1.3 # - build them via anonymous subs
394     # - introduce them via symbols
395    
396 joko 1.7 sub getCOREHANDLE {
397     my $self = shift;
398     $self->_abstract_function('getCOREHANDLE');
399     }
400    
401 cvsjoko 1.1 sub sendCommand {
402     my $self = shift;
403     $self->_abstract_function('sendCommand');
404 joko 1.11 }
405    
406     sub createChildNode {
407     my $self = shift;
408     $self->_abstract_function('createChildNode');
409 joko 1.7 }
410    
411     sub existsChildNode_tmp {
412     my $self = shift;
413     $self->_abstract_function('existsChildNode');
414 cvsjoko 1.1 }
415    
416     sub getChildNodes {
417     my $self = shift;
418     $self->_abstract_function('getChildNodes');
419     }
420    
421     sub configureCOREHANDLE {
422     my $self = shift;
423     $self->_abstract_function('configureCOREHANDLE');
424     }
425    
426 joko 1.3 sub getMetaInfo {
427     my $self = shift;
428     $self->_abstract_function('getMetaInfo');
429     return;
430     }
431    
432     sub getListUnfiltered {
433     my $self = shift;
434     $self->_abstract_function('getListUnfiltered');
435     return;
436     }
437    
438     sub getListFiltered {
439     my $self = shift;
440     $self->_abstract_function('getListFiltered');
441     return;
442     }
443    
444     sub sendQuery {
445     my $self = shift;
446     $self->_abstract_function('sendQuery');
447     return;
448     }
449    
450     sub connect {
451     my $self = shift;
452     $self->_abstract_function('connect');
453     return;
454     }
455    
456     sub testIntegrity {
457     my $self = shift;
458     $self->_abstract_function('testIntegrity');
459     return;
460     }
461    
462     sub quoteSql {
463     my $self = shift;
464     $self->_abstract_function('quoteSql');
465 joko 1.4 return;
466     }
467    
468     sub eraseAll {
469     my $self = shift;
470     $self->_abstract_function('eraseAll');
471     return;
472     }
473    
474     sub createDb {
475     my $self = shift;
476     $self->_abstract_function('createDb');
477 joko 1.9 return;
478     }
479    
480     sub dropDb {
481     my $self = shift;
482     $self->_abstract_function('dropDb');
483     return;
484     }
485    
486     sub rebuildDb {
487     my $self = shift;
488     $self->_abstract_function('rebuildDb');
489 joko 1.13 return;
490     }
491    
492     sub getDbName {
493     my $self = shift;
494     $self->_abstract_function('getDbName');
495     return;
496     }
497    
498     sub testAvailability {
499     my $self = shift;
500     $self->_abstract_function('testAvailability');
501     return;
502     }
503    
504     sub isConnected {
505     my $self = shift;
506     $self->_abstract_function('isConnected');
507     return;
508     }
509    
510     sub testDsn {
511     my $self = shift;
512     $self->_abstract_function('testDsn');
513 joko 1.3 return;
514     }
515    
516     1;

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