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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.19 - (show annotations)
Tue Feb 18 19:22:11 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.18: +9 -2 lines
+ fixed logging

1 ## ------------------------------------------------------------------------
2 ##
3 ## $Id: Storage.pm,v 1.18 2003/01/30 22:12:17 joko Exp $
4 ##
5 ## Copyright (c) 2002 Andreas Motl <andreas.motl@ilo.de>
6 ##
7 ## See COPYRIGHT section in pod text below for usage and distribution rights.
8 ##
9 ## ------------------------------------------------------------------------
10 ##
11 ## $Log: Storage.pm,v $
12 ## Revision 1.18 2003/01/30 22:12:17 joko
13 ## - removed/refactored old code: ->Data::Storage::Handler::Tangram|DBI
14 ##
15 ## Revision 1.17 2003/01/30 21:42:22 joko
16 ## + minor update: renamed method
17 ##
18 ## Revision 1.16 2003/01/20 16:52:13 joko
19 ## + now using 'DesignPattern::Object' to create a new 'Data::Storage::Handler::Xyz' on demand - before we did this in a hand-rolled fashion
20 ##
21 ## Revision 1.15 2003/01/19 03:12:59 joko
22 ## + modified header
23 ## - removed pod-documentation - now in 'Storage.pod'
24 ##
25 ## Revision 1.14 2002/12/19 16:27:59 joko
26 ## - moved 'sub dropDb' to Data::Storage::Handler::DBI
27 ##
28 ## Revision 1.13 2002/12/17 21:54:12 joko
29 ## + feature when using Tangram:
30 ## + what? each object created should delivered with a globally(!?) unique identifier (GUID) besides the native tangram object id (OID)
31 ## + patched Tangram::Storage (jonen)
32 ## + enhanced Data::Storage::Schema::Tangram (joko)
33 ## + enhanced Data::Storage::Handler::Tangram 'sub getObjectByGuid' (jonen)
34 ## + how?
35 ## + each concrete (non-abstract) class gets injected with an additional field/property called 'guid' - this is done (dynamically) on schema level
36 ## + this property ('guid') gets filled on object creation/insertion from 'sub Tangram::Storage::_insert' using Data::UUID from CPAN
37 ## + (as for now) this property can get accessed by calling 'getObjectByGuid' on the already known storage-handle used throughout the application
38 ##
39 ## Revision 1.12 2002/12/12 02:50:15 joko
40 ## + this now (unfortunately) needs DBI for some helper functions
41 ## + TODO: these have to be refactored to another scope! (soon!)
42 ##
43 ## Revision 1.11 2002/12/11 06:53:19 joko
44 ## + updated pod
45 ##
46 ## Revision 1.10 2002/12/07 03:37:23 joko
47 ## + updated pod
48 ##
49 ## Revision 1.9 2002/12/01 22:15:45 joko
50 ## - sub createDb: moved to handler
51 ##
52 ## Revision 1.8 2002/11/29 04:48:23 joko
53 ## + updated pod
54 ##
55 ## Revision 1.7 2002/11/17 06:07:18 joko
56 ## + creating the handler is easier than proposed first - for now :-)
57 ## + sub testAvailability
58 ##
59 ## Revision 1.6 2002/11/09 01:04:58 joko
60 ## + updated pod
61 ##
62 ## Revision 1.5 2002/10/29 19:24:18 joko
63 ## - reduced logging
64 ## + added some pod
65 ##
66 ## Revision 1.4 2002/10/27 18:35:07 joko
67 ## + added pod
68 ##
69 ## Revision 1.3 2002/10/25 11:40:37 joko
70 ## + enhanced robustness
71 ## + more logging for debug-levels
72 ## + sub dropDb
73 ##
74 ## Revision 1.2 2002/10/17 00:04:29 joko
75 ## + sub createDb
76 ## + sub isConnected
77 ## + bugfixes regarding "deep recursion" stuff
78 ##
79 ## Revision 1.1 2002/10/10 03:43:12 cvsjoko
80 ## + new
81 ## ------------------------------------------------------------------------
82
83
84 BEGIN {
85 $Data::Storage::VERSION = 0.03;
86 }
87
88 package Data::Storage;
89
90 use strict;
91 use warnings;
92
93 use Data::Dumper;
94 # FIXME: wipe out!
95 use DBI;
96
97 use Data::Storage::Locator;
98 use DesignPattern::Object;
99
100
101 # TODO: actually implement level (integrate with Log::Dispatch)
102 my $TRACELEVEL = 0;
103
104 # get logger instance
105 my $logger = Log::Dispatch::Config->instance;
106
107 sub new {
108 my $invocant = shift;
109 my $class = ref($invocant) || $invocant;
110 #my @args = normalizeArgs(@_);
111
112 my $arg_locator = shift;
113 my $arg_options = shift;
114 #my @args = @_;
115 #@args ||= ();
116
117 if (!$arg_locator) {
118 $logger->critical( __PACKAGE__ . "->new: No locator passed in!" );
119 return;
120 }
121
122 #print Dumper($arg_locator);
123
124 #my $self = { STORAGEHANDLE => undef, @_ };
125 my $self = { STORAGEHANDLE => undef, locator => $arg_locator, options => $arg_options };
126 #$logger->debug( __PACKAGE__ . "[$self->{locator}->{type}]" . "->new(@_)" );
127 $logger->debug( __PACKAGE__ . "[$arg_locator->{type}]" . "->new()" );
128 return bless $self, $class;
129 }
130
131 sub AUTOLOAD {
132
133 # since this is a core function acting as dispatcher to $self->{STORAGEHANDLE},
134 # some sophisticated handling and filtering is needed to avoid things like
135 # - Deep recursion on subroutine "Data::Storage::AUTOLOAD"
136 # - Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD"
137 # - Deep recursion on anonymous subroutine at [...]
138 # we also might filter log messages caused by logging to itself in "advanced logging of AUTOLOAD calls"
139
140 my $self = shift;
141 our $AUTOLOAD;
142
143 # ->DESTROY would - if not declared - trigger an AUTOLOAD also
144 return if $AUTOLOAD =~ m/::DESTROY$/;
145
146 my $method = $AUTOLOAD;
147 $method =~ s/^.*:://;
148
149 # advanced logging of AUTOLOAD calls ...
150 # ... nice but do it only when TRACING (TODO) is enabled
151 my $logstring = "";
152 $logstring .= __PACKAGE__ . "[$self->{locator}->{type}]" . "->" . $method;
153 #print "count: ", $#_, "\n";
154 #$logstring .= Dumper(@_) if ($#_ != -1);
155 my $tabcount = int( (80 - length($logstring)) / 10 );
156 $logstring .= "\t" x $tabcount . "(AUTOLOAD)";
157 # TODO: only ok if logstring doesn't contain
158 # e.g. "Data::Storage[Tangram]->insert(SystemEvent=HASH(0x5c0034c)) (AUTOLOAD)"
159 # but that would be _way_ too specific as long as we don't have an abstract handler for this ;)
160 if ($TRACELEVEL) {
161 $logger->debug( $logstring );
162 #print join('; ', @_);
163 }
164
165 # filtering AUTOLOAD calls and first-time-touch of the actual storage impl
166 if ($self->_filter_AUTOLOAD($method)) {
167 #print "=== FILTER!", "\n";
168 $self->_accessStorageHandle();
169 if ($self->{STORAGEHANDLE}) {
170 return $self->{STORAGEHANDLE}->$method(@_);
171 } else {
172 $logger->critical( __PACKAGE__ . "->AUTOLOAD: ERROR: " . $logstring );
173 return;
174 }
175 }
176
177 }
178
179 sub _filter_AUTOLOAD {
180 my $self = shift;
181 my $method = shift;
182 if ($self->{options}->{protected}) {
183 if ($method eq 'disconnect') {
184 return;
185 }
186 }
187 return 1;
188 }
189
190
191 sub _accessStorageHandle {
192 my $self = shift;
193 # TODO: to some tracelevel!
194 #print "=========== _accessStorage", "\n";
195 if ($TRACELEVEL) {
196 $logger->debug( __PACKAGE__ . "[$self->{locator}->{type}]" . "->_accessStorageHandle()" );
197 }
198 if (!$self->{STORAGEHANDLE}) {
199 return $self->_createStorageHandle();
200 }
201 }
202
203 sub _createStorageHandle1 {
204 my $self = shift;
205 my $type = $self->{locator}->{type};
206 $logger->debug( __PACKAGE__ . "[$type]" . "->_createStorageHandle()" );
207
208 my $pkg = "Data::Storage::Handler::" . $type . "";
209
210 # try to load perl module at runtime
211 my $evalstr = "use $pkg;";
212 eval($evalstr);
213 if ($@) {
214 $logger->error( __PACKAGE__ . "[$type]" . "->_createStorageHandle(): $@" );
215 return;
216 }
217
218 # build up some additional arguments to pass on
219 #my @args = %{$self->{locator}};
220 my @args = ();
221
222 # - create new storage handle object
223 # - propagate arguments to handler
224 # - pass locator by reference to be able to store status- or meta-information in it
225 $self->{STORAGEHANDLE} = $pkg->new( locator => $self->{locator}, @args );
226
227 }
228
229 sub _createStorageHandle {
230 my $self = shift;
231 my $type = $self->{locator}->{type};
232 $logger->debug( __PACKAGE__ . "[$type]" . "->_createStorageHandle()" );
233
234 #print Dumper($self);
235 #exit;
236
237 my $pkg = "Data::Storage::Handler::" . $type . "";
238
239 # try to load perl module at runtime
240 =pod
241 my $evalstr = "use $pkg;";
242 eval($evalstr);
243 if ($@) {
244 $logger->error( __PACKAGE__ . "[$type]" . "->_createStorageHandle(): $@" );
245 return;
246 }
247
248 # build up some additional arguments to pass on
249 #my @args = %{$self->{locator}};
250 my @args = ();
251
252 # - create new storage handle object
253 # - propagate arguments to handler
254 # - pass locator by reference to be able to store status- or meta-information in it
255 $self->{STORAGEHANDLE} = $pkg->new( locator => $self->{locator}, @args );
256 =cut
257
258 $self->{STORAGEHANDLE} = DesignPattern::Object->fromPackage( $pkg, locator => $self->{locator} );
259 return 1;
260
261 }
262
263 sub addLogDispatchHandler {
264
265 my $self = shift;
266 my $name = shift;
267 my $package = shift;
268 my $logger1 = shift;
269 my $objectCreator = shift;
270
271 #$logger->add( Log::Dispatch::Tangram->new( name => $name,
272 $logger->add( $package->new( name => $name,
273 #min_level => 'debug',
274 min_level => 'info',
275 storage => $self,
276 objectCreator => $objectCreator,
277 fields => {
278 message => 'usermsg',
279 timestamp => 'stamp',
280 level => 'level',
281 name => 'code',
282 },
283 filter_patterns => [ '->insert\(SystemEvent=' ],
284 #filter_patterns => [ 'SystemEvent' ],
285
286 #format => '[%d] [%p] %m%n',
287 ) );
288
289 }
290
291 sub removeLogDispatchHandler {
292 my $self = shift;
293 my $name = shift;
294 #my $logger = shift;
295 $logger->remove($name);
296 }
297
298
299 1;
300 __END__

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