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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (hide annotations)
Thu Jan 30 21:42:22 2003 UTC (21 years, 5 months ago) by joko
Branch: MAIN
Changes since 1.16: +9 -4 lines
+ minor update: renamed method

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

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