/[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.9 - (show 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 ## --------------------------------------------------------------------------------
2 ## $Id: Abstract.pm,v 1.8 2002/12/13 21:48:35 joko Exp $
3 ## --------------------------------------------------------------------------------
4 ## $Log: Abstract.pm,v $
5 ## Revision 1.8 2002/12/13 21:48:35 joko
6 ## + sub _abstract_function
7 ##
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 ## 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
33 package Data::Storage::Handler::Abstract;
34
35 use strict;
36 use warnings;
37
38 use base qw( DesignPattern::Object );
39
40 use Data::Dumper;
41 use Tie::SecureHash;
42 #use Data::Storage::Handler;
43
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 #$logger->debug( __PACKAGE__ . "->" . "new()" );
56
57 # 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 my $self = { @_ };
61 # create object from blessed hash-reference
62 bless $self, $class;
63 =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
109 # handle meta data
110 #my $metainfo = $self->getMetaInfo($class);
111 my $metainfo = $self->getMetaInfo();
112 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 $self->{metainfo} = $metainfo;
119
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 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
136
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
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
159 # handle locking (hack)
160 if ($self->exists('lock_info') && $self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
161 $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 #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 # test for COREHANDLE
176 #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 }
186 return;
187 }
188 #=cut
189
190 #print "$methodname - 3", "\n";
191
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 #print "$methodname - 4", "\n";
200
201 # try to dispatch method-call to COREHANDLE
202 # 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 #$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
225 #print "calling: $methodname", "\n";
226
227 # method calls doing it until here will get dispatched to the proper handler
228 return $core->$methodname(@_);
229
230 } elsif ($self->can($methodname)) {
231 return $self->$methodname(@_);
232 }
233
234 }
235
236 sub DESTROY {
237 my $self = shift;
238 #if ($self->{COREHANDLE}) {
239 if ($self->exists('_COREHANDLE')) {
240 $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 $disconnectMethod && $self->{_COREHANDLE} && ( $self->{_COREHANDLE}->$disconnectMethod() );
247
248 undef $self->{_COREHANDLE};
249 }
250 }
251
252 sub _typeCheck2 {
253 my $type = shift;
254 print "type: $type";
255 eval("use Data::Storage::$type;");
256 }
257
258
259 # ====================================================
260 # PUBLIC METHODS
261 # ====================================================
262
263 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
273 sub connect_tmp {
274
275 # my $self = shift;
276 # my $connectionString = shift;
277 # # todo: patch connectionString to $args
278 # _typeCheck($self->{args}{type});
279
280 }
281
282
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 # use Class::XYZ (Construct)
291 # - build them via anonymous subs
292 # - introduce them via symbols
293
294 sub getCOREHANDLE {
295 my $self = shift;
296 $self->_abstract_function('getCOREHANDLE');
297 }
298
299 sub sendCommand {
300 my $self = shift;
301 $self->_abstract_function('sendCommand');
302 }
303
304 sub existsChildNode_tmp {
305 my $self = shift;
306 $self->_abstract_function('existsChildNode');
307 }
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 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 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 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 return;
383 }
384
385 1;

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