/[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.15 - (hide annotations)
Thu Feb 20 20:19:13 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.14: +33 -4 lines
tried to get auto-disconnect working again - failed with that

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

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