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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show 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 #################################
2 #
3 # $Id: DBI.pm,v 1.8 2002/12/01 22:20:43 joko Exp $
4 #
5 # $Log: DBI.pm,v $
6 # Revision 1.8 2002/12/01 22:20:43 joko
7 # + sub createDb (from Storage.pm)
8 #
9 # Revision 1.7 2002/12/01 07:09:09 joko
10 # + sub getListFiltered (dummy redirecting to getListUnfiltered)
11 #
12 # Revision 1.6 2002/12/01 04:46:01 joko
13 # + sub eraseAll
14 #
15 # Revision 1.5 2002/11/29 05:00:26 joko
16 # + sub getListUnfiltered
17 # + sub sendQuery
18 #
19 # Revision 1.4 2002/11/17 08:46:42 jonen
20 # + wrapped eval around DBI->connect to prevent deaths
21 #
22 # 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 # Revision 1.2 2002/10/25 11:43:27 joko
27 # + enhanced robustness
28 # + more logging for debug-levels
29 #
30 # Revision 1.1 2002/10/10 03:44:07 cvsjoko
31 # + new
32 #
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 use Data::Dumper;
45 use libdb qw( getDbNameByDsn hash2Sql );
46 use Data::Storage::Result::DBI;
47
48 # get logger instance
49 my $logger = Log::Dispatch::Config->instance;
50
51
52 sub getMetaInfo {
53 my $self = shift;
54 $logger->debug( __PACKAGE__ . "->getMetaInfo()" );
55 return {
56 'disconnectMethod' => 'disconnect',
57 };
58 }
59
60 sub connect {
61
62 my $self = shift;
63
64 # create handle
65 if ( my $dsn = $self->{locator}->{dbi}->{dsn} ) {
66 #if ( my $dsn = $self->{locator}->{dsn} ) {
67 $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 eval {
77 $self->{_COREHANDLE} = DBI->connect( $dsn, '', '', $self->{locator}->{dbi} );
78 if (!$self->{_COREHANDLE}) {
79 $logger->warning( __PACKAGE__ . "->connect failed: " . DBI::errstr );
80 return;
81 }
82 };
83 $logger->warning( __PACKAGE__ . "->connect failed: " . $@ ) if $@;
84
85 }
86 $self->configureCOREHANDLE();
87
88 $self->{locator}->{status}->{connected} = 1;
89
90 return 1;
91
92 }
93
94 sub configureCOREHANDLE {
95
96 my $self = shift;
97
98 $logger->debug( __PACKAGE__ . "->configureCOREHANDLE" );
99
100 return if !$self->{_COREHANDLE};
101
102 # apply configured modifications to DBI-handle
103 if (exists $self->{locator}->{dbi}->{trace_level} && exists $self->{locator}->{dbi}->{trace_file}) {
104 $self->{_COREHANDLE}->trace($self->{locator}->{dbi}->{trace_level}, $self->{locator}->{dbi}->{trace_file});
105 }
106 if (exists $self->{locator}->{dbi}->{RaiseError}) {
107 $self->{_COREHANDLE}->{RaiseError} = $self->{locator}->{dbi}->{RaiseError};
108 }
109 if (exists $self->{locator}->{dbi}->{PrintError}) {
110 $self->{_COREHANDLE}->{PrintError} = $self->{locator}->{dbi}->{PrintError};
111 }
112 if (exists $self->{locator}->{dbi}->{HandleError}) {
113 $self->{_COREHANDLE}->{HandleError} = $self->{locator}->{dbi}->{HandleError};
114 }
115
116 }
117
118 sub _sendSql {
119 my $self = shift;
120 my $sql = shift;
121
122 # two-level handling for implicit connect:
123 # if there's no corehandle ...
124 if (!$self->{_COREHANDLE}) {
125 # ... try to connect, but ...
126 $self->connect();
127 # ... if this still fails, there's something wrong probably, so we won't continue
128 if (!$self->{_COREHANDLE}) {
129 return;
130 }
131 }
132
133 #print "prepare sql: $sql\n";
134
135 my $sth = $self->{_COREHANDLE}->prepare($sql);
136 $sth->execute();
137 return $sth;
138 }
139
140 sub sendCommand {
141 my $self = shift;
142 my $command = shift;
143 # TODO: when tracing: yes, do actually log this
144 #$logger->debug( __PACKAGE__ . "->sendCommand( command $command )" );
145 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 $logger->debug( __PACKAGE__ . "->getChildNodes()" );
154 my $locator = $self->{locator};
155 #print Dumper($locator); exit;
156 if (my $result = $self->sendCommand( 'SHOW TABLES;' ) ) {
157 my $dbname = getDbNameByDsn($self->{locator}->{dbi}->{dsn});
158 my $key = "Tables_in_$dbname";
159 while ( my $row = $result->getNextEntry() ) {
160 push @nodes, $row->{$key};
161 }
162 }
163 return \@nodes;
164 }
165
166 sub getListUnfiltered {
167 my $self = shift;
168 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 }
178
179 sub sendQuery {
180 my $self = shift;
181 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 }
197
198 sub eraseAll {
199 my $self = shift;
200 my $classname = shift;
201 my $sql = "DELETE FROM $classname";
202 $self->sendCommand($sql);
203 }
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 }
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 }
248
249 sub getCOREHANDLE2 {
250 my $self = shift;
251 return $self->{_COREHANDLE};
252 }
253
254 1;

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