/[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.2 - (show 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 #################################
2 #
3 # $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 #
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 #$logger->debug( __PACKAGE__ . "->" . "new()" );
31
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 # - solution: locks! (by Hack or (maybe) via Perl "local"s)
60
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 #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 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