/[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.9 - (hide annotations)
Thu Dec 19 16:30:23 2002 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.8: +16 -1 lines
+ added 'sub dropDb' and 'sub rebuildDb' as croakers for concrete implementations of methods in proper handlers

1 joko 1.7 ## --------------------------------------------------------------------------------
2 joko 1.9 ## $Id: Abstract.pm,v 1.8 2002/12/13 21:48:35 joko Exp $
3 joko 1.7 ## --------------------------------------------------------------------------------
4     ## $Log: Abstract.pm,v $
5 joko 1.9 ## Revision 1.8 2002/12/13 21:48:35 joko
6     ## + sub _abstract_function
7     ##
8 joko 1.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 joko 1.7 ## 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 cvsjoko 1.1
33     package Data::Storage::Handler::Abstract;
34    
35     use strict;
36     use warnings;
37    
38 joko 1.8 use base qw( DesignPattern::Object );
39    
40 cvsjoko 1.1 use Data::Dumper;
41 joko 1.7 use Tie::SecureHash;
42     #use Data::Storage::Handler;
43 cvsjoko 1.1
44     # get logger instance
45     my $logger = Log::Dispatch::Config->instance;
46    
47     #our $lock_info;
48    
49     sub new {
50     my $invocant = shift;
51     my $class = ref($invocant) || $invocant;
52    
53     # logging info about the actual handler called
54     $logger->debug( "$invocant->new( @_ )" );
55 joko 1.2 #$logger->debug( __PACKAGE__ . "->" . "new()" );
56 cvsjoko 1.1
57 joko 1.7 # 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 joko 1.3 my $self = { @_ };
61     # create object from blessed hash-reference
62     bless $self, $class;
63 joko 1.7 =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 joko 1.3
109 cvsjoko 1.1 # handle meta data
110 joko 1.3 #my $metainfo = $self->getMetaInfo($class);
111     my $metainfo = $self->getMetaInfo();
112 cvsjoko 1.1 if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
113     # type?
114     $invocant =~ s/Data::Storage::Handler:://;
115     $metainfo->{type} = $invocant;
116    
117     # direct accessible (non-protected) properties ( was: my $self = { }; )
118 joko 1.3 $self->{metainfo} = $metainfo;
119 cvsjoko 1.1
120     return $self;
121     }
122    
123    
124     sub AUTOLOAD {
125    
126     # recursion problem to be avoided here!!!
127    
128     # - problem: we get recursion-hangs!!! => perl stops with ...
129     # "Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD" at [...]/libs/Data/Storage.pm line 38."
130    
131     # - when: if we log to ourselves as a storage-implementation (e.g. via Log::Dispatch::Tangram)
132     # - 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
134     # which leads to a infinite recursion loop (deep recursion)
135 joko 1.2 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
136 cvsjoko 1.1
137     my $self = shift;
138    
139     our $AUTOLOAD;
140     #return if $AUTOLOAD =~ m/::DESTROY$/;
141    
142     # find out methodname
143     my $methodname = $AUTOLOAD;
144     $methodname =~ s/^.*:://;
145 joko 1.7
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 cvsjoko 1.1
159     # handle locking (hack)
160 joko 1.7 if ($self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
161 cvsjoko 1.1 $self->{lock_info}->{log_lock} = 1;
162     } else {
163     $self->{lock_info}->{log_lock} = 0;
164     }
165     $self->{lock_info}->{last_method} = $methodname;
166    
167 joko 1.7 #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 cvsjoko 1.1 # test for COREHANDLE
176 joko 1.7 #if (!$self->{_COREHANDLE}) {
177     #=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 joko 1.2 }
186 cvsjoko 1.1 return;
187     }
188 joko 1.7 #=cut
189    
190     #print "$methodname - 3", "\n";
191 cvsjoko 1.1
192     # try to dispatch method-call to Storage::Handler::*
193     #if ($self->can($methodname)) {
194     #$logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
195     #my $res = $self->$methodname(@_);
196     #if ($res) { return $res; }
197     #}
198    
199 joko 1.7 #print "$methodname - 4", "\n";
200    
201 cvsjoko 1.1 # try to dispatch method-call to COREHANDLE
202 joko 1.7 # 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 cvsjoko 1.1 #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
215     #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
216     if (!$self->{lock_info}->{log_lock}) {
217     #print "method: $methodname", "\n";
218     $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
219     } else {
220     # AUTOLOAD - sub is locked to prevent deep recursions if (e.g.) db-inserts cause log-actions to same db itself
221     }
222     #$lock_AUTOLOAD = 0;
223     #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
224 joko 1.3
225 joko 1.7 #print "calling: $methodname", "\n";
226    
227 joko 1.3 # method calls doing it until here will get dispatched to the proper handler
228 joko 1.7 return $core->$methodname(@_);
229 joko 1.6
230     } elsif ($self->can($methodname)) {
231     return $self->$methodname(@_);
232 cvsjoko 1.1 }
233    
234     }
235    
236     sub DESTROY {
237     my $self = shift;
238 joko 1.7 #if ($self->{COREHANDLE}) {
239     if ($self->exists('_COREHANDLE')) {
240 cvsjoko 1.1 $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
241    
242     my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
243    
244     # call "disconnect" or alike on COREHANDLE
245     # was: $self->{COREHANDLE}->disconnect();
246 joko 1.7 $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
247 cvsjoko 1.1
248 joko 1.7 undef $self->{_COREHANDLE};
249 cvsjoko 1.1 }
250     }
251    
252 joko 1.7 sub _typeCheck2 {
253 cvsjoko 1.1 my $type = shift;
254     print "type: $type";
255     eval("use Data::Storage::$type;");
256     }
257    
258    
259     # ====================================================
260     # PUBLIC METHODS
261     # ====================================================
262    
263 joko 1.3 sub existsChildNode {
264     my $self = shift;
265     my $nodename = shift;
266     #$nodename = 'TransactionRoutingTable';
267     $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );
268     $self->getChildNodes() unless $self->{meta}->{childnodes};
269     my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}}); # TODO: use "/i" only on win32-systems!
270     return $result;
271     }
272 cvsjoko 1.1
273 joko 1.3 sub connect_tmp {
274 cvsjoko 1.1
275     # my $self = shift;
276     # my $connectionString = shift;
277     # # todo: patch connectionString to $args
278     # _typeCheck($self->{args}{type});
279    
280     }
281    
282 joko 1.3
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 joko 1.4 # use Class::XYZ (Construct)
291 joko 1.3 # - build them via anonymous subs
292     # - introduce them via symbols
293    
294 joko 1.7 sub getCOREHANDLE {
295     my $self = shift;
296     $self->_abstract_function('getCOREHANDLE');
297     }
298    
299 cvsjoko 1.1 sub sendCommand {
300     my $self = shift;
301     $self->_abstract_function('sendCommand');
302 joko 1.7 }
303    
304     sub existsChildNode_tmp {
305     my $self = shift;
306     $self->_abstract_function('existsChildNode');
307 cvsjoko 1.1 }
308    
309     sub getChildNodes {
310     my $self = shift;
311     $self->_abstract_function('getChildNodes');
312     }
313    
314     sub configureCOREHANDLE {
315     my $self = shift;
316     $self->_abstract_function('configureCOREHANDLE');
317     }
318    
319 joko 1.3 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 joko 1.4 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 joko 1.9 return;
371     }
372    
373     sub dropDb {
374     my $self = shift;
375     $self->_abstract_function('dropDb');
376     return;
377     }
378    
379     sub rebuildDb {
380     my $self = shift;
381     $self->_abstract_function('rebuildDb');
382 joko 1.3 return;
383     }
384    
385     1;

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