/[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.9 - (hide annotations)
Thu Dec 5 07:58:20 2002 UTC (21 years, 7 months ago) by joko
Branch: MAIN
Changes since 1.8: +21 -11 lines
+ now using Tie::SecureHash as a base for the COREHANDLE
+ former public COREHANDLE becomes private _COREHANDLE now

1 cvsjoko 1.1 #################################
2     #
3 joko 1.9 # $Id: DBI.pm,v 1.8 2002/12/01 22:20:43 joko Exp $
4 joko 1.2 #
5     # $Log: DBI.pm,v $
6 joko 1.9 # Revision 1.8 2002/12/01 22:20:43 joko
7     # + sub createDb (from Storage.pm)
8     #
9 joko 1.8 # Revision 1.7 2002/12/01 07:09:09 joko
10     # + sub getListFiltered (dummy redirecting to getListUnfiltered)
11     #
12 joko 1.7 # Revision 1.6 2002/12/01 04:46:01 joko
13     # + sub eraseAll
14     #
15 joko 1.6 # Revision 1.5 2002/11/29 05:00:26 joko
16     # + sub getListUnfiltered
17     # + sub sendQuery
18     #
19 joko 1.5 # Revision 1.4 2002/11/17 08:46:42 jonen
20     # + wrapped eval around DBI->connect to prevent deaths
21     #
22 jonen 1.4 # Revision 1.3 2002/11/17 06:34:39 joko
23     # + locator metadata can now be reached via ->{locator}
24     # - sub hash2sql now taken from libdb
25     #
26 joko 1.3 # Revision 1.2 2002/10/25 11:43:27 joko
27     # + enhanced robustness
28     # + more logging for debug-levels
29     #
30 joko 1.2 # Revision 1.1 2002/10/10 03:44:07 cvsjoko
31     # + new
32 cvsjoko 1.1 #
33     #
34     #################################
35    
36     package Data::Storage::Handler::DBI;
37    
38     use strict;
39     use warnings;
40    
41     use base ("Data::Storage::Handler::Abstract");
42    
43     use DBI;
44 joko 1.3 use Data::Dumper;
45 joko 1.5 use libdb qw( getDbNameByDsn hash2Sql );
46     use Data::Storage::Result::DBI;
47 cvsjoko 1.1
48     # get logger instance
49     my $logger = Log::Dispatch::Config->instance;
50    
51    
52 joko 1.5 sub getMetaInfo {
53     my $self = shift;
54     $logger->debug( __PACKAGE__ . "->getMetaInfo()" );
55     return {
56     'disconnectMethod' => 'disconnect',
57     };
58     }
59 cvsjoko 1.1
60     sub connect {
61    
62     my $self = shift;
63    
64     # create handle
65 joko 1.3 if ( my $dsn = $self->{locator}->{dbi}->{dsn} ) {
66     #if ( my $dsn = $self->{locator}->{dsn} ) {
67 joko 1.2 $logger->debug( __PACKAGE__ . "->connect( dsn $dsn )" );
68    
69     # HACK:
70     # set errorhandler before actually calling DBI->connect
71     # in order to catch errors from the very beginning
72     #DBI->{HandleError} = $self->{dbi}->{HandleError};
73    
74     #use Data::Dumper; print Dumper($self->{dbi});
75    
76 jonen 1.4 eval {
77 joko 1.9 $self->{_COREHANDLE} = DBI->connect( $dsn, '', '', $self->{locator}->{dbi} );
78     if (!$self->{_COREHANDLE}) {
79 jonen 1.4 $logger->warning( __PACKAGE__ . "->connect failed: " . DBI::errstr );
80     return;
81     }
82     };
83     $logger->warning( __PACKAGE__ . "->connect failed: " . $@ ) if $@;
84    
85 cvsjoko 1.1 }
86     $self->configureCOREHANDLE();
87 joko 1.3
88     $self->{locator}->{status}->{connected} = 1;
89    
90 joko 1.2 return 1;
91    
92 cvsjoko 1.1 }
93    
94     sub configureCOREHANDLE {
95    
96     my $self = shift;
97    
98 joko 1.3 $logger->debug( __PACKAGE__ . "->configureCOREHANDLE" );
99 cvsjoko 1.1
100 joko 1.9 return if !$self->{_COREHANDLE};
101 joko 1.8
102 joko 1.5 # apply configured modifications to DBI-handle
103 joko 1.3 if (exists $self->{locator}->{dbi}->{trace_level} && exists $self->{locator}->{dbi}->{trace_file}) {
104 joko 1.9 $self->{_COREHANDLE}->trace($self->{locator}->{dbi}->{trace_level}, $self->{locator}->{dbi}->{trace_file});
105 cvsjoko 1.1 }
106 joko 1.3 if (exists $self->{locator}->{dbi}->{RaiseError}) {
107 joko 1.9 $self->{_COREHANDLE}->{RaiseError} = $self->{locator}->{dbi}->{RaiseError};
108 cvsjoko 1.1 }
109 joko 1.3 if (exists $self->{locator}->{dbi}->{PrintError}) {
110 joko 1.9 $self->{_COREHANDLE}->{PrintError} = $self->{locator}->{dbi}->{PrintError};
111 cvsjoko 1.1 }
112 joko 1.3 if (exists $self->{locator}->{dbi}->{HandleError}) {
113 joko 1.9 $self->{_COREHANDLE}->{HandleError} = $self->{locator}->{dbi}->{HandleError};
114 cvsjoko 1.1 }
115    
116     }
117    
118     sub _sendSql {
119     my $self = shift;
120     my $sql = shift;
121 joko 1.2
122     # two-level handling for implicit connect:
123     # if there's no corehandle ...
124 joko 1.9 if (!$self->{_COREHANDLE}) {
125 joko 1.2 # ... try to connect, but ...
126     $self->connect();
127     # ... if this still fails, there's something wrong probably, so we won't continue
128 joko 1.9 if (!$self->{_COREHANDLE}) {
129 joko 1.2 return;
130     }
131     }
132    
133 joko 1.3 #print "prepare sql: $sql\n";
134    
135 joko 1.9 my $sth = $self->{_COREHANDLE}->prepare($sql);
136 cvsjoko 1.1 $sth->execute();
137     return $sth;
138     }
139    
140     sub sendCommand {
141     my $self = shift;
142     my $command = shift;
143 joko 1.5 # TODO: when tracing: yes, do actually log this
144 joko 1.2 #$logger->debug( __PACKAGE__ . "->sendCommand( command $command )" );
145 cvsjoko 1.1 my $cmdHandle = $self->_sendSql($command);
146     my $result = Data::Storage::Result::DBI->new( RESULTHANDLE => $cmdHandle );
147     return $result;
148     }
149    
150     sub getChildNodes {
151     my $self = shift;
152     my @nodes;
153 joko 1.3 $logger->debug( __PACKAGE__ . "->getChildNodes()" );
154 joko 1.9 my $locator = $self->{locator};
155     #print Dumper($locator); exit;
156 cvsjoko 1.1 if (my $result = $self->sendCommand( 'SHOW TABLES;' ) ) {
157 joko 1.3 my $dbname = getDbNameByDsn($self->{locator}->{dbi}->{dsn});
158     my $key = "Tables_in_$dbname";
159 joko 1.5 while ( my $row = $result->getNextEntry() ) {
160 joko 1.3 push @nodes, $row->{$key};
161 cvsjoko 1.1 }
162     }
163     return \@nodes;
164     }
165    
166 joko 1.5 sub getListUnfiltered {
167 cvsjoko 1.1 my $self = shift;
168 joko 1.5 my $nodename = shift;
169     my @list;
170     $logger->debug( __PACKAGE__ . "->getListUnfiltered( nodename => '" . $nodename . "' )" );
171     # get list of rows from rdbms by table name
172     my $result = $self->sendCommand("SELECT * FROM $nodename");
173     while ( my $row = $result->getNextEntry() ) {
174     push @list, $row;
175     }
176     return \@list;
177 cvsjoko 1.1 }
178    
179 joko 1.5 sub sendQuery {
180 cvsjoko 1.1 my $self = shift;
181 joko 1.5 my $query = shift;
182     #my $sql = "SELECT cs FROM $self->{metainfo}->{$descent}->{node} WHERE $self->{metainfo}->{$descent}->{IdentProvider}->{arg}='$self->{entry}->{source}->{ident}';";
183     #my $result = $self->{metainfo}->{$descent}->{storage}->sendCommand($sql);
184     my @crits;
185     foreach (@{$query->{criterias}}) {
186     my $op = '';
187     $op = '=' if lc $_->{op} eq 'eq';
188     push @crits, "$_->{key}$op'$_->{val}'";
189     }
190     my $subnodes = {};
191     map { $subnodes->{$_}++ } @{$query->{subnodes}};
192     # HACK: this is hardcoded ;( expand possibilities!
193     my $crit = join(' AND ', @crits);
194     my $sql = hash2Sql($query->{node}, $subnodes, 'SELECT', $crit);
195     return $self->sendCommand($sql);
196 joko 1.6 }
197    
198     sub eraseAll {
199     my $self = shift;
200     my $classname = shift;
201     my $sql = "DELETE FROM $classname";
202     $self->sendCommand($sql);
203 joko 1.7 }
204    
205     # TODO: actually implement the filtering functionality using $this->sendQuery
206     sub getListFiltered {
207     my $self = shift;
208     my $nodename = shift;
209     return $self->getListUnfiltered($nodename);
210 joko 1.8 }
211    
212     # TODO: do this via a parametrized "$self->connect(<connect just to database server - don't select database>)"
213     sub createDb {
214    
215     my $self = shift;
216    
217     # get dsn from Data::Storage::Locator instance
218     my $dsn = $self->{locator}->{dbi}->{dsn};
219    
220     $logger->debug( __PACKAGE__ . "->createDb( dsn $dsn )" );
221    
222     # remove database setting from dsn-string
223     $dsn =~ s/database=(.+?);//;
224    
225     # remember extracted database name to know what actually to create right now
226     my $database_name = $1;
227    
228     # flag to indicate goodness
229     my $ok;
230    
231     # connect to database server - don't select/use any specific database
232     #if ( my $dbh = DBI->connect($dsn, '', '', { PrintError => 0 } ) ) {
233     if ( my $dbh = DBI->connect($dsn, '', '', $self->{locator}->{dbi} ) ) {
234    
235     if ($database_name) {
236     if ($dbh->do("CREATE DATABASE $database_name")) {
237     $ok = 1;
238     }
239     }
240    
241     $dbh->disconnect();
242    
243     }
244    
245     return $ok;
246    
247 joko 1.9 }
248    
249     sub getCOREHANDLE2 {
250     my $self = shift;
251     return $self->{_COREHANDLE};
252 cvsjoko 1.1 }
253    
254 jonen 1.4 1;

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