File Coverage

blib/lib/DBO.pm
Criterion Covered Total %
statement 121 154 78.5
branch 3 16 18.7
condition n/a
subroutine 46 55 83.6
pod 6 15 40.0
total 176 240 73.3


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # DBO - Database Objects
3             #
4             # DESCRIPTION
5             # An object-oriented database abstraction layer.
6             #
7             # AUTHOR
8             # Gareth Rees
9             #
10             # COPYRIGHT
11             # Copyright (c) 1999 Canon Research Centre Europe Ltd/
12             #
13             # $Id: DBO.pm,v 1.4 1999/06/29 17:09:30 garethr Exp $
14             #------------------------------------------------------------------------------
15              
16 4     4   12863 use strict;
  4         8  
  4         145  
17             package DBO;
18 4     4   18 use base 'Exporter';
  4         6  
  4         441  
19 4     4   48 use Carp;
  4         9  
  4         352  
20 4     4   3544 use UNIVERSAL 'isa';
  4         46  
  4         18  
21 4     4   5339 use Class::Multimethods qw(visit_database visit_table);
  4         74861  
  4         32  
22 4     4   6989 use vars qw($VERSION $DEBUG @EXPORT_OK %EXPORT_TAGS);
  4         11  
  4         3171  
23              
24             $VERSION = '0.01';
25             $DEBUG = 0;
26             @EXPORT_OK = qw(Database Table Key Option ForeignKey Char Text Integer Unsigned AutoIncrement Time);
27             %EXPORT_TAGS = (constructors => [qw(Database Table Key Option ForeignKey Char Text Integer Unsigned AutoIncrement Time)]);
28              
29             sub new {
30 4     4 0 817 my $class = shift;
31 4         24 my $self = bless { @_ }, $class;
32              
33             # Check that the schema argument is a DBO::Database.
34 4 50       65 isa($self->{schema},'DBO::Database')
35             or croak(DBO::Exception->new
36             (SCHEMA => "'schema' must be a DBO::Database, not %s.",
37             ref $self->{schema}));
38              
39             # Check that the handle argument is a DBO::Handle.
40 4 50       49 isa($self->{handle},'DBO::Handle')
41             or croak(DBO::Exception->new
42             (HANDLE => "'handle' must be a DBO::Handle, not %s.",
43             ref $self->{handle}));
44              
45             # Apply the Initialize visitor.
46 0         0 require DBO::Visitor::Initialize;
47 0         0 $self->apply_to_database('DBO::Visitor::Initialize');
48              
49 0         0 return $self;
50             }
51              
52             sub DESTROY {
53 4     4   11 my $self = shift;
54 4         316 $self->{dbh}->disconnect;
55             }
56              
57             sub apply_to_database {
58 0     0 0 0 my $self = shift;
59 0         0 my $vis = shift;
60 0 0       0 $vis = $vis->new(@_) unless ref $vis;
61 0         0 visit_database($vis, $self->{schema}, $self->{handle});
62             }
63              
64             sub apply_to_table {
65 0     0 0 0 my $self = shift;
66 0         0 my $id = shift;
67 0 0       0 my $table = $self->{schema}->lookup_table($id)
68             or die DBO::Exception->new(NO_SUCH_TABLE => "No such table: %s", $id);
69 0         0 my $vis = shift;
70 0 0       0 $vis = $vis->new(@_) unless ref $vis;
71 0         0 visit_table($vis, $table, $self->{handle});
72             }
73              
74             sub error {
75 0     0 0 0 my $self = shift;
76 0         0 $self->{error} = shift;
77             }
78              
79             #------------------------------------------------------------------------------
80             # Constructor functions (for convenience)
81             #------------------------------------------------------------------------------
82              
83 4     4 1 51 sub Database { DBO::Database->new(@_) }
84 4     4 1 82 sub Table { DBO::Table->new(@_) }
85 4     4 0 53 sub Key { DBO::Column::Key->new(@_) }
86 8     8 0 49 sub Option { DBO::Column::Option->new(@_) }
87 0     0 0 0 sub ForeignKey { DBO::Column::ForeignKey->new(@_) }
88 8     8 1 57 sub Char { DBO::Column::Char->new(@_) }
89 4     4 1 38 sub Text { DBO::Column::Text->new(@_) }
90 4     4 1 39 sub Integer { DBO::Column::Integer->new(@_) }
91 8     8 1 48 sub Unsigned { DBO::Column::Unsigned->new(@_) }
92 4     4 0 8075 sub AutoIncrement { DBO::Column::AutoIncrement->new(@_) }
93 8     8 0 63 sub Time { DBO::Column::Time->new(@_) }
94              
95              
96             #------------------------------------------------------------------------------
97             # DBO::Handle - handle to a database
98             #------------------------------------------------------------------------------
99              
100             package DBO::Handle;
101              
102             package DBO::Handle::DBI;
103 4     4   27 use base 'DBO::Handle';
  4         5  
  4         2335  
104 4     4   22 use vars '$AUTOLOAD';
  4         8  
  4         920  
105              
106             sub connect {
107 4     4   4035 my $class = shift;
108 4         9366 require DBI;
109 4 0       89774 my $dbh = DBI->connect(@_) or return;
110 0         0 bless \$dbh, $class;
111             }
112              
113             sub dosql {
114 0     0   0 my $self = shift;
115 0         0 my $sql = join ' ', @_;
116 0 0       0 $$self->do($sql)
117             or croak(DBO::Exception->new
118             (SQL => "Failed to execute SQL statement %s: %s.",
119             $sql, $$self->errstr));
120             }
121              
122             sub AUTOLOAD {
123 0     0   0 my $self = shift;
124 0         0 my $method = $AUTOLOAD;
125 0         0 $method =~ s/.*://;
126 0         0 $$self->$method(@_);
127             }
128              
129             package DBO::Handle::DBI::mSQL;
130 4     4   20 use base 'DBO::Handle::DBI';
  4         7  
  4         1983  
131              
132             package DBO::Handle::DBI::mysql;
133 4     4   60 use base 'DBO::Handle::DBI';
  4         7  
  4         1896  
134              
135              
136             #------------------------------------------------------------------------------
137             # DBO::Exception - class of exceptions
138             #------------------------------------------------------------------------------
139              
140             package DBO::Exception;
141              
142             sub new {
143 4     4   9 my $class = shift;
144 4         11 my $exception = shift;
145 4         8 my $default = shift;
146 4         29 my $self = bless { exception => $exception,
147             default => $default,
148             args => [ @_ ] }, $class;
149 4 50       34 warn $self->format if $DBO::DEBUG;
150 4         154 return $self;
151             }
152              
153             sub format {
154 4     4   10 my $self = shift;
155 4         24 sprintf $self->{default}, @{$self->{args}};
  4         379  
156             }
157              
158              
159             #------------------------------------------------------------------------------
160             # DBO::Database - abstract representation of a database
161             #------------------------------------------------------------------------------
162              
163             package DBO::Database;
164 4     4   19 use Class::Multimethods 'visit_database';
  4         5  
  4         20  
165              
166             sub new {
167 4     4   8 my $class = shift;
168 4         18 my $self = bless { @_ }, $class;
169 4         14 return $self;
170             }
171              
172             sub lookup_table {
173 0     0   0 my $self = shift;
174 0         0 my $id = shift;
175 0         0 $self->{tables_by_id}{$id};
176             }
177              
178              
179             #------------------------------------------------------------------------------
180             # DBO::Table - abstract representation of a database table
181             #------------------------------------------------------------------------------
182              
183             package DBO::Table;
184 4     4   4221 use Class::Multimethods 'visit_table';
  4         8  
  4         14  
185              
186             sub new {
187 4     4   9 my $class = shift;
188 4         22 my $self = bless { @_ }, $class;
189 4         15 return $self;
190             }
191              
192             sub lookup_column {
193 0     0   0 my $self = shift;
194 0         0 my $id = shift;
195 0         0 $self->{columns_by_id}{$id};
196             }
197              
198              
199             #------------------------------------------------------------------------------
200             # DBO::Column - abstract representation of a database column
201             #------------------------------------------------------------------------------
202              
203             package DBO::Column;
204 4     4   3815 use Class::Multimethods 'visit_column';
  4         6  
  4         15  
205              
206             sub new {
207 48     48   63 my $class = shift;
208 48         181 my $self = bless { @_ }, $class;
209 48         235 return $self;
210             }
211              
212             sub visit {
213 0     0   0 my $self = shift;
214 0         0 my $visitor = shift;
215 0         0 visit_column($visitor, $self);
216             }
217              
218             package DBO::Column::Modifier;
219 4     4   3898 use base 'DBO::Column';
  4         8  
  4         1819  
220              
221             package DBO::Column::Key;
222 4     4   21 use base 'DBO::Column::Modifier';
  4         8  
  4         1721  
223              
224             package DBO::Column::Option;
225 4     4   21 use base 'DBO::Column::Modifier';
  4         6  
  4         2000  
226              
227             package DBO::Column::ForeignKey;
228 4     4   21 use base 'DBO::Column::Modifier';
  4         7  
  4         1704  
229              
230             package DBO::Column::Base;
231 4     4   24 use base 'DBO::Column';
  4         6  
  4         1768  
232              
233             package DBO::Column::Number;
234 4     4   24 use base 'DBO::Column::Base';
  4         6  
  4         1820  
235              
236             package DBO::Column::String;
237 4     4   20 use base 'DBO::Column::Base';
  4         6  
  4         1552  
238              
239             package DBO::Column::Char;
240 4     4   19 use base 'DBO::Column::String';
  4         8  
  4         2125  
241              
242             package DBO::Column::Text;
243 4     4   36 use base 'DBO::Column::String';
  4         7  
  4         1564  
244              
245             package DBO::Column::Integer;
246 4     4   22 use base 'DBO::Column::Number';
  4         6  
  4         1960  
247              
248             package DBO::Column::Unsigned;
249 4     4   23 use base 'DBO::Column::Integer';
  4         9  
  4         1788  
250              
251             package DBO::Column::AutoIncrement;
252 4     4   21 use base 'DBO::Column::Unsigned';
  4         7  
  4         1755  
253              
254             package DBO::Column::Time;
255 4     4   20 use base 'DBO::Column::Char';
  4         7  
  4         1549  
256              
257              
258             #------------------------------------------------------------------------------
259             # DBO::Visitor - an action on a database
260             #------------------------------------------------------------------------------
261              
262             package DBO::Visitor;
263 4     4   23 use Class::Multimethods;
  4         5  
  4         21  
264              
265             sub new {
266 7     7   3211 my $class = shift;
267 7         24 my $self = bless { @_ }, $class;
268 7         19 return $self;
269             }
270              
271             multimethod visit_database =>
272             qw(DBO::Visitor DBO::Database DBO::Handle) =>
273             sub {
274             my ($vis, $database, $handle) = @_;
275             foreach my $table (@{$database->{tables}}) {
276             visit_table($vis, $table, $handle);
277             }
278             };
279              
280             multimethod visit_table =>
281             qw(DBO::Visitor DBO::Table DBO::Handle) =>
282             sub {
283             my ($vis, $table, $handle) = @_;
284             foreach my $col (@{$table->{columns}}) {
285             visit_column($vis, $col, $handle);
286             }
287             };
288              
289             multimethod visit_column =>
290             qw(DBO::Visitor DBO::Column::Base DBO::Handle) =>
291             sub {
292             # my ($vis, $col, $handle) = @_;
293             };
294              
295             multimethod visit_column =>
296             qw(DBO::Visitor DBO::Column::Modifier DBO::Handle) =>
297             sub {
298             my ($vis, $col, $handle) = @_;
299             visit_column($vis, $col->{base}, $handle);
300             };
301              
302             1;
303              
304             __END__