/[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.6 - (show annotations)
Tue Dec 3 15:52:24 2002 UTC (21 years, 7 months ago) by joko
Branch: MAIN
Changes since 1.5: +7 -1 lines
+ fix/feature: if dispatching to deep core method fails (is not declared), try method at Data::Storage - level

1 #################################
2 #
3 # $Id: Abstract.pm,v 1.5 2002/12/01 22:19:33 joko Exp $
4 #
5 # $Log: Abstract.pm,v $
6 # Revision 1.5 2002/12/01 22:19:33 joko
7 # + just disconnect if COREHANDLE exists
8 #
9 # Revision 1.4 2002/12/01 04:45:38 joko
10 # + sub eraseAll
11 # + sub createDb
12 #
13 # Revision 1.3 2002/11/29 04:58:20 joko
14 # + Storage::Result now uses the same dispatching mechanism like Storage::Handler
15 #
16 # Revision 1.2 2002/10/17 00:08:07 joko
17 # + bugfixes regarding "deep recursion" stuff
18 #
19 # Revision 1.1 2002/10/10 03:44:07 cvsjoko
20 # + new
21 #
22 #
23 #################################
24
25 package Data::Storage::Handler::Abstract;
26
27 use strict;
28 use warnings;
29
30 use Data::Dumper;
31
32 # get logger instance
33 my $logger = Log::Dispatch::Config->instance;
34
35 #our $lock_info;
36
37 sub new {
38 my $invocant = shift;
39 my $class = ref($invocant) || $invocant;
40
41 # logging info about the actual handler called
42 $logger->debug( "$invocant->new( @_ )" );
43 #$logger->debug( __PACKAGE__ . "->" . "new()" );
44
45 # arguments become properties
46 my $self = { @_ };
47 # create object from blessed hash-reference
48 bless $self, $class;
49
50 # handle meta data
51 #my $metainfo = $self->getMetaInfo($class);
52 my $metainfo = $self->getMetaInfo();
53 if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
54 # type?
55 $invocant =~ s/Data::Storage::Handler:://;
56 $metainfo->{type} = $invocant;
57
58 # direct accessible (non-protected) properties ( was: my $self = { }; )
59 $self->{metainfo} = $metainfo;
60
61 return $self;
62 }
63
64
65 sub AUTOLOAD {
66
67 # recursion problem to be avoided here!!!
68
69 # - problem: we get recursion-hangs!!! => perl stops with ...
70 # "Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD" at [...]/libs/Data/Storage.pm line 38."
71
72 # - when: if we log to ourselves as a storage-implementation (e.g. via Log::Dispatch::Tangram)
73 # - why: debug-messages are on a very low level including every data-operation to "Data::Storage(::Handler::X)",
74 # so e.g. a "$storage->insert" would trigger another "$storage->insert" itself
75 # which leads to a infinite recursion loop (deep recursion)
76 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
77
78 my $self = shift;
79
80 our $AUTOLOAD;
81 #return if $AUTOLOAD =~ m/::DESTROY$/;
82
83 # find out methodname
84 my $methodname = $AUTOLOAD;
85 $methodname =~ s/^.*:://;
86
87 # handle locking (hack)
88 if ($self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
89 $self->{lock_info}->{log_lock} = 1;
90 } else {
91 $self->{lock_info}->{log_lock} = 0;
92 }
93 $self->{lock_info}->{last_method} = $methodname;
94
95 # test for COREHANDLE
96 if (!$self->{COREHANDLE}) {
97 #print "no COREHANDLE", "\n";
98 if (!$self->{lock_info}->{log_lock}) {
99 $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );
100 }
101 return;
102 }
103
104 # try to dispatch method-call to Storage::Handler::*
105 #if ($self->can($methodname)) {
106 #$logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
107 #my $res = $self->$methodname(@_);
108 #if ($res) { return $res; }
109 #}
110
111 # try to dispatch method-call to COREHANDLE
112 if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {
113 #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
114 #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
115 if (!$self->{lock_info}->{log_lock}) {
116 #print "method: $methodname", "\n";
117 $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
118 } else {
119 # AUTOLOAD - sub is locked to prevent deep recursions if (e.g.) db-inserts cause log-actions to same db itself
120 }
121 #$lock_AUTOLOAD = 0;
122 #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
123
124 # method calls doing it until here will get dispatched to the proper handler
125 return $self->{COREHANDLE}->$methodname(@_);
126
127 } elsif ($self->can($methodname)) {
128 return $self->$methodname(@_);
129 }
130
131 }
132
133 sub DESTROY {
134 my $self = shift;
135 if ($self->{COREHANDLE}) {
136 $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
137
138 my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
139
140 # call "disconnect" or alike on COREHANDLE
141 # was: $self->{COREHANDLE}->disconnect();
142 $disconnectMethod && $self->{COREHANDLE} && ( $self->{COREHANDLE}->$disconnectMethod() );
143
144 undef $self->{COREHANDLE};
145 }
146 }
147
148
149 sub _abstract_function {
150 my $self = shift;
151 my $fName = shift;
152 my $class = ref($self);
153 $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\"");
154 #exit;
155 }
156
157 sub _typeCheck {
158 my $type = shift;
159 print "type: $type";
160 eval("use Data::Storage::$type;");
161 }
162
163
164 # ====================================================
165 # PUBLIC METHODS
166 # ====================================================
167
168 sub existsChildNode {
169 my $self = shift;
170 my $nodename = shift;
171 #$nodename = 'TransactionRoutingTable';
172 $logger->debug( __PACKAGE__ . "->getChildNode( nodename $nodename )" );
173 $self->getChildNodes() unless $self->{meta}->{childnodes};
174 my $result = grep(m/$nodename/i, @{$self->{meta}->{childnodes}}); # TODO: use "/i" only on win32-systems!
175 return $result;
176 }
177
178 sub connect_tmp {
179
180 # my $self = shift;
181 # my $connectionString = shift;
182 # # todo: patch connectionString to $args
183 # _typeCheck($self->{args}{type});
184
185 }
186
187
188 # ====================================================
189 # CONCRETE METHOD DUMMIES (croaking via "$logger" by calling "_abstract_function")
190 # ====================================================
191
192 # TODO:
193 # - abstract "abstract methods" to list/hash to be used in AUTOLOAD
194 # e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
195 # use Class::XYZ (Construct)
196 # - build them via anonymous subs
197 # - introduce them via symbols
198
199 sub sendCommand {
200 my $self = shift;
201 $self->_abstract_function('sendCommand');
202 }
203
204 sub getChildNodes {
205 my $self = shift;
206 $self->_abstract_function('getChildNodes');
207 }
208
209 sub configureCOREHANDLE {
210 my $self = shift;
211 $self->_abstract_function('configureCOREHANDLE');
212 }
213
214 sub getMetaInfo {
215 my $self = shift;
216 $self->_abstract_function('getMetaInfo');
217 return;
218 }
219
220 sub getListUnfiltered {
221 my $self = shift;
222 $self->_abstract_function('getListUnfiltered');
223 return;
224 }
225
226 sub getListFiltered {
227 my $self = shift;
228 $self->_abstract_function('getListFiltered');
229 return;
230 }
231
232 sub sendQuery {
233 my $self = shift;
234 $self->_abstract_function('sendQuery');
235 return;
236 }
237
238 sub connect {
239 my $self = shift;
240 $self->_abstract_function('connect');
241 return;
242 }
243
244 sub testIntegrity {
245 my $self = shift;
246 $self->_abstract_function('testIntegrity');
247 return;
248 }
249
250 sub quoteSql {
251 my $self = shift;
252 $self->_abstract_function('quoteSql');
253 return;
254 }
255
256 sub eraseAll {
257 my $self = shift;
258 $self->_abstract_function('eraseAll');
259 return;
260 }
261
262 sub createDb {
263 my $self = shift;
264 $self->_abstract_function('createDb');
265 return;
266 }
267
268 1;

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