File Coverage

blib/lib/Class/DBI/AutoLoader.pm
Criterion Covered Total %
statement 9 41 21.9
branch 0 8 0.0
condition n/a
subroutine 3 6 50.0
pod 0 2 0.0
total 12 57 21.0


line stmt bran cond sub pod time code
1             package Class::DBI::AutoLoader;
2              
3 1     1   624 use strict;
  1         2  
  1         33  
4 1     1   6 use warnings;
  1         3  
  1         31  
5 1     1   2242 use DBI;
  1         21215  
  1         553  
6              
7             our $VERSION = '0.12';
8              
9             sub import {
10 0     0     my $self = shift;
11 0           my $args = { @_ };
12            
13             # Fetch the driver
14 0           my ($driver) = $args->{dsn} =~ m|^dbi:(.*?):.*$|;
15              
16             # Get the tables
17 0           my @tables = ();
18 0 0         if(defined $args->{tables}) {
19 0           @tables = @{ $args->{tables} };
  0            
20             }
21             else {
22 0 0         my $dbh = DBI->connect($args->{dsn},$args->{username},$args->{password})
23             or die "Couldn't establish connection to database via $args->{dsn}: $DBI::errstr";
24 0           @tables = $dbh->tables();
25 0           $dbh->disconnect;
26             }
27            
28             # Generate the classes
29 0           foreach my $table (@tables) {
30 0           generateClass($table,$driver,$args);
31             }
32             }
33              
34             sub table2class {
35 0     0 0   my ($table) = @_;
36            
37 0           $table = ucfirst($table);
38 0           $table = join('', map { ucfirst($_) } split(/[^a-zA-Z0-9]/, $table));
  0            
39            
40 0           return $table;
41             }
42              
43             sub generateClass {
44 0     0 0   my($table,$driver,$args) = @_;
45 0           my $package = $args->{namespace} . '::' . table2class($table);
46            
47 0           my $class = "package $package;"
48             . "use strict;"
49             . "use vars '\@ISA';";
50              
51             # Determine the base class
52 0 0         if(defined $args->{use_base}) {
53 0           $class .= "use base '$args->{use_base}';";
54             }
55             else {
56 0           $class .= "use base 'Class::DBI::BaseDSN';";
57             }
58              
59             # Add any additional requested packages
60 0           foreach my $add_pkg (@{ $args->{additional_packages} }) {
  0            
61 0           $class .= "use $add_pkg;";
62             }
63              
64             # Finish it off
65 0           $class .= '1;';
66 0           eval($class);
67 0 0         if(my $error = $@) {
68 0           warn "An error occurred generating $package: $error";
69             }
70              
71             # Setup the rest of the good stuff
72 0           $package->set_db('Main' => $args->{dsn}, $args->{username}, $args->{password}, $args->{options});
73 0           $package->set_up_table($table);
74             }
75              
76             1;
77              
78             =head1 NAME
79              
80             Class::DBI::AutoLoader - Generates Class::DBI subclasses dynamically.
81              
82             =head1 SYNOPSIS
83              
84             use Class::DBI::AutoLoader (
85             dsn => 'dbi:mysql:database',
86             username => 'username',
87             password => 'passw0rd',
88             options => { RaiseError => 1 },
89             tables => ['favorite_films','directors']
90             namespace => 'Films'
91             );
92            
93             my $film = Films::FavoriteFilms->retrieve(1);
94             my $dir = Films::Directors( film => $film->id() );
95              
96             =head1 DESCRIPTION
97              
98             Class::DBI::AutoLoader scans the tables in a given database,
99             and auto-generates the Class::DBI classes. These are loaded into
100             your package when you import Class::DBI::AutoLoader, as though
101             you had created the Data::FavoriteFilms class and "use"d that
102             directly.
103              
104             =head1 NOTE
105              
106             Class::DBI::AutoLoader messes with your table names to make them
107             look more like regular class names. Specifically it turns table_name
108             into TableName. The actual function is just:
109              
110             $table = join('', map { ucfirst($_) } split(/[^a-zA-Z0-9]/, $table));
111              
112             =head1 WARNING
113              
114             I haven't tested this with any database but MySQL. Let me know if you
115             use it with PostgreSQL or SQLite. Success or failure.
116              
117             =head1 OPTIONS
118              
119             Options that can be used in the import:
120              
121             =over 4
122              
123             =item * dsn
124              
125             The standard DBI style DSN that you always pass.
126              
127             =item * username
128              
129             The username for the database.
130              
131             =item * password
132              
133             The password for the database.
134              
135             =item * options
136              
137             A hashref of options such as you'd pass to the DBI->connect() method.
138             This can contain any option that is valid for your database.
139              
140             =item * tables
141              
142             An array reference of table names to load. If you leave this option
143             out, all tables in the database will be loaded.
144              
145             =item * namespace
146              
147             The master namespace you would like your packages declared in. See the
148             example above.
149              
150             =item * use_base
151              
152             If you don't specify a base class, then L will be used.
153             This module does explicitly use the method 'set_up_table' from the
154             L, L, and L
155             series of modules. Unless you have a module that supports, or subclasses, these
156             than you won't want to use this.
157              
158             =item * additional_packages
159              
160             An array reference of additional packages you would like each class to "use".
161             For example:
162              
163             use Class::DBI::AutoLoader (
164             ...
165             additional_packages => ['Class::DBI::AbstractSearch']
166             );
167              
168             This allows you to use Class::DBI plugins or other assorted goodies in the
169             generated class.
170              
171             =back
172              
173             =head1 SUPPORTED DATABASES
174              
175             Currently this module supports MySQL, PostgreSQL, and SQLite via
176             L, L, and L.
177              
178             =head1 TIPS AND TRICKS
179              
180             =head2 USE ADDITIONAL_PACKAGES
181              
182             Class::DBI::AbstractSearch is extremely useful for doing any kind of complex
183             query. Use it like this:
184              
185             use Class::DBI::AutoLoader (
186             ...
187             additional_packages => ['Class::DBI::AbstractSearch']
188             );
189            
190             my @records = MyDBI::Table->search_where( fname => ['me','you','another'] );
191              
192             Please see L for full details
193              
194             =head2 USE IN MOD_PERL
195              
196             Put your use Class::DBI::AutoLoader(...) call in your startup.pl file. Then
197             all your mod_perl packages can use the generated classes directly.
198              
199             =head2 USE IN CGIs
200              
201             If you don't use the C option and you don't need all of the tables
202             in the database, you're going to take an unneccessary penalty.
203              
204             =head2 WRAP IT IN A SUBCLASS
205              
206             You probably want to wrap this in a subclass so you don't have to go through
207             all of the dsn, user, blah blah everytime you use it. Additionally, you can
208             put any __PACKAGE__->set_sql(...) type stuff in your subclass. That's helpful
209             since you can't edit the generated classes.
210              
211             =head2 USING A SUBCLASS FOR CGIs
212              
213             package My::DBI::ForCGI;
214            
215             sub import {
216             my ($self,@tables) = @_;
217             require Class::DBI::AutoLoader;
218             Class::DBI::AutoLoader->import(
219             dsn => 'dbi:mysql:application',
220             username => 'joe',
221             password => 'friday',
222             options => { RaiseError => 1 },
223             tables => \@tables,
224             namespace => 'My::DBI::ForCGI'
225             );
226             }
227             1;
228              
229             Then in your CGI:
230              
231             use strict;
232             use CGI;
233             use My::DBI::ForCGI ( tables => 'users' );
234              
235             my $cgi = CGI->new();
236             my $user = My::DBI::ForCGI::Users->retrieve( $cgi->param('user_id') );
237             ...
238              
239             Since your classes are scanned and generated, you will always take some
240             performance hit, especially when used in non-persistant environments like
241             a CGI application. Use C liberally.
242            
243             =head1 SEE ALSO
244              
245             L, L, L, L
246              
247             =head1 AUTHOR
248              
249             Ryan Parr, Eryanparr@thejamescompany.comE
250              
251             This software is based off the original work performed by
252             Ikebe Tomohiro on the Class::DBI::Loader module.
253              
254             =head1 THANKS
255              
256             To Casey West for helping to hash-out what makes this module useful.
257             To Mike Castle for submitting the first patch :)
258              
259             =head1 COPYRIGHT AND LICENSE
260              
261             This library is free software; you can redistribute it and/or modify
262             it under the same terms as Perl itself.
263              
264             =cut