/[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.18 - (show annotations)
Thu Jan 30 22:12:17 2003 UTC (21 years, 5 months ago) by joko
Branch: MAIN
Changes since 1.17: +4 -49 lines
- removed/refactored old code: ->Data::Storage::Handler::Tangram|DBI

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

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