/[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.8 - (show annotations)
Fri Dec 13 21:48:35 2002 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.7: +7 -13 lines
+ sub _abstract_function

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

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