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

Contents of /nfo/perl/libs/Data/Storage/Handler/Tangram.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Sun Dec 1 04:46:19 2002 UTC (21 years, 7 months ago) by joko
Branch: MAIN
Changes since 1.6: +19 -1 lines
+ sub eraseAll

1 ############################################
2 #
3 # $Id: Tangram.pm,v 1.6 2002/11/29 05:02:30 joko Exp $
4 #
5 # $Log: Tangram.pm,v $
6 # Revision 1.6 2002/11/29 05:02:30 joko
7 # - sub getNewPerlObjectByPkgName (moved to libp.pm)
8 # + sub getMetaInfo
9 # - sub existsChildNode (moved to Abstract.pm)
10 # + sub getListUnfiltered
11 # + sub getListFiltered
12 # + sub createCursor
13 # + sub createSet
14 # + sub sendQuery
15 #
16 # Revision 1.5 2002/11/17 06:35:18 joko
17 # + locator metadata can now be reached via ->{locator}
18 # - getChildNodes is now wrapped via COREHANDLE
19 #
20 # Revision 1.4 2002/10/25 11:44:44 joko
21 # + sub _initSchema
22 # + sub existsChildNode
23 # + sub testIntegrity
24 # + sub rebuildDbAndSchema
25 #
26 # Revision 1.3 2002/10/17 03:56:55 joko
27 # + bugfix: trapped eval error
28 #
29 # Revision 1.2 2002/10/17 00:10:05 joko
30 # + removed dependency from tsobj.pm, schema is now independent
31 # + sub getNewPerlObjectByPkgName
32 # + sub deploySchema
33 # + sub retreatSchema
34 #
35 # Revision 1.1 2002/10/10 03:44:07 cvsjoko
36 # + new
37 #
38 ############################################
39
40
41 package Data::Storage::Handler::Tangram;
42
43 use strict;
44 use warnings;
45
46 use base ("Data::Storage::Handler::Abstract");
47
48 use Tangram;
49 use Data::Dumper;
50 use libp qw( getNewPerlObjectByPkgName );
51 use Data::Storage::Result::Tangram;
52 use Data::Compare::Struct qw( isEmpty );
53
54 # get logger instance
55 my $logger = Log::Dispatch::Config->instance;
56
57
58 sub getMetaInfo {
59 my $self = shift;
60 $logger->debug( __PACKAGE__ . "->getMetaInfo()" );
61 return {
62 'disconnectMethod' => 'disconnect',
63 };
64 }
65
66 sub _initSchema {
67 my $self = shift;
68 $logger->debug( __PACKAGE__ . "->_initSchema()" );
69 #if (!$self->{schema_tangram}) {
70 my $obj = getNewPerlObjectByPkgName($self->{locator}->{schema}, { EXPORT_OBJECTS => $self->{locator}->{classnames}, want_transactions => $self->{locator}->{want_transactions} } );
71 $self->{schema_tangram} = $obj->getSchema();
72 #}
73 if (!$self->{schema_tangram}) {
74 $logger->error( __PACKAGE__ . "->_initSchema: No Schema available for $self->{schema}" );
75 return 0;
76 }
77 return 1;
78 }
79
80 sub connect {
81
82 my $self = shift;
83
84 my $dsn = shift;
85 $dsn ||= $self->{locator}->{dbi}->{dsn};
86
87 $logger->debug( __PACKAGE__ . "->connect( dsn $dsn )" );
88
89 #my $storage = Tangram::Relational->connect( $schema, $dsn );
90 #my $storage = Tangram::mysql->connect( $schema, $dsn );
91 #$storage = Tangram::Relational->connect( Project->schema, $dsn );
92
93 # if (!testDsn($dsn)) {
94 # croak("Database at \"$dsn\" is not available");
95 # return;
96 # }
97
98 return unless $self->_initSchema();
99
100 # create the main tangram storage object
101 #$self->{COREHANDLE} = Tangram::Relational->connect( $schema, $dsn );
102 $self->{COREHANDLE} = Tangram::Relational->connect( $self->{schema_tangram}, $dsn );
103
104 # some attempts for configuring the wrapped underlying dbi.....
105 #$self->{STORAGEHANDLE_UNDERLYING} = $self->getUnderlyingStorage();
106 #$self->{STORAGEHANDLE_UNDERLYING}->_configureCOREHANDLE();
107 #$self->_configureUnderlyingStorage;
108
109 # ..... encapsulation wins!
110 $self->configureCOREHANDLE();
111
112 $self->{locator}->{status}->{connected} = 1;
113
114 return 1;
115
116 }
117
118 sub getChildNodes {
119
120 my $self = shift;
121 my @nodes;
122
123 $logger->debug( __PACKAGE__ . "->getChildNodes()" );
124
125 # create new DBI - Data::Storage - object from already connected DBI::db - handle inside the current COREHANDLE
126 #my $loc = new Data::Storage::Locator( type => "DBI", dbi => { db => $self->{COREHANDLE}->{db} });
127 #my $loc = new Data::Storage::Locator( type => "DBI", COREHANDLE => $self->{COREHANDLE}->{db} );
128
129 # todo: should we retrieve information from the schema here
130 # rather than poorly getting table names from underlying dbi?
131 my $storage = $self->_getSubLayerHandle();
132 @nodes = @{$storage->getChildNodes()};
133 #$storage->_configureCOREHANDLE();
134 #print "getchildnodes\n";
135 #print Dumper($self);
136 #if (my $result = $self->sendCommand( 'SHOW TABLES;' ) ) {
137
138 $storage->disconnect();
139
140 $self->{meta}->{childnodes} = \@nodes;
141
142 return \@nodes;
143
144 }
145
146
147 sub testIntegrity {
148
149 my $self = shift;
150
151 $logger->debug( __PACKAGE__ . "->testIntegrity()" );
152
153 # 1st test: are there tables?
154 if (!$self->getChildNodes()) {
155 $logger->warning( __PACKAGE__ . "->testIntegrity no childnodes exist" );
156 return;
157 }
158
159 # 2nd test: is there a table named "Tangram"?
160 if (!$self->existsChildNode("Tangram")) {
161 $logger->warning( __PACKAGE__ . "->testIntegrity childnode \"Tangram\" doesn't exist" );
162 return;
163 }
164
165 $self->{locator}->{status}->{integrity} = 1;
166 return 1;
167
168 }
169
170
171 sub _getSubLayerHandle {
172
173 my $self = shift;
174
175 $logger->debug( __PACKAGE__ . "->_getSubLayerHandle()" );
176
177 #print Dumper($self);
178
179 # hack, make more generic!
180 if (!$self->{dataStorageLayer}) {
181 $logger->debug( __PACKAGE__ . "->_getSubLayerHandle() creating new dataStorageLayer" );
182 #my $loc = Data::Storage::Locator->new( type => "DBI", dbi => $self->{dbi}, COREHANDLE => $self->{COREHANDLE}->{db} );
183 my $loc = Data::Storage::Locator->new( { type => "DBI", dbi => $self->{locator}->{dbi} } );
184 $self->{dataStorageLayer} = Data::Storage->new( $loc, { protected => 1 } );
185 #$self->{STORAGE_UNDER_THE_HOOD}->{STORAGEHANDLE}->_configureCOREHANDLE();
186 #$self->{STORAGE_UNDER_THE_HOOD}->_configureCOREHANDLE();
187 }
188
189 #print Dumper($self->{STORAGE_UNDER_THE_HOOD});
190
191 return $self->{dataStorageLayer};
192
193 }
194
195 sub _configureUnderlyingStorage {
196
197 my $self = shift;
198
199 $logger->debug( __PACKAGE__ . "->_configureUnderlyingStorage" );
200
201 $self->_configureCOREHANDLE_DBI();
202 return;
203
204 foreach my $key (keys %{$self->{dbi}}) {
205 my $val = $self->{dbi}->{$key};
206 print "entry: $key; $val", "\n";
207 $self->{COREHANDLE}->{db}->{$key} = $val;
208 }
209 #print Dumper($self->{COREHANDLE}->{db});
210 }
211
212
213 sub configureCOREHANDLE {
214
215 my $self = shift;
216
217 $logger->debug( __PACKAGE__ . "->configureCOREHANDLE" );
218
219 #my $subLayer = $self->_getSubLayerHandle();
220
221 # apply configured modifications
222 if (exists $self->{dbi}->{trace_level} && exists $self->{dbi}->{trace_file}) {
223 $self->{COREHANDLE}->{db}->trace($self->{dbi}->{trace_level}, $self->{dbi}->{trace_file});
224 }
225 if (exists $self->{dbi}->{RaiseError}) {
226 $self->{COREHANDLE}->{db}->{RaiseError} = $self->{dbi}->{RaiseError};
227 }
228 if (exists $self->{dbi}->{PrintError}) {
229 $self->{COREHANDLE}->{db}->{PrintError} = $self->{dbi}->{PrintError};
230 }
231 if (exists $self->{dbi}->{HandleError}) {
232 $self->{COREHANDLE}->{db}->{HandleError} = $self->{dbi}->{HandleError};
233 }
234
235 }
236
237 sub deploySchema {
238 my $self = shift;
239 my $args = shift;
240
241 my $dsn = $self->{locator}->{dbi}->{dsn};
242 #my $dsn = $self->{dbi}->{dsn};
243
244 $logger->debug( __PACKAGE__ . "->deploySchema( dsn $dsn )" );
245
246 my $ok;
247 # TODO: is this DBI->connect okay here like it is? regarding errors.....???
248 if ( my $dbh = DBI->connect($dsn, '', '', {
249 PrintError => 0,
250 } ) ) {
251
252 return unless $self->_initSchema();
253
254 $ok = Tangram::Relational->deploy($self->{schema_tangram}, $dbh );
255 $dbh->disconnect();
256 }
257 return $ok;
258 }
259
260 sub retreatSchema {
261
262 my $self = shift;
263 my $dsn = $self->{locator}->{dbi}->{dsn};
264 #my $dsn = $self->{dbi}->{dsn};
265
266 $logger->debug( __PACKAGE__ . "->retreatSchema( dsn $dsn )" );
267
268 my $ok;
269 if ( my $dbh = DBI->connect($dsn, '', '', {
270 #PrintError => 0,
271 #RaiseError => 0,
272 } ) ) {
273
274 return unless $self->_initSchema();
275
276 #use Data::Dumper; print Dumper($self);
277 $self->{dataStorageLayer}->removeLogDispatchHandler("Tangram11");
278
279 $ok = Tangram::Relational->retreat($self->{schema_tangram}, $dbh );
280 $ok = 2; # answer is "maybe" for now since Tangram::Relational->retreat doesn't seem to return a valid status
281 # idea: test this by checking for count of tables in database -
282 # problem with this: there may be some left not having been included to the schema
283 $dbh->disconnect();
284 }
285 return $ok;
286 }
287
288 sub rebuildDbAndSchema {
289 my $self = shift;
290 $logger->info( __PACKAGE__ . "->rebuildDbAndSchema()" );
291 my @results;
292
293 # sum up results (bool (0/1)) in array
294 push @results, $self->retreatSchema();
295 push @results, $self->{dataStorageLayer}->dropDb();
296 push @results, $self->{dataStorageLayer}->createDb();
297 push @results, $self->deploySchema();
298
299 # scan array for "bad ones"
300 my $res = 1;
301 map {
302 $res = 0 if (!$_);
303 } @results;
304
305 return $res;
306 }
307
308 sub getListUnfiltered {
309 my $self = shift;
310 my $nodename = shift;
311 my @results;
312 $logger->debug( __PACKAGE__ . "->getListUnfiltered( nodename => '" . $nodename . "' )" );
313 # get set of objects from odbms by object name
314 my $object_set = $self->{COREHANDLE}->remote($nodename);
315 @results = $self->{COREHANDLE}->select($object_set);
316 return \@results;
317 }
318
319 sub getListFiltered {
320 my $self = shift;
321
322 # redirect to unfiltered mode
323 #return $self->getListUnfiltered(@_);
324
325 my $nodename = shift;
326 my $filters = shift;
327 my @results;
328 $logger->debug( __PACKAGE__ . "->getListFiltered( nodename => '" . $nodename . "' )" );
329
330 #print Dumper($filters);
331
332 my @tfilters;
333
334 foreach my $filter (@$filters) {
335
336 # get filter - TODO: for each filter
337 #my $filter = $filters->[0];
338
339 # build filter
340 my $lexpr = $filter->{key};
341 #my $op = $filter->{op};
342 my $op = '=';
343 my $rexpr = $filter->{val};
344 my $tight = 100;
345
346 # my $tfilter = Tangram::Filter->new(
347 # expr => "t1.$lexpr $op '$rexpr'",
348 # tight => $tight,
349 # objects => $objects,
350 # );
351
352 # HACK: build eval-string (sorry) to get filtered list - please give advice here
353 push @tfilters, '$remote->{' . $filter->{key} . '}' . " $filter->{op} '$filter->{val}'";
354
355 }
356
357 my $tfilter = join(' & ', @tfilters);
358
359 # get set of objects from odbms by object name
360 my $remote = $self->{COREHANDLE}->remote($nodename);
361
362 # was:
363 #@results = $self->{COREHANDLE}->select($object_set, $tfilter);
364
365 # is:
366 # HACK: build eval-string (sorry) to get filtered list - please give advice here
367 my $evalstring = 'return $self->{COREHANDLE}->select($remote, ' . $tfilter . ');';
368
369 # get filtered list/set
370 @results = eval($evalstring);
371 die $@ if $@;
372
373 return \@results;
374 }
375
376 sub createCursor {
377 my $self = shift;
378 my $node = shift;
379 my $cmdHandle = $self->{COREHANDLE}->cursor($node);
380 my $result = Data::Storage::Result::Tangram->new( RESULTHANDLE => $cmdHandle );
381 return $result;
382 }
383
384 sub createSet {
385 my $self = shift;
386 my @objects = @_;
387 my $rh = Set::Object->new();
388 foreach (@objects) {
389 #print Dumper($_);
390 $rh->insert($_) if !isEmpty($_);
391 }
392 #print Dumper($rh->members());
393 my $result = Data::Storage::Result::Tangram->new( RESULTHANDLE => $rh );
394 return $result;
395 }
396
397 sub sendQuery {
398 my $self = shift;
399 my $query = shift;
400 #my $sql = "SELECT cs FROM $self->{metainfo}->{$descent}->{node} WHERE $self->{metainfo}->{$descent}->{IdentProvider}->{arg}='$self->{entry}->{source}->{ident}';";
401 #my $result = $self->{metainfo}->{$descent}->{storage}->sendCommand($sql);
402
403 #print Dumper($query);
404
405 # HACK: special case: querying by id does not translate into a common tangram query
406 # just load the object by given id(ent)
407 if ($query->{criterias}->[0]->{key} eq 'id' && $query->{criterias}->[0]->{op} eq 'eq') {
408 #print "LOAD!!!", "\n";
409 #exit;
410 #return Set::Object->new( $self->{COREHANDLE}->load($query->{criterias}->[0]->{val}) );
411 my $ident = $query->{criterias}->[0]->{val};
412 #print "load obj", "\n";
413 #return $self->createSet() if $ident == 5;
414 my $object = $self->{COREHANDLE}->load($ident);
415 #print "get id", "\n";
416 my $oid = $self->{COREHANDLE}->id($object);
417 return $self->createSet($object);
418 #return $self->createSet( $self->{COREHANDLE}->load('300090018') );
419 }
420
421 die("This should not be reached for now - redirect to \$self->getListFiltered() here!");
422
423 # TODO: do a common tangram query here
424
425 my @crits;
426 foreach (@{$query->{criterias}}) {
427 my $op = '';
428 $op = '=' if lc $_->{op} eq 'eq';
429 push @crits, "$_->{key}$op'$_->{val}'";
430 }
431 my $subnodes = {};
432 map { $subnodes->{$_}++ } @{$query->{subnodes}};
433 # HACK: this is hardcoded ;( expand possibilities!
434 #my $crit = join(' AND ', @crits);
435 #my $sql = hash2Sql($query->{node}, $subnodes, 'SELECT', $crit);
436 #return $self->sendCommand($sql);
437 #my $h = $self->{COREHANDLE}->remote($query->{node});
438 #my $res = $self->{COREHANDLE}->select($h, $h->{);
439 return $self->createCursor($query->{node});
440 }
441
442 sub eraseAll {
443 my $self = shift;
444 my $classname = shift;
445 my $remote = $self->{storage}->remote($classname);
446 my @objs = $self->{storage}->select($remote);
447 $self->{COREHANDLE}->erase(@objs);
448 }
449
450 1;

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