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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations)
Tue Apr 8 23:06:45 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.12: +9 -4 lines
renamed core database helper functions

1 cvsjoko 1.1 #################################
2     #
3 joko 1.13 # $Id: DBI.pm,v 1.12 2003/01/30 22:28:21 joko Exp $
4 joko 1.2 #
5     # $Log: DBI.pm,v $
6 joko 1.13 # Revision 1.12 2003/01/30 22:28:21 joko
7     # + implemented new concrete methods
8     #
9 joko 1.12 # Revision 1.11 2002/12/19 16:31:05 joko
10     # + sub dropDb
11     # + sub rebuildDb
12     #
13 joko 1.11 # Revision 1.10 2002/12/15 02:02:22 joko
14     # + fixed logging-message
15     #
16 joko 1.10 # Revision 1.9 2002/12/05 07:58:20 joko
17     # + now using Tie::SecureHash as a base for the COREHANDLE
18     # + former public COREHANDLE becomes private _COREHANDLE now
19     #
20 joko 1.9 # Revision 1.8 2002/12/01 22:20:43 joko
21     # + sub createDb (from Storage.pm)
22     #
23 joko 1.8 # Revision 1.7 2002/12/01 07:09:09 joko
24     # + sub getListFiltered (dummy redirecting to getListUnfiltered)
25     #
26 joko 1.7 # Revision 1.6 2002/12/01 04:46:01 joko
27     # + sub eraseAll
28     #
29 joko 1.6 # Revision 1.5 2002/11/29 05:00:26 joko
30     # + sub getListUnfiltered
31     # + sub sendQuery
32     #
33 joko 1.5 # Revision 1.4 2002/11/17 08:46:42 jonen
34     # + wrapped eval around DBI->connect to prevent deaths
35     #
36 jonen 1.4 # Revision 1.3 2002/11/17 06:34:39 joko
37     # + locator metadata can now be reached via ->{locator}
38     # - sub hash2sql now taken from libdb
39     #
40 joko 1.3 # Revision 1.2 2002/10/25 11:43:27 joko
41     # + enhanced robustness
42     # + more logging for debug-levels
43     #
44 joko 1.2 # Revision 1.1 2002/10/10 03:44:07 cvsjoko
45     # + new
46 cvsjoko 1.1 #
47     #
48     #################################
49    
50     package Data::Storage::Handler::DBI;
51    
52     use strict;
53     use warnings;
54    
55     use base ("Data::Storage::Handler::Abstract");
56    
57 joko 1.13
58 cvsjoko 1.1 use DBI;
59 joko 1.3 use Data::Dumper;
60 joko 1.13 use shortcuts::db qw( hash2sql dsn2dbname );
61 joko 1.5 use Data::Storage::Result::DBI;
62 cvsjoko 1.1
63 joko 1.13
64 cvsjoko 1.1 # get logger instance
65     my $logger = Log::Dispatch::Config->instance;
66    
67    
68 joko 1.5 sub getMetaInfo {
69     my $self = shift;
70     $logger->debug( __PACKAGE__ . "->getMetaInfo()" );
71     return {
72     'disconnectMethod' => 'disconnect',
73     };
74     }
75 cvsjoko 1.1
76     sub connect {
77    
78     my $self = shift;
79    
80     # create handle
81 joko 1.3 if ( my $dsn = $self->{locator}->{dbi}->{dsn} ) {
82     #if ( my $dsn = $self->{locator}->{dsn} ) {
83 joko 1.2 $logger->debug( __PACKAGE__ . "->connect( dsn $dsn )" );
84    
85     # HACK:
86     # set errorhandler before actually calling DBI->connect
87     # in order to catch errors from the very beginning
88     #DBI->{HandleError} = $self->{dbi}->{HandleError};
89    
90     #use Data::Dumper; print Dumper($self->{dbi});
91    
92 jonen 1.4 eval {
93 joko 1.9 $self->{_COREHANDLE} = DBI->connect( $dsn, '', '', $self->{locator}->{dbi} );
94     if (!$self->{_COREHANDLE}) {
95 jonen 1.4 $logger->warning( __PACKAGE__ . "->connect failed: " . DBI::errstr );
96     return;
97     }
98     };
99     $logger->warning( __PACKAGE__ . "->connect failed: " . $@ ) if $@;
100    
101 cvsjoko 1.1 }
102     $self->configureCOREHANDLE();
103 joko 1.3
104     $self->{locator}->{status}->{connected} = 1;
105    
106 joko 1.2 return 1;
107    
108 cvsjoko 1.1 }
109    
110     sub configureCOREHANDLE {
111    
112     my $self = shift;
113    
114 joko 1.3 $logger->debug( __PACKAGE__ . "->configureCOREHANDLE" );
115 cvsjoko 1.1
116 joko 1.9 return if !$self->{_COREHANDLE};
117 joko 1.8
118 joko 1.5 # apply configured modifications to DBI-handle
119 joko 1.3 if (exists $self->{locator}->{dbi}->{trace_level} && exists $self->{locator}->{dbi}->{trace_file}) {
120 joko 1.9 $self->{_COREHANDLE}->trace($self->{locator}->{dbi}->{trace_level}, $self->{locator}->{dbi}->{trace_file});
121 cvsjoko 1.1 }
122 joko 1.3 if (exists $self->{locator}->{dbi}->{RaiseError}) {
123 joko 1.9 $self->{_COREHANDLE}->{RaiseError} = $self->{locator}->{dbi}->{RaiseError};
124 cvsjoko 1.1 }
125 joko 1.3 if (exists $self->{locator}->{dbi}->{PrintError}) {
126 joko 1.9 $self->{_COREHANDLE}->{PrintError} = $self->{locator}->{dbi}->{PrintError};
127 cvsjoko 1.1 }
128 joko 1.3 if (exists $self->{locator}->{dbi}->{HandleError}) {
129 joko 1.9 $self->{_COREHANDLE}->{HandleError} = $self->{locator}->{dbi}->{HandleError};
130 cvsjoko 1.1 }
131    
132     }
133    
134     sub _sendSql {
135     my $self = shift;
136     my $sql = shift;
137 joko 1.2
138     # two-level handling for implicit connect:
139     # if there's no corehandle ...
140 joko 1.9 if (!$self->{_COREHANDLE}) {
141 joko 1.2 # ... try to connect, but ...
142     $self->connect();
143     # ... if this still fails, there's something wrong probably, so we won't continue
144 joko 1.9 if (!$self->{_COREHANDLE}) {
145 joko 1.2 return;
146     }
147     }
148    
149 joko 1.3 #print "prepare sql: $sql\n";
150    
151 joko 1.9 my $sth = $self->{_COREHANDLE}->prepare($sql);
152 cvsjoko 1.1 $sth->execute();
153     return $sth;
154     }
155    
156     sub sendCommand {
157     my $self = shift;
158     my $command = shift;
159 joko 1.5 # TODO: when tracing: yes, do actually log this
160 joko 1.2 #$logger->debug( __PACKAGE__ . "->sendCommand( command $command )" );
161 cvsjoko 1.1 my $cmdHandle = $self->_sendSql($command);
162     my $result = Data::Storage::Result::DBI->new( RESULTHANDLE => $cmdHandle );
163     return $result;
164     }
165    
166     sub getChildNodes {
167     my $self = shift;
168     my @nodes;
169 joko 1.3 $logger->debug( __PACKAGE__ . "->getChildNodes()" );
170 joko 1.9 my $locator = $self->{locator};
171     #print Dumper($locator); exit;
172 cvsjoko 1.1 if (my $result = $self->sendCommand( 'SHOW TABLES;' ) ) {
173 joko 1.13 my $dbname = dsn2dbname($self->{locator}->{dbi}->{dsn});
174 joko 1.3 my $key = "Tables_in_$dbname";
175 joko 1.5 while ( my $row = $result->getNextEntry() ) {
176 joko 1.3 push @nodes, $row->{$key};
177 cvsjoko 1.1 }
178     }
179     return \@nodes;
180     }
181    
182 joko 1.5 sub getListUnfiltered {
183 cvsjoko 1.1 my $self = shift;
184 joko 1.5 my $nodename = shift;
185     my @list;
186     $logger->debug( __PACKAGE__ . "->getListUnfiltered( nodename => '" . $nodename . "' )" );
187     # get list of rows from rdbms by table name
188     my $result = $self->sendCommand("SELECT * FROM $nodename");
189     while ( my $row = $result->getNextEntry() ) {
190     push @list, $row;
191     }
192     return \@list;
193 cvsjoko 1.1 }
194    
195 joko 1.5 sub sendQuery {
196 cvsjoko 1.1 my $self = shift;
197 joko 1.5 my $query = shift;
198 joko 1.10
199     $logger->debug( __PACKAGE__ . "->sendQuery" );
200    
201 joko 1.5 #my $sql = "SELECT cs FROM $self->{metainfo}->{$descent}->{node} WHERE $self->{metainfo}->{$descent}->{IdentProvider}->{arg}='$self->{entry}->{source}->{ident}';";
202     #my $result = $self->{metainfo}->{$descent}->{storage}->sendCommand($sql);
203     my @crits;
204     foreach (@{$query->{criterias}}) {
205     my $op = '';
206     $op = '=' if lc $_->{op} eq 'eq';
207     push @crits, "$_->{key}$op'$_->{val}'";
208     }
209     my $subnodes = {};
210     map { $subnodes->{$_}++ } @{$query->{subnodes}};
211     # HACK: this is hardcoded ;( expand possibilities!
212     my $crit = join(' AND ', @crits);
213 joko 1.13 my $sql = hash2sql($query->{node}, $subnodes, 'SELECT', $crit);
214 joko 1.5 return $self->sendCommand($sql);
215 joko 1.6 }
216    
217     sub eraseAll {
218     my $self = shift;
219     my $classname = shift;
220 joko 1.10 $logger->debug( __PACKAGE__ . "->eraseAll" );
221 joko 1.6 my $sql = "DELETE FROM $classname";
222     $self->sendCommand($sql);
223 joko 1.7 }
224    
225     # TODO: actually implement the filtering functionality using $this->sendQuery
226     sub getListFiltered {
227     my $self = shift;
228     my $nodename = shift;
229     return $self->getListUnfiltered($nodename);
230 joko 1.8 }
231    
232     # TODO: do this via a parametrized "$self->connect(<connect just to database server - don't select database>)"
233     sub createDb {
234    
235     my $self = shift;
236    
237     # get dsn from Data::Storage::Locator instance
238     my $dsn = $self->{locator}->{dbi}->{dsn};
239    
240     $logger->debug( __PACKAGE__ . "->createDb( dsn $dsn )" );
241    
242     # remove database setting from dsn-string
243     $dsn =~ s/database=(.+?);//;
244    
245     # remember extracted database name to know what actually to create right now
246     my $database_name = $1;
247    
248     # flag to indicate goodness
249     my $ok;
250    
251     # connect to database server - don't select/use any specific database
252     #if ( my $dbh = DBI->connect($dsn, '', '', { PrintError => 0 } ) ) {
253     if ( my $dbh = DBI->connect($dsn, '', '', $self->{locator}->{dbi} ) ) {
254    
255     if ($database_name) {
256     if ($dbh->do("CREATE DATABASE $database_name")) {
257     $ok = 1;
258     }
259     }
260    
261     $dbh->disconnect();
262    
263     }
264    
265     return $ok;
266    
267 joko 1.9 }
268    
269     sub getCOREHANDLE2 {
270     my $self = shift;
271     return $self->{_COREHANDLE};
272 joko 1.11 }
273    
274     sub dropDb {
275     my $self = shift;
276     my $dsn = $self->{locator}->{dbi}->{dsn};
277    
278     $logger->debug( __PACKAGE__ . "->dropDb( dsn $dsn )" );
279    
280     $dsn =~ s/database=(.+?);//;
281     my $database_name = $1;
282    
283     my $ok;
284    
285     if ( my $dbh = DBI->connect($dsn, '', '', {
286     PrintError => 0,
287     } ) ) {
288     if ($database_name) {
289     if ($dbh->do("DROP DATABASE $database_name;")) {
290     $ok = 1;
291     }
292     }
293    
294     $dbh->disconnect();
295    
296     }
297    
298     return $ok;
299     }
300    
301     sub rebuildDb {
302     my $self = shift;
303     $logger->info( __PACKAGE__ . "->rebuildDb()" );
304     my @results;
305    
306     # sum up results (bool (0/1)) in array
307     #push @results, $self->retreatSchema();
308     push @results, $self->dropDb();
309     push @results, $self->createDb();
310     #push @results, $self->deploySchema();
311    
312     # scan array for "bad ones"
313     my $res = 1;
314     map {
315     $res = 0 if (!$_);
316     } @results;
317    
318     return $res;
319 cvsjoko 1.1 }
320    
321 joko 1.12 sub testAvailability {
322     my $self = shift;
323     my $status = $self->testDsn();
324     $self->{locator}->{status}->{available} = $status;
325     return $status;
326     }
327    
328     sub testDsn {
329     my $self = shift;
330     my $dsn = $self->{locator}->{dbi}->{dsn};
331     my $result;
332     if ( my $dbh = DBI->connect($dsn, '', '', {
333     PrintError => 0,
334     } ) ) {
335    
336     # TODO: REVIEW
337     $dbh->disconnect();
338    
339     return 1;
340     } else {
341     $logger->warning( __PACKAGE__ . "[$self->{locator}->{type}]" . "->testDsn(): " . "DBI-error: " . $DBI::errstr );
342     }
343     }
344    
345 jonen 1.4 1;
346 joko 1.12 __END__

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