File Coverage

blib/lib/IO/DB.pm
Criterion Covered Total %
statement 9 98 9.1
branch 0 26 0.0
condition n/a
subroutine 3 14 21.4
pod 6 8 75.0
total 18 146 12.3


line stmt bran cond sub pod time code
1             package IO::DB;
2              
3             # IO::DB object module
4             # Copyright (c) 2003-2005 by David Bialac
5             # Rights to use and or modify this code is granted under the terms of the GNU
6             # Lesser Public license or the Perl Artistic License.
7              
8 1     1   38459 use DBI;
  1         22779  
  1         99  
9 1     1   14 use Carp;
  1         2  
  1         107  
10 1     1   6 use strict;
  1         7  
  1         1227  
11              
12             our ($VERSION);
13              
14             $VERSION = "0.1";
15              
16             =head1 NAME
17              
18             IO::DB - Database convenience object.
19              
20             =head1 SYNOPSIS
21              
22             use IO::DB;
23              
24             my $db = new IO::DB( { db_dsn => 'dbi:Sybase:db01',
25             db_user => 'web',
26             db_pass => 'password' } );
27              
28             # Note the lack of a connect!
29              
30             my $rows = $db->sql_rows( 'select count(*) from mytable' );
31              
32             foreach my $row (@$rows) {
33             print $row->{value}, "\n";
34             }
35              
36             my $hash = $db->sql_hash( 'select name, count(*)
37             from mytable
38             group by name' );
39              
40             foreach my $key (keys(%$hash)) {
41             print "$key is $hash{$key}\n";
42             }
43              
44             =head1 DESCRIPTION
45              
46             The IO::DB library was created and is intended as a convenience library. It
47             works by reducing clutter in your code caused by using the same redundant
48             code. It also works under the philosophy of intelligent code. That is,
49             let me tell you to do something and let the code figure out the prerequisits.
50             This is in part responsible for the lack of an explicit connect function.
51             It is also responsible for the currently incomplete quote function. Those who
52             are adventurous may poke around and try it out.
53              
54             Back to the topic of connecting, the library will automatically connect to
55             the database the first time you issue a sql statement. If for some reason
56             you need some functionality tied to dbh, you can access it through the dbh
57             member like this:
58              
59             $db->{dbh}->quote( $mycolumndata );
60              
61             Note that if you haven't executed any sql, this will not work. If you find
62             a case where you do need an explicit connect, simply call the private
63             _connect function like so:
64              
65             $db->_connect();
66              
67             Features eventually slated include an improved 'quote' function which looks
68             at the table and determines if a field needs quoting or not. All of this
69             information will of course be cached to limit the additional load on the
70             database that this will inevidably cause.
71              
72             =head1 METHODS
73              
74             =head2 new
75              
76             The new function creates a new instance of the IO::DB object. It
77             should be passed a configuration parameter either through a hash
78             or through a configuration object resembling a hash. The three
79             parameters in the configuration are:
80              
81             db_dsn - the DSN string you would normally pass to DBI
82             db_user - the username to log into the database with
83             db_pass - the password to use or undef if no password
84              
85             =cut
86              
87             sub new {
88 0     0 1   my $base = shift;
89 0           my $registry = shift;
90 0           my %self = ( 'registry' => $registry );
91 0           my $s = bless \%self, $base;
92              
93 0           return $s;
94             }
95              
96             sub _connect {
97 0     0     my $self = shift;
98 0           my $registry = $self->{registry};
99              
100 0           my $dsn = $self->{registry}->{db_dsn};
101 0           my $user = $self->{registry}->{db_user};
102 0           my $pass = $self->{registry}->{db_pass};
103              
104 0 0         if (ref($pass) =~ /HASH/) {
105 0           $pass = "";
106             }
107              
108 0 0         unless ($self->{dbh}) {
109 0           $self->{dbh} = DBI->connect( $dsn, $user, $pass );
110             }
111              
112 0 0         unless ($self->{dbh}) {
113 0           confess "Unable to connect to database! ($dsn/$user/$pass)";
114             }
115             }
116              
117             =head2 sql_do
118              
119             The sql_do function simply privides a wrapper around the DBI 'do'
120             statement. Other than this, it does nothing. Simply pass the
121             sql to execute as the first parameter.
122              
123             $db->sql_do("delete from mytable where inactive='Y'");
124              
125             =cut
126              
127             sub sql_do {
128 0     0 1   my $self = shift;
129 0           my $sql = shift;
130              
131 0           $self->_connect();
132 0           $self->{dbh}->do( $sql );
133             }
134              
135             =head2 sql
136              
137             The sql function works by wrapping around a prepare statement
138             and executing the passed sql. It supports using paramaters
139             (1, 2, 3, ... or ?, ?, ?,...) for the sql. Coming enhancements
140             include caching sth handles to improve performance.
141              
142             my $sth = $db->sql( "select count(*) from mytable" );
143              
144             -or-
145              
146             my $sth = $db->sql( "select count(*) from mytable
147             where a=? and b=?", $a, $b );
148              
149             =cut
150              
151             sub sql {
152 0     0 1   my $self = shift;
153 0           my $sql = shift;
154              
155 0           $self->_connect();
156              
157 0           my $sth = $self->{dbh}->prepare( $sql );
158 0           my $rv;
159 0 0         if (scalar(@_)) {
160 0           $rv = $sth->execute( @_ );
161             } else {
162 0           $rv = $sth->execute();
163             }
164 0 0         print STDERR "--DBSQL--\n$sql\n" if ($self->{dbh}->errstr);
165              
166 0           return $sth;
167             }
168              
169             =head2 sql_rows
170              
171             The sql_rows function behaves much like the sql statement, except
172             that instead of returning the $sth object, it will instead return
173             a reference to an array containing the result set. Each row will
174             have it's values contained within a hash. Care should be
175             taken with this function as large result sets will undoubtedly
176             kill the performance of your computer.
177              
178             my $rows = $db->sql_rows( 'select foo, bar from mytable' );
179              
180             foreach my $row (@$rows) {
181             print "$row->{foo}, $row->{bar}\n";
182             }
183              
184             =cut
185              
186             sub sql_rows {
187 0     0 1   my $self = shift;
188 0           my $sql = shift;
189              
190 0           my @array;
191              
192             my $sth;
193              
194 0 0         if (@_) {
195 0           $sth = $self->sql( $sql, @_ );
196             } else {
197 0           $sth = $self->sql( $sql );
198             }
199              
200 0           while (my $row = $sth->fetchrow_hashref()) {
201 0           push (@array, $row);
202             }
203              
204 0           return \@array;
205             }
206              
207             sub get_column_types {
208 0     0 0   my $self = shift;
209 0           my $table = shift;
210              
211              
212 0 0         unless (exists($self->{'.tables'}->{$table})) {
213 0           my ($t, $d);
214 0 0         if ($table =~ /\.\./) {
215 0           ($d,$t) = split ('\.\.', $table );
216 0           $self->sql("use $d");
217             } else {
218 0           $t = $table;
219             }
220 0           my $sql = "sp_columns $t";
221              
222 0           my $cols = $self->sql_rows( $sql );
223 0           my %chash = ();
224 0           foreach my $col (@$cols) {
225 0           $chash{$col->{COLUMN_NAME}} = $col->{TYPE_NAME};
226             }
227              
228 0           $self->{'.tables'}->{$table} = \%chash;
229             }
230              
231 0           return $self->{'.tables'}->{$table};
232             }
233              
234             sub get_columns {
235 0     0 0   my $self = shift;
236 0           my $table = shift;
237              
238 0           $self->get_column_types($table);
239 0           my @cols = keys(%{$self->{'.tables'}->{$table}});
  0            
240 0           return \@cols;
241             }
242              
243             =head2 sql_hash
244              
245             The sql_hash function is useful for returning two-column
246             result sets as a hash rather than as a set of rows. It again
247             behaves in much the same manner as the sql function does.
248              
249             =cut
250              
251             sub sql_hash {
252 0     0 1   my $self = shift;
253 0           my $sql = shift;
254              
255 0           my $sth;
256 0 0         if (@_) {
257 0           $sth = $self->sql($sql, @_);
258             } else {
259 0           $sth = $self->sql($sql);
260             }
261 0           my %return_hash;
262              
263 0           while (my @row = $sth->fetchrow_array) {
264 0           $return_hash{$row[0]} = $row[1];
265             }
266              
267 0           return \%return_hash;
268             }
269              
270             =head2 quote
271              
272             WARNING: THIS FUNCTION MAY NOT FUNCTION PROPERYLY FOR YOU.
273             It is currenty specific to SQL Server and Sybase.
274              
275             The quote function is useful for quoting data prior to insertion.
276             It has the nice trate that it does datatype lookups on tables
277             so you don't have to know what to quote and what not to. HOWEVER
278             it currently will quote functions as though they are strings with
279             the notable exception of the getdate() function.
280              
281             =cut
282              
283             sub quote {
284 0     0 1   my $self = shift;
285 0           my $table = shift;
286 0           my $column = shift;
287 0           my $data = shift;
288              
289 0           $self->get_column_types($table);
290              
291             # Null conversion
292 0 0         unless ($data) {
293 0           return 'NULL';
294             }
295              
296             # Functions never get quoted, this needs extreme expanding
297 0 0         if ($data =~ /getdate()/i) {
298 0           return $data;
299             }
300              
301 0 0         if ($self->{'.tables'}->{$table}->{$column} =~ /CHAR|DATE|TEXT|BINARY/i) {
302 0           $self->_connect();
303 0           return $self->{dbh}->quote( $data );
304             }
305 0           return $data;
306             }
307              
308             sub _disconnect {
309 0     0     my $self = shift;
310              
311 0 0         if ($self->{dbh}) {
312 0           $self->{dbh}->disconnect();
313 0           delete ($self->{dbh});
314             }
315             }
316              
317              
318             sub DESTROY {
319 0     0     my $self = shift;
320 0           $self->_disconnect();
321             }
322              
323             =head1 AUTHOR
324              
325             David Bialac
326              
327             =head1 VERSION
328              
329             IO::DB version 0.1, released on 22 June 2005.
330              
331             =head1 COPYRIGHT
332              
333             Copyright (C) 2003-2005 David Bialac. All Rights Reserved.
334              
335             This module is free software; you can redistribute it and/or modify
336             it under the terms of the GNU Lesser Public License or the Perl
337             Artistic License at your discression.
338              
339             =cut
340              
341             1;