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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations)
Tue Feb 18 19:19:47 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
Changes since 1.7: +23 -7 lines
+ modified locator handling

1 ################################################
2 #
3 # $Id: Container.pm,v 1.7 2003/01/30 22:21:52 joko Exp $
4 #
5 # $Log: Container.pm,v $
6 # Revision 1.7 2003/01/30 22:21:52 joko
7 # + changed 'connect'-behaviour back to old state
8 # + renamed log-output (now using 'initializing' instead of 'booting' - corresponding to 'initStorage')
9 #
10 # Revision 1.6 2003/01/30 21:44:00 joko
11 # + temporary fix: (FIXME) now connecting to storage on storagehandle-instantiation
12 #
13 # Revision 1.5 2003/01/19 02:39:57 joko
14 # + moved 'deep_copy' from module 'libp' to module 'Data::Transform::Deep'
15 # + preserved order for hashes '$self->{config}' and '$self->{locator}' by using Tie::IxHash
16 #
17 # Revision 1.4 2002/12/04 07:38:07 jonen
18 # + deep copy
19 #
20 # Revision 1.3 2002/12/01 22:18:28 joko
21 # - no interactive implicit deploy
22 # + only test integrity if storage available
23 #
24 # Revision 1.2 2002/12/01 07:08:35 joko
25 # + needs to "use Data::Storage;"
26 #
27 # Revision 1.1 2002/11/29 04:54:54 joko
28 # + initial check-in
29 #
30 # Revision 1.1 2002/11/17 06:20:41 joko
31 # + initial check in
32 #
33 #
34 ################################################
35
36
37 package Data::Storage::Container;
38
39 use strict;
40 use warnings;
41
42 # get logger instance
43 my $logger = Log::Dispatch::Config->instance;
44
45
46 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main
47 use Tie::IxHash;
48 use Data::Dumper;
49
50 use Data::Storage;
51 use Data::Storage::Locator;
52 use Data::Transform::Deep qw( deep_copy );
53 use Data::Compare::Struct qw( isEmpty );
54
55 sub new {
56 my $invocant = shift;
57 my $class = ref($invocant) || $invocant;
58
59 # get constructor arguments
60 my @args = ();
61 @_ && (@args = @_);
62 $logger->debug( __PACKAGE__ . "->new( @args )" );
63
64 my $self = { @_ };
65 bless $self, $class;
66
67 # preserve order of configuration variables
68 #$self->{config} = {};
69 tie %{$self->{config}}, 'Tie::IxHash';
70 tie %{$self->{locator}}, 'Tie::IxHash';
71
72 return $self;
73 }
74
75 sub addConfig {
76 my $self = shift;
77 my $name = shift;
78 my $config = shift;
79 $self->{config}->{$name} = $config;
80 }
81
82 sub addConfigByDsn {
83 my $self = shift;
84 my $name = shift;
85 my $dsn = shift;
86
87 # HACK: assume DBI as default type for now
88 # TODO: guess type from dsn
89 my $type = "DBI";
90
91 $self->addConfig($name, { type => $type, dsn => $dsn });
92 }
93
94 sub addStorage {
95 my $self = shift;
96 my $name = shift;
97 my $storage = shift;
98 $self->{storage}->{$name} = $storage;
99 }
100
101 sub initLocator {
102 my $self = shift;
103 my $name = shift;
104 my $db_config = $self->{config}->{$name};
105 $db_config ||= {};
106
107 $logger->debug( __PACKAGE__ . "->initLocator( name='$name' )" );
108
109 my $cfg_locator = {};
110
111 # set default settings, if any
112 my $default = deep_copy($self->{config}->{_default});
113 foreach (keys %$default) {
114 $cfg_locator->{$_} = $default->{$_};
115 }
116
117 # merge in specific settings
118 my $specific = deep_copy($db_config);
119 foreach (keys %$specific) {
120 $cfg_locator->{$_} = $specific->{$_};
121 }
122
123 # HACK: transfer dsn from main to dbi settings
124 $cfg_locator->{dbi}->{dsn} = $cfg_locator->{dsn} if $cfg_locator->{dsn};
125
126 # HACK: set classnames empty if none given from config
127 $cfg_locator->{classnames} = [] if !$cfg_locator->{classnames};
128
129 # HACK: set errorhandler if dbi settings are present
130 $cfg_locator->{dbi}->{HandleError} = \&_dbErrorHandler if $cfg_locator->{dbi};
131
132 # trace
133 #print "locator:", "\n";
134 #print Dumper($cfg_locator);
135
136 # check locator metadata
137 if (isEmpty($cfg_locator)) {
138 $logger->warning( __PACKAGE__ . "->initLocator( name='$name' ): Metadata was empty. Please check configuration." );
139 return;
140 }
141
142 # name it
143 $cfg_locator->{name} = $name;
144
145 # create new locator object
146 $self->{locator}->{$name} = Data::Storage::Locator->new( $cfg_locator );
147
148 }
149
150 sub initLocators {
151 my $self = shift;
152 foreach (keys %{$self->{config}}) {
153 #print $_, "\n";
154 $self->initLocator($_, $self->{config}->{$_}) if !/^_/;
155 }
156 #print "locs: ", Dumper($self->{locator});
157 }
158
159 sub getLocator {
160 my $self = shift;
161 my $name = shift;
162 return $self->{locator}->{$name};
163 }
164
165 sub initStorage {
166 my $self = shift;
167 my $name = shift;
168
169 my $locator = $self->getLocator($name);
170 $logger->info( __PACKAGE__ . " is initializing storage declared by locator \"$name\"" );
171
172 my $storage = Data::Storage->new($locator);
173
174 # TODO: do below (after 'testAvailability' and 'testIntegrity') again!!!
175 #$storage->connect();
176
177 my $log_prefix = __PACKAGE__ . "->initStorage: ";
178 $log_prefix .= "dsn=\"$self->{locator}->{$name}->{dsn}\"" if $self->{locator}->{$name}->{dsn};
179
180 # should we test availability of the storage before using it?
181 if ($locator->{test_availability}) {
182 $locator->{status}->{availability} = $storage->testAvailability();
183 if ( !$storage->testAvailability() ) {
184 $logger->error( "$log_prefix: testAvailability failed" );
185 }
186 }
187
188 # should we test integrity of the storage before using it?
189 if ($locator->{status}->{availability} && $locator->{test_integrity}) {
190 #return unless $storage->testIntegrity();
191 $locator->{status}->{integrity} = $storage->testIntegrity();
192 # actions if integrity fails
193 if (!$locator->{status}->{integrity}) {
194 $logger->error( "$log_prefix: testIntegrity failed" );
195 }
196 }
197
198 # try to connect...
199 # TODO:
200 # don't connect right here, do an implicit connect on (later) usage
201 # maybe set ->{meta}->{connectmethod} = "connect" here
202 #return unless $storage->connect();
203 $storage->connect() if $locator->{status}->{integrity};
204
205 # should we check emptyness?
206 if ($locator->{status}->{availability} && $locator->{test_emptyness}) {
207 #print "test empty", "\n";
208 if ( !@{$storage->getChildNodes()} ) {
209 $locator->{status}->{empty} = 1;
210 $logger->warning( "$log_prefix: Storage is empty.");
211 #return;
212 }
213 }
214
215 # expand logging?
216 if ( $locator->{status}->{integrity} && $locator->{logger} ) {
217 # expand logging (to Tangram-Database)
218 # TODO:
219 # - move configuration data from this code to db_config somehow
220 # - do complete handling of this stuff in Data::Storage::* also
221 # - just leave a simple on/off-trigger here and/or
222 # - make it optionally configurable via e.g. get/set-methods
223 # to satisfy "manual"-mode instead of "config"-mode
224 # - (re-)add hierarchical logging (each event may have a parent)
225 no strict;
226 my $creator = sub { return new SystemEvent; };
227 use strict;
228 $storage->addLogDispatchHandler("Tangram11", "Log::Dispatch::Tangram", $logger, $creator);
229 #$storage_left->addLogDispatchHandler("Tangram11", "Log::Dispatch::Tangram", $logger);
230 }
231
232 #$self->{storage}->{$name} = $storage;
233 #print "add storage: $name", "\n";
234 $self->addStorage($name, $storage);
235
236 return 1;
237
238 }
239
240 sub initStorages {
241 my $self = shift;
242 foreach (keys %{$self->{locator}}) {
243 #print $_, "\n";
244 $self->initStorage($_);
245 }
246 }
247
248 sub _dbErrorHandler {
249 my $message_db = shift;
250 # get logger instance
251 #my $logger = Log::Dispatch::Config->instance;
252 #$logger->log(level => 'error', message => "Tangram DBI-Error: $message");
253 my $message_log = "DBI-Error: $message_db";
254 print STDERR $message_log, "\n";
255 #$logger->error( $message_log );
256 #$logger->log_to( name => 'file', level => 'error', message => $message_log);
257 $logger->log_to( name => 'file', level => 'warning', message => $message_log);
258 return 1;
259 }
260
261 1;

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