/[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.7 - (hide annotations)
Thu Dec 5 07:57:48 2002 UTC (21 years, 7 months ago) by joko
Branch: MAIN
Changes since 1.6: +144 -36 lines
+ now using Tie::SecureHash as a base for the COREHANDLE
+ former public COREHANDLE becomes private _COREHANDLE now

1 joko 1.7 ## --------------------------------------------------------------------------------
2     ## $Id: Abstract.pm,v 1.6 2002/12/03 15:52:24 joko Exp $
3     ## --------------------------------------------------------------------------------
4     ## $Log: Abstract.pm,v $
5     ## Revision 1.6 2002/12/03 15:52:24 joko
6     ## + fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level
7     ##
8     ## Revision 1.5 2002/12/01 22:19:33 joko
9     ## + just disconnect if COREHANDLE exists
10     ##
11     ## Revision 1.4 2002/12/01 04:45:38 joko
12     ## + sub eraseAll
13     ## + sub createDb
14     ##
15     ## Revision 1.3 2002/11/29 04:58:20 joko
16     ## + Storage::Result now uses the same dispatching mechanism like Storage::Handler
17     ##
18     ## Revision 1.2 2002/10/17 00:08:07 joko
19     ## + bugfixes regarding "deep recursion" stuff
20     ##
21     ## Revision 1.1 2002/10/10 03:44:07 cvsjoko
22     ## + new
23     ## --------------------------------------------------------------------------------
24    
25 cvsjoko 1.1
26     package Data::Storage::Handler::Abstract;
27    
28     use strict;
29     use warnings;
30    
31     use Data::Dumper;
32 joko 1.7 use Tie::SecureHash;
33     #use Data::Storage::Handler;
34 cvsjoko 1.1
35     # get logger instance
36     my $logger = Log::Dispatch::Config->instance;
37    
38     #our $lock_info;
39    
40     sub new {
41     my $invocant = shift;
42     my $class = ref($invocant) || $invocant;
43    
44     # logging info about the actual handler called
45     $logger->debug( "$invocant->new( @_ )" );
46 joko 1.2 #$logger->debug( __PACKAGE__ . "->" . "new()" );
47 cvsjoko 1.1
48 joko 1.7 # V1 - arguments become properties automagically / normal perl mode blessing
49     =pod
50     # autovivify passed-in arguments as future object attributes into to-be-blessed hash
51 joko 1.3 my $self = { @_ };
52     # create object from blessed hash-reference
53     bless $self, $class;
54 joko 1.7 =cut
55    
56    
57     # V2 - maybe more convenient/secure? utilizing Damian Conway's Tie::SecureHash...
58     my $self = Tie::SecureHash->new(
59     $class,
60     # that's it:
61     'metainfo' => undef,
62     'lock_info' => undef,
63     '_COREHANDLE' => undef,
64     'meta' => undef,
65     'locator' => undef,
66     'dataStorageLayer' => undef,
67     'dbi' => undef,
68     # tries:
69     #'Data::Storage::Handler::Abstract::metainfo' => undef,
70     #'dataStorageLayer'
71     #'Data::Storage::Handler::Abstract::dataStorageLayer' => undef,
72     #'Data::Storage::Handler::Tangram::dataStorageLayer' => undef,
73     #'Data::Dumper::locator' => undef,
74     #$class . '::locator' => undef,
75     #'Data::Storage::Handler::Tangram::locator' => undef,
76     #'Data::Storage::Handler::DBI::locator' => undef,
77     #_protected => ,
78     #__private => ,
79     );
80    
81    
82     # merge passed-in arguments to constructor as properties into already blessed secure object
83    
84     # mungle arguments from array into hash - perl does the job ;)
85     my %args = @_;
86    
87     # merge attributes one-by-one
88     # TODO: deep_copy? / merge_deep?
89     foreach (keys %args) {
90     #print "key: $_", "\n";
91     $self->{$_} = $args{$_};
92     }
93    
94     # V3 - rolling our own security (just for {COREHANDLE} - nothing else) - nope, Tie::SecureHash works wonderful
95     #my $self = { @_ };
96     #bless $self, $class;
97    
98    
99 joko 1.3
100 cvsjoko 1.1 # handle meta data
101 joko 1.3 #my $metainfo = $self->getMetaInfo($class);
102     my $metainfo = $self->getMetaInfo();
103 cvsjoko 1.1 if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
104     # type?
105     $invocant =~ s/Data::Storage::Handler:://;
106     $metainfo->{type} = $invocant;
107    
108     # direct accessible (non-protected) properties ( was: my $self = { }; )
109 joko 1.3 $self->{metainfo} = $metainfo;
110 cvsjoko 1.1
111     return $self;
112     }
113    
114    
115     sub AUTOLOAD {
116    
117     # recursion problem to be avoided here!!!
118    
119     # - problem: we get recursion-hangs!!! => perl stops with ...
120     # "Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD" at [...]/libs/Data/Storage.pm line 38."
121    
122     # - when: if we log to ourselves as a storage-implementation (e.g. via Log::Dispatch::Tangram)
123     # - why: debug-messages are on a very low level including every data-operation to "Data::Storage(::Handler::X)",
124     # so e.g. a "$storage->insert" would trigger another "$storage->insert" itself
125     # which leads to a infinite recursion loop (deep recursion)
126 joko 1.2 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
127 cvsjoko 1.1
128     my $self = shift;
129    
130     our $AUTOLOAD;
131     #return if $AUTOLOAD =~ m/::DESTROY$/;
132    
133     # find out methodname
134     my $methodname = $AUTOLOAD;
135     $methodname =~ s/^.*:://;
136 joko 1.7
137     #print "method: $methodname", "\n";
138    
139     # TODO: document this! handler-private methods listed here will not be triggered (internal use)
140     # in this case, "exists" is a method reserved for Tie::SecureHash,
141     # which encapsulates the perl data structure (HASH) under this object
142     # this is to prevent deep recursion's
143     return if lc $methodname eq 'exists';
144    
145     #print "$methodname - 1", "\n";
146    
147     # TODO: enhance logging/debugging
148     #if (!$self->exists('COREHANDLE')) { return; }
149 cvsjoko 1.1
150     # handle locking (hack)
151 joko 1.7 if ($self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
152 cvsjoko 1.1 $self->{lock_info}->{log_lock} = 1;
153     } else {
154     $self->{lock_info}->{log_lock} = 0;
155     }
156     $self->{lock_info}->{last_method} = $methodname;
157    
158 joko 1.7 #print "$methodname - 2", "\n";
159    
160     #print Dumper($self);
161     #exit;
162    
163     # get corehandle instance from underlying handler
164     my $core = $self->getCOREHANDLE();
165    
166 cvsjoko 1.1 # test for COREHANDLE
167 joko 1.7 #if (!$self->{_COREHANDLE}) {
168     #=pod
169     #if (!$self->exists('_COREHANDLE')) {
170     #if (!$self->{_COREHANDLE}) {
171     if (!$core) {
172     my $err_msg_core = __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"";
173     print $err_msg_core, "\n";
174     if ($self->exists('lock_info') && !$self->{lock_info}->{log_lock}) {
175     $logger->error( $err_msg_core );
176 joko 1.2 }
177 cvsjoko 1.1 return;
178     }
179 joko 1.7 #=cut
180    
181     #print "$methodname - 3", "\n";
182 cvsjoko 1.1
183     # try to dispatch method-call to Storage::Handler::*
184     #if ($self->can($methodname)) {
185     #$logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
186     #my $res = $self->$methodname(@_);
187     #if ($res) { return $res; }
188     #}
189    
190 joko 1.7 #print "$methodname - 4", "\n";
191    
192 cvsjoko 1.1 # try to dispatch method-call to COREHANDLE
193 joko 1.7 # was:
194     #my $core = $self->{_COREHANDLE};
195     # is:
196     #my $core = $self->getCOREHANDLE();
197    
198     #print Dumper($core);
199     #exit;
200    
201     # was:
202     #if ($self->{_COREHANDLE}->can($methodname) || $self->{_COREHANDLE}->can("AUTOLOAD")) {
203     # is:
204     if ($core->can($methodname) || $core->can("AUTOLOAD")) {
205 cvsjoko 1.1 #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
206     #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
207     if (!$self->{lock_info}->{log_lock}) {
208     #print "method: $methodname", "\n";
209     $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
210     } else {
211     # AUTOLOAD - sub is locked to prevent deep recursions if (e.g.) db-inserts cause log-actions to same db itself
212     }
213     #$lock_AUTOLOAD = 0;
214     #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
215 joko 1.3
216 joko 1.7 #print "calling: $methodname", "\n";
217    
218 joko 1.3 # method calls doing it until here will get dispatched to the proper handler
219 joko 1.7 return $core->$methodname(@_);
220 joko 1.6
221     } elsif ($self->can($methodname)) {
222     return $self->$methodname(@_);
223 cvsjoko 1.1 }
224    
225     }
226    
227     sub DESTROY {
228     my $self = shift;
229 joko 1.7 #if ($self->{COREHANDLE}) {
230     if ($self->exists('_COREHANDLE')) {
231 cvsjoko 1.1 $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
232    
233     my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
234    
235     # call "disconnect" or alike on COREHANDLE
236     # was: $self->{COREHANDLE}->disconnect();
237 joko 1.7 $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
238 cvsjoko 1.1
239 joko 1.7 undef $self->{_COREHANDLE};
240 cvsjoko 1.1 }
241     }
242    
243    
244     sub _abstract_function {
245     my $self = shift;
246     my $fName = shift;
247     my $class = ref($self);
248 joko 1.7 # was:
249     # $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\"");
250     # is:
251     die( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\"");
252 cvsjoko 1.1 #exit;
253     }
254    
255 joko 1.7 sub _typeCheck2 {
256 cvsjoko 1.1 my $type = shift;
257     print "type: $type";
258     eval("use Data::Storage::$type;");
259     }
260    
261    
262     # ====================================================
263     # PUBLIC METHODS
264     # ====================================================
265    
266 joko 1.3 sub existsChildNode {
267     my $self = shift;
268     my $nodename = shift;
269     #$nodename = 'TransactionRoutingTable';
270     $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );
271     $self->getChildNodes() unless $self->{meta}->{childnodes};
272     my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}}); # TODO: use "/i" only on win32-systems!
273     return $result;
274     }
275 cvsjoko 1.1
276 joko 1.3 sub connect_tmp {
277 cvsjoko 1.1
278     # my $self = shift;
279     # my $connectionString = shift;
280     # # todo: patch connectionString to $args
281     # _typeCheck($self->{args}{type});
282    
283     }
284    
285 joko 1.3
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 joko 1.4 # use Class::XYZ (Construct)
294 joko 1.3 # - build them via anonymous subs
295     # - introduce them via symbols
296    
297 joko 1.7 sub getCOREHANDLE {
298     my $self = shift;
299     $self->_abstract_function('getCOREHANDLE');
300     }
301    
302 cvsjoko 1.1 sub sendCommand {
303     my $self = shift;
304     $self->_abstract_function('sendCommand');
305 joko 1.7 }
306    
307     sub existsChildNode_tmp {
308     my $self = shift;
309     $self->_abstract_function('existsChildNode');
310 cvsjoko 1.1 }
311    
312     sub getChildNodes {
313     my $self = shift;
314     $self->_abstract_function('getChildNodes');
315     }
316    
317     sub configureCOREHANDLE {
318     my $self = shift;
319     $self->_abstract_function('configureCOREHANDLE');
320     }
321    
322 joko 1.3 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 joko 1.4 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 joko 1.3 return;
374     }
375    
376     1;

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