File Coverage

blib/lib/Class/DBI/mysql.pm
Criterion Covered Total %
statement 7 47 14.8
branch 0 16 0.0
condition 0 6 0.0
subroutine 3 10 30.0
pod 7 7 100.0
total 17 86 19.7


line stmt bran cond sub pod time code
1             package Class::DBI::mysql;
2              
3             $VERSION = '1.00';
4              
5             =head1 NAME
6              
7             Class::DBI::mysql - Extensions to Class::DBI for MySQL
8              
9             =head1 SYNOPSIS
10              
11             package Film;
12             use base 'Class::DBI::mysql';
13             __PACKAGE__->set_db('Main', 'dbi:mysql:dbname', 'user', 'password');
14             __PACKAGE__->set_up_table("film");
15              
16             __PACKAGE__->autoinflate(dates => 'Time::Piece');
17              
18             # Somewhere else ...
19              
20             my $type = $class->column_type('column_name');
21             my @allowed = $class->enum_vals('column_name');
22              
23             my $tonights_viewing = Film->retrieve_random;
24              
25             =head1 DESCRIPTION
26              
27             This is an extension to Class::DBI, containing several functions and
28             optimisations for the MySQL database. Instead of setting Class::DBI
29             as your base class, use this instead.
30              
31             =cut
32              
33 1     1   48496 use strict;
  1         5  
  1         137  
34 1     1   6 use base 'Class::DBI';
  1         2  
  1         6969  
35              
36             =head1 METHODS
37              
38             =head2 set_up_table
39              
40             __PACKAGE__->set_up_table("table_name");
41              
42             Traditionally, to use Class::DBI, you have to set up the columns:
43              
44             __PACKAGE__->columns(All => qw/list of columns/);
45             __PACKAGE__->columns(Primary => 'column_name');
46              
47             Whilst this allows for more flexibility if you're going to arrange your
48             columns into a variety of groupings, sometimes you just want to create the
49             'all columns' list. Well, this information is really simple to extract
50             from MySQL itself, so why not just use that?
51              
52             This call will extract the list of all the columns, and the primary key
53             and set them up for you. It will die horribly if the table contains
54             no primary key, or has a composite primary key.
55              
56             =cut
57              
58             __PACKAGE__->set_sql(desc_table => 'DESCRIBE __TABLE__');
59              
60             sub set_up_table {
61 0     0 1 0 my $class = shift;
62 0   0     0 $class->table(my $table = shift || $class->table);
63 0         0 (my $sth = $class->sql_desc_table)->execute;
64 0         0 my (@cols, @pri);
65 0         0 while (my $hash = $sth->fetch_hash) {
66 0         0 my ($col) = $hash->{field} =~ /(\w+)/;
67 0         0 push @cols, $col;
68 0 0       0 push @pri, $col if $hash->{key} eq "PRI";
69             }
70 0 0       0 $class->_croak("$table has no primary key") unless @pri;
71 0         0 $class->columns(Primary => @pri);
72 0         0 $class->columns(All => @cols);
73             }
74              
75             =head2 autoinflate
76              
77             __PACKAGE__->autoinflate(column_type => 'Inflation::Class');
78              
79             __PACKAGE__->autoinflate(timestamp => 'Time::Piece');
80             __PACKAGE__->autoinflate(dates => 'Time::Piece');
81              
82             This will automatically set up has_a() relationships for all columns of
83             the specified type to the given class.
84              
85             We currently assume that all classess passed will be able to inflate
86             and deflate without needing extra has_a arguments, with the example of
87             Time::Piece objects, which we deal with using Time::Piece::mysql (which
88             you'll have to have installed!).
89              
90             The special type 'dates' will autoinflate all columns of type date,
91             datetime or timestamp.
92              
93             =cut
94              
95             sub autoinflate {
96 0     0 1 0 my ($class, %how) = @_;
97 0   0     0 $how{$_} ||= $how{dates} for qw/date datetime timestamp/;
98 0         0 my $info = $class->_column_info;
99 0         0 foreach my $col (keys %$info) {
100 0         0 (my $type = $info->{$col}->{type}) =~ s/\W.*//;
101 0 0       0 next unless $how{$type};
102 0         0 my %args;
103 0 0       0 if ($how{$type} eq "Time::Piece") {
104 0         0 eval "use Time::Piece::MySQL";
105 0 0       0 $class->_croak($@) if $@;
106 0         0 $args{inflate} = "from_mysql_$type";
107 0         0 $args{deflate} = "mysql_$type";
108             }
109 0         0 $class->has_a($col => $how{$type}, %args);
110             }
111             }
112              
113             =head2 create_table
114              
115             $class->create_table(q{
116             name VARCHAR(40) NOT NULL PRIMARY KEY,
117             rank VARCHAR(20) NOT NULL DEFAULT 'Private',
118             serial INTEGER NOT NULL
119             });
120              
121             This creates the table for the class, with the given schema. If the
122             table already exists we do nothing.
123              
124             A typical use would be:
125              
126             Music::CD->table('cd');
127             Music::CD->create_table(q{
128             cdid MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
129             artist MEDIUMINT UNSIGNED NOT NULL,
130             title VARCHAR(255),
131             year YEAR,
132             INDEX (artist),
133             INDEX (title)
134             });
135             Music::CD->set_up_table;
136              
137             =head2 drop_table
138              
139             $class->drop_table;
140              
141             Drops the table for this class, if it exists.
142              
143             =cut
144              
145             __PACKAGE__->set_sql(
146             create_table => 'CREATE TABLE IF NOT EXISTS __TABLE__ (%s)');
147             __PACKAGE__->set_sql(drop_table => 'DROP TABLE IF EXISTS __TABLE__');
148              
149 2     2 1 11509 sub drop_table { shift->sql_drop_table->execute }
150              
151             sub create_table {
152 0     0 1   my ($class, $schema) = @_;
153 0           $class->sql_create_table($schema)->execute;
154             }
155              
156             =head2 column_type
157              
158             my $type = $class->column_type('column_name');
159              
160             This returns the 'type' of this table (VARCHAR(20), BIGINT, etc.)
161              
162             =cut
163              
164             sub _column_info {
165 0     0     my $class = shift;
166 0           (my $sth = $class->sql_desc_table)->execute;
167 0           return { map { $_->{field} => $_ } $sth->fetchall_hash };
  0            
168             }
169              
170             sub column_type {
171 0     0 1   my $class = shift;
172 0 0         my $col = shift or die "Need a column for column_type";
173 0           return $class->_column_info->{$col}->{type};
174             }
175              
176             =head2 enum_vals
177              
178             my @allowed = $class->enum_vals('column_name');
179              
180             This returns a list of the allowable values for an ENUM column.
181              
182             =cut
183              
184             sub enum_vals {
185 0     0 1   my $class = shift;
186 0 0         my $col = shift or die "Need a column for enum_vals";
187 0           my $series = $class->_column_info->{$col}->{type};
188 0 0         $series =~ /enum\((.*?)\)/ or die "$col is not an ENUM column";
189 0           (my $enum = $1) =~ s/'//g;
190 0           return split /,/, $enum;
191             }
192              
193             =head2 retrieve_random
194              
195             my $film = Film->retrieve_random;
196              
197             This will select a random row from the database, and return you
198             the relevant object.
199              
200             (MySQL 3.23 and higher only, at this point)
201              
202             =cut
203              
204             __PACKAGE__->add_constructor(_retrieve_random => '1 ORDER BY RAND() LIMIT 1');
205              
206 0     0 1   sub retrieve_random { shift->_retrieve_random->first }
207              
208             =head1 SEE ALSO
209              
210             L. MySQL (http://www.mysql.com/)
211              
212             =head1 AUTHOR
213              
214             Tony Bowden
215              
216             =head1 BUGS and QUERIES
217              
218             Please direct all correspondence regarding this module to:
219             bug-Class-DBI-mysql@rt.cpan.org
220              
221             =head1 COPYRIGHT AND LICENSE
222              
223             Copyright (C) 2001-2005 Tony Bowden.
224              
225             This program is free software; you can redistribute it and/or modify it under
226             the terms of the GNU General Public License; either version 2 of the License,
227             or (at your option) any later version.
228              
229             This program is distributed in the hope that it will be useful, but WITHOUT
230             ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
231             FOR A PARTICULAR PURPOSE.
232              
233             =cut
234              
235             1;