/[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.8 - (show annotations)
Sun Dec 1 22:20:43 2002 UTC (21 years, 7 months ago) by joko
Branch: MAIN
Changes since 1.7: +43 -1 lines
+ sub createDb (from Storage.pm)

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

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