File Coverage

blib/lib/DBIx/HTMLView/DB.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             # DB.pm - A generic DBI databse with SQL interface
4             # (c) Copyright 1999 Hakan Ardo
5             #
6             # This program is free software; you can redistribute it and/or modify
7             # it under the terms of the GNU General Public License as published by
8             # the Free Software Foundation; either version 2 of the License, or
9             # any later version.
10             #
11             # This program is distributed in the hope that it will be useful,
12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14             # GNU General Public License for more details.
15             #
16             # You should have received a copy of the GNU General Public License
17             # along with this program; if not, write to the Free Software
18             # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19              
20             =head1 NAME
21              
22             DBIx::HTMLView::DB - A generic DBI databse with SQL interface
23              
24             =head1 SYNOPSIS
25              
26             use DBIx::HTMLView;
27             my $dbi=my $dbi=DB("DBI:mSQL:HTMLViewTester:localhost", "", "",
28             Table ('Test', Id('id'), Str('testf')));
29             my $hist=$dbi->tab('Test')->list();
30              
31              
32             =head1 DESCRIPTION
33              
34             The DB object is usualy only used to represent the top level database
35             and to access the diffrent tabel objects. But all databse
36             communications is routed through it.
37              
38             This class is intended as a generic base class it is then inherited by
39             engine specifik classes such as DBIx::HTMLView::msqlDB and
40             DBIx::HTMLView::mysqlDB. If you plan to use this with another database
41             engine you'll probably have to atleast overide the insert sub to
42             handle the assignmet of id values to new posts correctly.
43              
44             =head1 METHODS
45             =cut
46              
47             package DBIx::HTMLView::DB;
48 1     1   4 use strict;
  1         2  
  1         35  
49 1     1   844 use DBIx::HTMLView::Log;
  1         2  
  1         89  
50              
51 1     1   3278 use DBI;
  0            
  0            
52             use Carp;
53              
54             =head2 $dbi=DBIx::HTMLView::DB->new($db, $user, $pass, @tabs)
55             =head2 $dbi=DBIx::HTMLView::DB->new($dbh, @tabs)
56              
57             Creates a new database representation to the database engine represented
58             by the DBI data_source $db and connect's to it using $user and $pass
59             as user name and pasword. @tabs is a list of the tables contained in
60             the database in form of DBIx::HTMLView::Table objects.
61              
62             If you'r db needs more initialising than a DBI connect you can
63             initialise the connection yourself and then pass the dbh (as returned
64             by the DBI->connect call) using the second form of the constructor.
65              
66             The database connection will not be closed untill this object is
67             destroyed.
68              
69             =cut
70              
71             sub new {
72             my $this = shift;
73             my $class = ref($this) || $this;
74             my $self= bless {}, $class;
75              
76             my $db=shift;
77             if (ref $db) {
78             $self->{'dbh'}=$db;
79             } else {
80             my $user=shift;
81             my $pass=shift;
82             $self->{'user'}=$user;
83             $self->{'pass'}=$pass;
84             $self->{'database'}=$db;
85             }
86              
87             my $t;
88             foreach $t (@_) {
89             $self->{'tabs'}{$t->name}=$t;
90             $t->set_db($self);
91             }
92              
93             $self;
94             }
95              
96             sub dbh {
97             my ($self)=@_;
98             if(!$self->{'dbh'}) {
99             $self->{'dbh'}=DBI->connect($self->{'database'}, $self->{'user'},
100             $self->{'pass'});
101             if(!$self->{'dbh'}) {croak "DBI->connect failed on ",
102             $self->{'database'}, " for user ",
103             $self->{'user'}}
104             }
105             return $self->{'dbh'};
106             }
107              
108             sub database {shift->{'database'}}
109              
110             sub DESTROY {
111             my $self=shift;
112             if(!$self->{'dbh'}) {
113             $self->{'dbh'}->disconnect;
114             }
115             }
116              
117             sub getlogfile {
118             my $self=shift;
119             $self->{'logfile'};
120             }
121            
122             sub setlogfile {
123             my $self=shift;
124             $self->{'logfile'}=shift;
125             }
126            
127             sub getname {
128             my $self=shift;
129             $self->{'user'};
130             }
131              
132             sub rows {
133             my $self=shift;
134             my $postset=shift;
135              
136             $postset->getsth->rows; #OK DEFAULT
137             }
138              
139              
140             =head2 $dbi->send($cmd)
141              
142             Will prepare and send the SQL command $cmd to the database and it dies
143             on errors. The $sth is returned.
144              
145             =cut
146              
147             =head2 $dbi->print_only
148              
149             After this method has been called all sql queries will be printed
150             instead of sent to the database.
151              
152             =cut
153              
154             sub print_only {shift->{'should_print_only'}=1}
155              
156             sub should_print_only {shift->{'should_print_only'}}
157              
158             sub send {
159             my $self=shift;
160             my $cmd=shift;
161              
162             if ($self->should_print_only) {
163             print "$cmd \n";
164             } else {
165             my $sth = $self->dbh->prepare($cmd);
166             if (!$sth) {
167             confess "Error preparing $cmd: " . $sth->errstr . "\n";
168             }
169             if (!$sth->execute) {
170             confess "Error executing $cmd:" . $sth->errstr . "\n";
171             }
172            
173             make_log($cmd,$self->getname(),$self->getlogfile());
174             $sth;
175             }
176             }
177              
178             =head2 $dbi->tab($tab)
179              
180             Returns the DBIx::HTMLView::Table object representing the table named
181             $tab.
182              
183             =cut
184              
185             sub tab {
186             my ($self, $tab)=@_;
187             croak "Unknown table $tab" if (!defined $self->{'tabs'}{$tab});
188             $self->{'tabs'}{$tab};
189             }
190              
191             =head2 $dbi->tabs
192              
193             Returns an array of DBIx::HTMLView::Table objects representing all the
194             tables in the database.
195              
196             =cut
197              
198             sub tabs {
199             my $self=shift;
200             croak "No tables fond!" if (!defined $self->{'tabs'});
201             values %{$self->{'tabs'}};
202             }
203              
204             =head2 $dbi->sql_escape
205              
206             Escapes the supplied string to be valid inside an SQL command.
207             That is, it changes the string q[I'm a string] to q['I\'m a string'];
208              
209             =cut
210              
211             sub sql_escape {
212             my $self=shift;
213             my $str = shift;
214             $str =~ s/(['\\])/\\$1/g;
215             return "'$str'";
216             }
217              
218             =head2 $dbi->del($tab, $id)
219              
220             Deletes the post with id $id form the table $tab (a DBIx::HTMLView::Table
221             object).
222              
223             =cut
224              
225             sub del {
226             my ($self, $tab, $id)=@_;
227             if ($id =~ /^\d+$/) {$id=$tab->id->name . " = $id";}
228             my $cmd="delete from " . $tab->name . " where " . $id;
229             $self->send($cmd);
230             }
231              
232             =head2 $dbi->update($tab, $post)
233              
234             Updates the data in the database of the post represented by $post (a
235             DBIx::HTMLView::Post object) in the table $tab (a DBIx::HTMLView::Table
236             object) with the data contained in the $post object.
237              
238             =cut
239              
240             sub update {
241             my ($self, $tab, $post)=@_;
242             my $cmd="update " . $tab->name . " set ";
243            
244             foreach my $f ($post->fld_names) {
245             my $fld=$post->fld($f);
246             foreach ($fld->name_vals) {
247             $cmd.= $_->{'name'} ."=". $_->{'val'} . ", ";
248             }
249             }
250             $cmd=~s/, $//;
251             $cmd.=" where " . $tab->id->name . "=" . $post->id;
252             $self->send($cmd);
253              
254             foreach my $f ($post->fld_names) {
255             $post->fld($f)->post_updated;
256             }
257             }
258              
259             =head2 $dbi->insert($tab, $post)
260              
261             Insert the post $post (a DBIx::HTMLView::Post object) into the table
262             $tab (a DBIx::HTMLView::Table object). This is the method to override
263             if you need to change the way new post get's their id numbers
264             assigned. This method should also make sure to set the id fld of $post
265             to the id assigned to it.
266              
267             =cut
268              
269             sub insert {
270             my ($self, $tab, $post)=@_;
271             my $values="";
272             my $names="";
273             my $cmd="insert into " . $tab->name;
274              
275             foreach my $f ($post->fld_names) {
276             foreach ($post->fld($f)->name_vals) {
277             $names .= $_->{'name'}.", ";
278             $values .= $_->{'val'} .", ";
279             }
280             }
281             $names =~ s/, $//;
282             $values =~ s/, $//;
283              
284             $self->send($cmd . " ($names) VALUES ($values)");
285              
286             foreach my $f ($post->fld_names) {
287             $post->fld($f)->post_updated;
288             }
289             }
290              
291             =head2 $dbi->sql_create
292              
293             Will create the tables of the database using SQL commands that works
294             with msql. The database has to be created by hand using msqladmin or
295             msqlconfig.
296              
297             =cut
298              
299             sub sql_create {
300             my $self=shift;
301              
302             foreach ($self->tabs) {
303             $_->sql_create;
304             }
305             }
306              
307             =head2 $dbi->sql_create_table($table)
308              
309             Creates the table $table, a DBIx::HTMLView::Table object, using SQL
310             commands that works with msql.
311              
312             =cut
313              
314             sub sql_create_table {
315             my ($self, $table)=@_;
316             my $cmd="CREATE TABLE ".$table->name . "(";
317              
318             foreach ($table->flds) {
319             my $type=$_->sql_create;
320             if (defined $type) {
321             $cmd .= $_->name . " " . $type . ", ";
322             }
323             }
324             $cmd =~ s/, $//;
325             $self->send($cmd.")");
326             }
327              
328             =head2 $dbi->sql_type($type, $fld)
329              
330             Returns the SQL type string used for the type $type of the Fld $fld. $type
331             should be one of "Id", "Int", "Str", "Text", "Bool", "Date" and $fld
332             should be a DBIx::HTMLView::Fld object.
333              
334             =cut
335              
336             sub sql_type {
337             my ($self, $type, $fld)=@_;
338             my $t=lc($type);
339              
340             if ($fld->got_data('sql_type')) {return $fld->data('sql_type')}
341              
342             my $s="";
343             $s="(".$fld->data('sql_size').")" if ($fld->got_data('sql_size'));
344            
345              
346             if ($t eq 'id') {return "INT$s"}
347             if ($t eq 'int') {return "INT$s"}
348             if ($t eq 'date') {return "DATE"}
349             if ($t eq 'str') {if (!$s) {$s="(100)"} return "CHAR$s"}
350             if ($t eq 'text') {if (!$s) {$s="(500)"} return "CHAR$s"}
351             if ($t eq 'bool') {if (!$s) {$s="(1)"} return "CHAR$s"}
352              
353             die "Bad type $t";
354             }
355              
356             sub viewer {
357             my ($self, $viewer)=@_;
358             if (defined $viewer) {
359             $self->{'viewer'}=$viewer;
360             }
361             return $self->{'viewer'}
362             }
363              
364             1;
365              
366             # Local Variables:
367             # mode: perl
368             # tab-width: 8
369             # perl-indent-level: 2
370             # End: