added test for rescan, fixed a few issues
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader.pm
1 package DBIx::Class::Schema::Loader;
2
3 use strict;
4 use warnings;
5 use base qw/DBIx::Class::Schema/;
6 use base qw/Class::Data::Accessor/;
7 use Carp::Clan qw/^DBIx::Class/;
8 use UNIVERSAL::require;
9 use Class::C3;
10 use Scalar::Util qw/ weaken /;
11
12 # Always remember to do all digits for the version even if they're 0
13 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
14 # brain damage and presumably various other packaging systems too
15 our $VERSION = '0.03999_01';
16
17 __PACKAGE__->mk_classaccessor('_loader_args' => {});
18 __PACKAGE__->mk_classaccessors(qw/dump_to_dir _loader_invoked _loader/);
19
20 =head1 NAME
21
22 DBIx::Class::Schema::Loader - Dynamic definition of a DBIx::Class::Schema
23
24 =head1 SYNOPSIS
25
26   package My::Schema;
27   use base qw/DBIx::Class::Schema::Loader/;
28
29   __PACKAGE__->loader_options(
30       constraint              => '^foo.*',
31       # debug                 => 1,
32   );
33
34   # in seperate application code ...
35
36   use My::Schema;
37
38   my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs);
39   # -or-
40   my $schema1 = "My::Schema"; $schema1->connection(as above);
41
42 =head1 DESCRIPTION 
43
44 DBIx::Class::Schema::Loader automates the definition of a
45 L<DBIx::Class::Schema> by scanning database table definitions and
46 setting up the columns, primary keys, and relationships.
47
48 DBIx::Class::Schema::Loader currently supports only the DBI storage type.
49 It has explicit support for L<DBD::Pg>, L<DBD::mysql>, L<DBD::DB2>, and
50 L<DBD::SQLite>.  Other DBI drivers may function to a greater or lesser
51 degree with this loader, depending on how much of the DBI spec they
52 implement, and how standard their implementation is.  Patches to make
53 other DBDs work correctly welcome.
54
55 See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing
56 your own vendor-specific subclass for an unsupported DBD driver.
57
58 This module requires L<DBIx::Class> 0.06 or later, and obsoletes
59 the older L<DBIx::Class::Loader>.
60
61 This module is designed more to get you up and running quickly against
62 an existing database, or to be effective for simple situations, rather
63 than to be what you use in the long term for a complex database/project.
64
65 That being said, transitioning your code from a Schema generated by this
66 module to one that doesn't use this module should be straightforward and
67 painless, so don't shy away from it just for fears of the transition down
68 the road.
69
70 =head1 METHODS
71
72 =head2 loader_options
73
74 Example in Synopsis above demonstrates a few common arguments.  For
75 detailed information on all of the arguments, most of which are
76 only useful in fairly complex scenarios, see the
77 L<DBIx::Class::Schema::Loader::Base> documentation.
78
79 One must call C<loader_options> before any connection is made,
80 or embed the C<loader_options> in the connection information itself
81 as shown below.  Setting C<loader_options> after the connection has
82 already been made is useless.
83
84 =cut
85
86 sub loader_options {
87     my $self = shift;
88     
89     my %args = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
90     $self->_loader_args(\%args);
91
92     $self;
93 }
94
95 sub _invoke_loader {
96     my $self = shift;
97     my $class = ref $self || $self;
98
99     my $args = $self->_loader_args;
100
101     # set up the schema/schema_class arguments
102     $args->{schema} = $self;
103     $args->{schema_class} = $class;
104     weaken($args->{schema}) if ref $self;
105     $args->{dump_directory} ||= $self->dump_to_dir;
106
107     # XXX this only works for relative storage_type, like ::DBI ...
108     my $impl = "DBIx::Class::Schema::Loader" . $self->storage_type;
109     $impl->require or
110       croak qq/Could not load storage_type loader "$impl": / .
111             qq/"$UNIVERSAL::require::ERROR"/;
112
113     $self->_loader($impl->new(%$args));
114     $self->_loader->load;
115     $self->_loader_invoked(1);
116
117     $self;
118 }
119
120 =head2 connection
121
122 See L<DBIx::Class::Schema> for basic usage.
123
124 If the final argument is a hashref, and it contains a key C<loader_options>,
125 that key will be deleted, and its value will be used for the loader options,
126 just as if set via the L</loader_options> method above.
127
128 The actual auto-loading operation (the heart of this module) will be invoked
129 as soon as the connection information is defined.
130
131 =cut
132
133 sub connection {
134     my $self = shift;
135
136     if($_[-1] && ref $_[-1] eq 'HASH') {
137         if(my $loader_opts = delete $_[-1]->{loader_options}) {
138             $self->loader_options($loader_opts);
139             pop @_ if !keys %{$_[-1]};
140         }
141     }
142
143     $self = $self->next::method(@_);
144
145     my $class = ref $self || $self;
146     if(!$class->_loader_invoked) {
147         $self->_invoke_loader
148     }
149
150     return $self;
151 }
152
153 =head2 clone
154
155 See L<DBIx::Class::Schema>.
156
157 =cut
158
159 sub clone {
160     my $self = shift;
161
162     my $clone = $self->next::method(@_);
163
164     if($clone->_loader_args) {
165         $clone->_loader_args->{schema} = $clone;
166         weaken($clone->_loader_args->{schema});
167     }
168
169     $clone;
170 }
171
172 =head2 dump_to_dir
173
174 Argument: directory name.
175
176 Calling this as a class method on either L<DBIx::Class::Schema::Loader>
177 or any derived schema class will cause all affected schemas to dump
178 manual versions of themselves to the named directory when they are
179 loaded.  In order to be effective, this must be set before defining a
180 connection on this schema class or any derived object (as the loading
181 happens as soon as both a connection and loader_options are set, and
182 only once per class).
183
184 See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more
185 details on the dumping mechanism.
186
187 This can also be set at module import time via the import option
188 C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where
189 C</foo/bar> is the target directory.
190
191 Examples:
192
193     # My::Schema isa DBIx::Class::Schema::Loader, and has connection info
194     #   hardcoded in the class itself:
195     perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1
196
197     # Same, but no hard-coded connection, so we must provide one:
198     perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)'
199
200     # Or as a class method, as long as you get it done *before* defining a
201     #  connection on this schema class or any derived object:
202     use My::Schema;
203     My::Schema->dump_to_dir('/foo/bar');
204     My::Schema->connection(........);
205
206     # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all
207     #   derived schemas
208     use My::Schema;
209     use My::OtherSchema;
210     DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar');
211     My::Schema->connection(.......);
212     My::OtherSchema->connection(.......);
213
214     # Another alternative to the above:
215     use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |;
216     use My::Schema;
217     use My::OtherSchema;
218     My::Schema->connection(.......);
219     My::OtherSchema->connection(.......);
220
221 =cut
222
223 sub import {
224     my $self = shift;
225     return if !@_;
226     foreach my $opt (@_) {
227         if($opt =~ m{^dump_to_dir:(.*)$}) {
228             $self->dump_to_dir($1)
229         }
230         elsif($opt eq 'make_schema_at') {
231             no strict 'refs';
232             my $cpkg = (caller)[0];
233             *{"${cpkg}::make_schema_at"} = \&make_schema_at;
234         }
235     }
236 }
237
238 =head2 make_schema_at
239
240 This simple function allows one to create a Loader-based schema
241 in-memory on the fly without any on-disk class files of any
242 kind.  When used with the C<dump_directory> option, you can
243 use this to generate a rough draft manual schema from a dsn
244 without the intermediate step of creating a physical Loader-based
245 schema class.
246
247 The return value is the input class name.
248
249 This function can be exported/imported by the normal means, as
250 illustrated in these Examples:
251
252     # Simple example, creates as a new class 'New::Schema::Name' in
253     #  memory in the running perl interpreter.
254     use DBIx::Class::Schema::Loader qw/ make_schema_at /;
255     make_schema_at(
256         'New::Schema::Name',
257         { debug => 1 },
258         [ 'dbi:Pg:dbname="foo"','postgres' ],
259     );
260
261     # Complex: dump loaded schema to disk, all from the commandline:
262     perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("New::Schema::Name", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
263
264     # Same, but inside a script, and using a different way to specify the
265     # dump directory:
266     use DBIx::Class::Schema::Loader qw/ make_schema_at /;
267     make_schema_at(
268         'New::Schema::Name',
269         { debug => 1, dump_directory => './lib' },
270         [ 'dbi:Pg:dbname="foo"','postgres' ],
271     );
272
273 =cut
274
275 sub make_schema_at {
276     my ($target, $opts, $connect_info) = @_;
277
278     {
279         no strict 'refs';
280         @{$target . '::ISA'} = qw/DBIx::Class::Schema::Loader/;
281     }
282
283     $target->loader_options($opts);
284     $target->connection(@$connect_info);
285 }
286
287 =head2 rescan
288
289 Re-scans the database for newly added tables since the initial
290 load, and adds them to the schema at runtime, including relationships,
291 etc.  Does not process drops or changes.
292
293 Returns a list of the new monikers added.
294
295 =cut
296
297 sub rescan { my $self = shift; $self->_loader->rescan($self) }
298
299 =head1 EXAMPLE
300
301 Using the example in L<DBIx::Class::Manual::ExampleSchema> as a basis
302 replace the DB::Main with the following code:
303
304   package DB::Main;
305
306   use base qw/DBIx::Class::Schema::Loader/;
307
308   __PACKAGE__->loader_options(
309       debug         => 1,
310   );
311   __PACKAGE__->connection('dbi:SQLite:example.db');
312
313   1;
314
315 and remove the Main directory tree (optional).  Every thing else
316 should work the same
317
318 =head1 KNOWN ISSUES
319
320 =head2 Multiple Database Schemas
321
322 Currently the loader is limited to working within a single schema
323 (using the database vendors' definition of "schema").  If you
324 have a multi-schema database with inter-schema relationships (which
325 is easy to do in PostgreSQL or DB2 for instance), you only get to
326 automatically load the tables of one schema, and any relationships
327 to tables in other schemas will be silently ignored.
328
329 At some point in the future, an intelligent way around this might be
330 devised, probably by allowing the C<db_schema> option to be an
331 arrayref of schemas to load.
332
333 In "normal" L<DBIx::Class::Schema> usage, manually-defined
334 source classes and relationships have no problems crossing vendor schemas.
335
336 =head1 AUTHOR
337
338 Brandon Black, C<blblack@gmail.com>
339
340 Based on L<DBIx::Class::Loader> by Sebastian Riedel
341
342 Based upon the work of IKEBE Tomohiro
343
344 =head1 THANK YOU
345
346 Matt S Trout, all of the #dbix-class folks, and everyone who's ever sent
347 in a bug report or suggestion.
348
349 =head1 LICENSE
350
351 This library is free software; you can redistribute it and/or modify it under
352 the same terms as Perl itself.
353
354 =head1 SEE ALSO
355
356 L<DBIx::Class>, L<DBIx::Class::Manual::ExampleSchema>
357
358 =cut
359
360 1;