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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Thu Oct 17 00:08:07 2002 UTC (21 years, 8 months ago) by joko
Branch: MAIN
Changes since 1.1: +11 -5 lines
+ bugfixes regarding "deep recursion" stuff

1 cvsjoko 1.1 #################################
2     #
3 joko 1.2 # $Id: Abstract.pm,v 1.1 2002/10/10 03:44:07 cvsjoko Exp $
4     #
5     # $Log: Abstract.pm,v $
6     # Revision 1.1 2002/10/10 03:44:07 cvsjoko
7     # + new
8 cvsjoko 1.1 #
9     #
10     #################################
11    
12     package Data::Storage::Handler::Abstract;
13    
14     use strict;
15     use warnings;
16    
17     use Data::Dumper;
18    
19     # get logger instance
20     my $logger = Log::Dispatch::Config->instance;
21    
22     #our $lock_info;
23    
24     sub new {
25     my $invocant = shift;
26     my $class = ref($invocant) || $invocant;
27    
28     # logging info about the actual handler called
29     $logger->debug( "$invocant->new( @_ )" );
30 joko 1.2 #$logger->debug( __PACKAGE__ . "->" . "new()" );
31 cvsjoko 1.1
32     # handle meta data
33     my $metainfo = _getMetaInfo($class);
34     if (!$metainfo->{disconnectMethod}) { $metainfo->{disconnectMethod} = 'disconnect'; }
35     # type?
36     $invocant =~ s/Data::Storage::Handler:://;
37     $metainfo->{type} = $invocant;
38    
39     # create object from blessed hash-reference
40     # direct accessible (non-protected) properties ( was: my $self = { }; )
41     my $self = { metainfo => $metainfo, @_ };
42     bless $self, $class;
43    
44     return $self;
45     }
46    
47    
48     sub AUTOLOAD {
49    
50     # recursion problem to be avoided here!!!
51    
52     # - problem: we get recursion-hangs!!! => perl stops with ...
53     # "Deep recursion on subroutine "Data::Storage::Handler::Abstract::AUTOLOAD" at [...]/libs/Data/Storage.pm line 38."
54    
55     # - when: if we log to ourselves as a storage-implementation (e.g. via Log::Dispatch::Tangram)
56     # - why: debug-messages are on a very low level including every data-operation to "Data::Storage(::Handler::X)",
57     # so e.g. a "$storage->insert" would trigger another "$storage->insert" itself
58     # which leads to a infinite recursion loop (deep recursion)
59 joko 1.2 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
60 cvsjoko 1.1
61     my $self = shift;
62    
63     our $AUTOLOAD;
64     #return if $AUTOLOAD =~ m/::DESTROY$/;
65    
66     # find out methodname
67     my $methodname = $AUTOLOAD;
68     $methodname =~ s/^.*:://;
69    
70     # handle locking (hack)
71     if ($self->{lock_info}->{last_method} && $methodname eq $self->{lock_info}->{last_method}) {
72     $self->{lock_info}->{log_lock} = 1;
73     } else {
74     $self->{lock_info}->{log_lock} = 0;
75     }
76     $self->{lock_info}->{last_method} = $methodname;
77    
78     # test for COREHANDLE
79     if (!$self->{COREHANDLE}) {
80 joko 1.2 #print "no COREHANDLE", "\n";
81     if (!$self->{lock_info}->{log_lock}) {
82     $logger->error( __PACKAGE__ . "[$self->{metainfo}->{type}]" . ": " . "COREHANDLE is undefined while trying to execute method \"$methodname\"" );
83     }
84 cvsjoko 1.1 return;
85     }
86    
87     # try to dispatch method-call to Storage::Handler::*
88     #if ($self->can($methodname)) {
89     #$logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
90     #my $res = $self->$methodname(@_);
91     #if ($res) { return $res; }
92     #}
93    
94     # try to dispatch method-call to COREHANDLE
95     if ($self->{COREHANDLE}->can($methodname) || $self->{COREHANDLE}->can("AUTOLOAD")) {
96     #$logger->debug( __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
97     #$lock_AUTOLOAD = 1 if ($methodname eq 'insert');
98     if (!$self->{lock_info}->{log_lock}) {
99     #print "method: $methodname", "\n";
100     $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->" . $methodname . "(@_)" );
101     } else {
102     # AUTOLOAD - sub is locked to prevent deep recursions if (e.g.) db-inserts cause log-actions to same db itself
103     }
104     #$lock_AUTOLOAD = 0;
105     #$logger->log( level => 'debug', message => __PACKAGE__ . "->" . $methodname . " (AUTOLOAD)" );
106     return $self->{COREHANDLE}->$methodname(@_);
107     }
108    
109     }
110    
111     sub DESTROY {
112     my $self = shift;
113     if ($self->{COREHANDLE}) {
114     $logger->debug( __PACKAGE__ . "[$self->{metainfo}->{type}]" . "->DESTROY" );
115    
116     my $disconnectMethod = $self->{metainfo}->{disconnectMethod};
117    
118     # call "disconnect" or alike on COREHANDLE
119     # was: $self->{COREHANDLE}->disconnect();
120     $disconnectMethod && ( $self->{COREHANDLE}->$disconnectMethod() );
121    
122     undef $self->{COREHANDLE};
123     }
124     }
125    
126    
127     sub _abstract_function {
128     my $self = shift;
129     my $fName = shift;
130     my $class = ref($self);
131     $logger->error( __PACKAGE__ . ": function \"$fName\" is an abstract method, please implement it in \"$class\"");
132     #exit;
133     }
134    
135     sub _typeCheck {
136     my $type = shift;
137     print "type: $type";
138     eval("use Data::Storage::$type;");
139     }
140    
141     sub _getMetaInfo {
142     my $packagename = shift;
143     #return $self->$metainfo;
144    
145     my $ns = '$' . $packagename . "::metainfo";
146     $logger->debug( __PACKAGE__ . "->" . "_getMetaInfo()" . " " . "[$ns]" );
147     return eval($ns);
148     }
149    
150    
151     # ====================================================
152     # PUBLIC METHODS
153     # ====================================================
154    
155     # TODO: abstract "abstract methods" to list/hash to be used in AUTOLOAD
156     # e.g.: my @ABSTRACT_METHODS = (qw( connect sendCommand getChildNodes ));
157    
158     sub connect {
159    
160     my $self = shift;
161     $self->_abstract_function('connect');
162     return;
163    
164     $logger->debug( "\"connect\" has to be implemented by handler!" );
165     return;
166    
167     # my $self = shift;
168     # my $connectionString = shift;
169     # # todo: patch connectionString to $args
170     # _typeCheck($self->{args}{type});
171    
172     }
173    
174     sub sendCommand {
175     my $self = shift;
176     $self->_abstract_function('sendCommand');
177     }
178    
179     sub getChildNodes {
180     my $self = shift;
181     $self->_abstract_function('getChildNodes');
182     }
183    
184     sub configureCOREHANDLE {
185     my $self = shift;
186     $self->_abstract_function('configureCOREHANDLE');
187     }
188    
189     1;

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