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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show 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 ## --------------------------------------------------------------------------------
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
26 package Data::Storage::Handler::Abstract;
27
28 use strict;
29 use warnings;
30
31 use Data::Dumper;
32 use Tie::SecureHash;
33 #use Data::Storage::Handler;
34
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 #$logger->debug( __PACKAGE__ . "->" . "new()" );
47
48 # 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 my $self = { @_ };
52 # create object from blessed hash-reference
53 bless $self, $class;
54 =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
100 # handle meta data
101 #my $metainfo = $self->getMetaInfo($class);
102 my $metainfo = $self->getMetaInfo();
103 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 $self->{metainfo} = $metainfo;
110
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 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
127
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
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
150 # handle locking (hack)
151 if ($self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
152 $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 #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 # test for COREHANDLE
167 #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 }
177 return;
178 }
179 #=cut
180
181 #print "$methodname - 3", "\n";
182
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 #print "$methodname - 4", "\n";
191
192 # try to dispatch method-call to COREHANDLE
193 # 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 #$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
216 #print "calling: $methodname", "\n";
217
218 # method calls doing it until here will get dispatched to the proper handler
219 return $core->$methodname(@_);
220
221 } elsif ($self->can($methodname)) {
222 return $self->$methodname(@_);
223 }
224
225 }
226
227 sub DESTROY {
228 my $self = shift;
229 #if ($self->{COREHANDLE}) {
230 if ($self->exists('_COREHANDLE')) {
231 $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 $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
238
239 undef $self->{_COREHANDLE};
240 }
241 }
242
243
244 sub _abstract_function {
245 my $self = shift;
246 my $fName = shift;
247 my $class = ref($self);
248 # 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 #exit;
253 }
254
255 sub _typeCheck2 {
256 my $type = shift;
257 print "type: $type";
258 eval("use Data::Storage::$type;");
259 }
260
261
262 # ====================================================
263 # PUBLIC METHODS
264 # ====================================================
265
266 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
276 sub connect_tmp {
277
278 # my $self = shift;
279 # my $connectionString = shift;
280 # # todo: patch connectionString to $args
281 # _typeCheck($self->{args}{type});
282
283 }
284
285
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 # use Class::XYZ (Construct)
294 # - build them via anonymous subs
295 # - introduce them via symbols
296
297 sub getCOREHANDLE {
298 my $self = shift;
299 $self->_abstract_function('getCOREHANDLE');
300 }
301
302 sub sendCommand {
303 my $self = shift;
304 $self->_abstract_function('sendCommand');
305 }
306
307 sub existsChildNode_tmp {
308 my $self = shift;
309 $self->_abstract_function('existsChildNode');
310 }
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 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 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 return;
374 }
375
376 1;

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