forgotten commit of final 0.03008 changes
[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.03008';
16
17 __PACKAGE__->mk_classaccessor('dump_to_dir');
18 __PACKAGE__->mk_classaccessor('loader');
19 __PACKAGE__->mk_classaccessor('_loader_args');
20
21 =head1 NAME
22
23 DBIx::Class::Schema::Loader - Dynamic definition of a DBIx::Class::Schema
24
25 =head1 SYNOPSIS
26
27   package My::Schema;
28   use base qw/DBIx::Class::Schema::Loader/;
29
30   __PACKAGE__->loader_options(
31       relationships           => 1,
32       constraint              => '^foo.*',
33       # debug                 => 1,
34   );
35
36   # in seperate application code ...
37
38   use My::Schema;
39
40   my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs);
41   # -or-
42   my $schema1 = "My::Schema"; $schema1->connection(as above);
43
44 =head1 DESCRIPTION 
45
46 DBIx::Class::Schema::Loader automates the definition of a
47 L<DBIx::Class::Schema> by scanning database table definitions and
48 setting up the columns, primary keys, and relationships.
49
50 DBIx::Class::Schema::Loader currently supports only the DBI storage type.
51 It has explicit support for L<DBD::Pg>, L<DBD::mysql>, L<DBD::DB2>, and
52 L<DBD::SQLite>.  Other DBI drivers may function to a greater or lesser
53 degree with this loader, depending on how much of the DBI spec they
54 implement, and how standard their implementation is.  Patches to make
55 other DBDs work correctly welcome.
56
57 See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing
58 your own vendor-specific subclass for an unsupported DBD driver.
59
60 This module requires L<DBIx::Class> 0.06 or later, and obsoletes
61 the older L<DBIx::Class::Loader>.
62
63 This module is designed more to get you up and running quickly against
64 an existing database, or to be effective for simple situations, rather
65 than to be what you use in the long term for a complex database/project.
66
67 That being said, transitioning your code from a Schema generated by this
68 module to one that doesn't use this module should be straightforward and
69 painless (as long as you're not using any methods that are now deprecated
70 in this document), so don't shy away from it just for fears of the
71 transition down the road.
72
73 =head1 METHODS
74
75 =head2 loader_options
76
77 Example in Synopsis above demonstrates a few common arguments.  For
78 detailed information on all of the arguments, most of which are
79 only useful in fairly complex scenarios, see the
80 L<DBIx::Class::Schema::Loader::Base> documentation.
81
82 This method is *required* at this time, for backwards compatibility
83 reasons.  If you do not wish to change any options, just call it
84 with an empty argument list during schema class initialization.
85
86 Setting these options explicitly via this method B<after> calling
87 C<connection> is deprecated and will stop working in version 0.04000.
88 For now the code merely warns about this condition.
89
90 The preferred way of doing things is to either call C<loader_options>
91 before any connection is made, or embed the C<loader_options> in
92 the connection information itself as shown below.
93
94 =cut
95
96 sub loader_options {
97     my $self = shift;
98     
99     my %args = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
100
101     my $class = ref $self || $self;
102     $args{schema} = $self;
103     $args{schema_class} = $class;
104     weaken($args{schema}) if ref $self;
105
106     $self->_loader_args(\%args);
107     if($self->storage && !$class->loader) {
108         warn "Do not set loader_options after specifying the connection info,"
109            . " this will be unsupported in 0.04000";
110         $self->_invoke_loader;
111     }
112
113     $self;
114 }
115
116 sub _invoke_loader {
117     my $self = shift;
118     my $class = ref $self || $self;
119
120     $self->_loader_args->{dump_directory} ||= $self->dump_to_dir;
121
122     # XXX this only works for relative storage_type, like ::DBI ...
123     my $impl = "DBIx::Class::Schema::Loader" . $self->storage_type;
124     $impl->require or
125       croak qq/Could not load storage_type loader "$impl": / .
126             qq/"$UNIVERSAL::require::ERROR"/;
127
128     # XXX in the future when we get rid of ->loader, the next two
129     # lines can be replaced by "$impl->new(%{$self->_loader_args})->load;"
130     $class->loader($impl->new(%{$self->_loader_args}));
131     $class->loader->load;
132
133     $self;
134 }
135
136 =head2 connection
137
138 See L<DBIx::Class::Schema> for basic usage.
139
140 If the final argument is a hashref, and it contains a key C<loader_options>,
141 that key will be deleted, and its value will be used for the loader options,
142 just as if set via the L</loader_options> method above.
143
144 The actual auto-loading operation (the heart of this module) will be invoked
145 as soon as the connection information is defined.
146
147 =cut
148
149 sub connection {
150     my $self = shift;
151
152     if($_[-1] && ref $_[-1] eq 'HASH') {
153         if(my $loader_opts = delete $_[-1]->{loader_options}) {
154             $self->loader_options($loader_opts);
155             pop @_ if !keys %{$_[-1]};
156         }
157     }
158
159     $self = $self->next::method(@_);
160
161     my $class = ref $self || $self;
162     if($self->_loader_args && !$class->loader) {
163         $self->_invoke_loader
164     }
165
166     return $self;
167 }
168
169 =head2 clone
170
171 See L<DBIx::Class::Schema>.
172
173 =cut
174
175 sub clone {
176     my $self = shift;
177
178     my $clone = $self->next::method(@_);
179
180     if($clone->_loader_args) {
181         $clone->_loader_args->{schema} = $clone;
182         weaken($clone->_loader_args->{schema});
183     }
184
185     $clone;
186 }
187
188 =head2 dump_to_dir
189
190 Argument: directory name.
191
192 Calling this as a class method on either L<DBIx::Class::Schema::Loader>
193 or any derived schema class will cause all affected schemas to dump
194 manual versions of themselves to the named directory when they are
195 loaded.  In order to be effective, this must be set before defining a
196 connection on this schema class or any derived object (as the loading
197 happens as soon as both a connection and loader_options are set, and
198 only once per class).
199
200 See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more
201 details on the dumping mechanism.
202
203 This can also be set at module import time via the import option
204 C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where
205 C</foo/bar> is the target directory.
206
207 Examples:
208
209     # My::Schema isa DBIx::Class::Schema::Loader, and has connection info
210     #   hardcoded in the class itself:
211     perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1
212
213     # Same, but no hard-coded connection, so we must provide one:
214     perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)'
215
216     # Or as a class method, as long as you get it done *before* defining a
217     #  connection on this schema class or any derived object:
218     use My::Schema;
219     My::Schema->dump_to_dir('/foo/bar');
220     My::Schema->connection(........);
221
222     # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all
223     #   derived schemas
224     use My::Schema;
225     use My::OtherSchema;
226     DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar');
227     My::Schema->connection(.......);
228     My::OtherSchema->connection(.......);
229
230     # Another alternative to the above:
231     use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |;
232     use My::Schema;
233     use My::OtherSchema;
234     My::Schema->connection(.......);
235     My::OtherSchema->connection(.......);
236
237 =cut
238
239 sub import {
240     my $self = shift;
241     return if !@_;
242     foreach my $opt (@_) {
243         if($opt =~ m{^dump_to_dir:(.*)$}) {
244             $self->dump_to_dir($1)
245         }
246         elsif($opt eq 'make_schema_at') {
247             no strict 'refs';
248             my $cpkg = (caller)[0];
249             *{"${cpkg}::make_schema_at"} = \&make_schema_at;
250         }
251     }
252 }
253
254 =head2 make_schema_at
255
256 This simple function allows one to create a Loader-based schema
257 in-memory on the fly without any on-disk class files of any
258 kind.  When used with the C<dump_directory> option, you can
259 use this to generate a rough draft manual schema from a dsn
260 without the intermediate step of creating a physical Loader-based
261 schema class.
262
263 The return value is the input class name.
264
265 This function can be exported/imported by the normal means, as
266 illustrated in these Examples:
267
268     # Simple example, creates as a new class 'New::Schema::Name' in
269     #  memory in the running perl interpreter.
270     use DBIx::Class::Schema::Loader qw/ make_schema_at /;
271     make_schema_at(
272         'New::Schema::Name',
273         { relationships => 1, debug => 1 },
274         [ 'dbi:Pg:dbname="foo"','postgres' ],
275     );
276
277     # Complex: dump loaded schema to disk, all from the commandline:
278     perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("New::Schema::Name", { relationships => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
279
280     # Same, but inside a script, and using a different way to specify the
281     # dump directory:
282     use DBIx::Class::Schema::Loader qw/ make_schema_at /;
283     make_schema_at(
284         'New::Schema::Name',
285         { relationships => 1, debug => 1, dump_directory => './lib' },
286         [ 'dbi:Pg:dbname="foo"','postgres' ],
287     );
288
289 =cut
290
291 sub make_schema_at {
292     my ($target, $opts, $connect_info) = @_;
293
294     {
295         no strict 'refs';
296         @{$target . '::ISA'} = qw/DBIx::Class::Schema::Loader/;
297     }
298
299     $target->loader_options($opts);
300     $target->connection(@$connect_info);
301 }
302
303 =head1 EXAMPLE
304
305 Using the example in L<DBIx::Class::Manual::ExampleSchema> as a basis
306 replace the DB::Main with the following code:
307
308   package DB::Main;
309
310   use base qw/DBIx::Class::Schema::Loader/;
311
312   __PACKAGE__->loader_options(
313       relationships => 1,
314       debug         => 1,
315   );
316   __PACKAGE__->connection('dbi:SQLite:example.db');
317
318   1;
319
320 and remove the Main directory tree (optional).  Every thing else
321 should work the same
322
323 =head1 DEPRECATED METHODS
324
325 You don't need to read anything in this section unless you're upgrading
326 code that was written against pre-0.03 versions of this module.  This
327 version is intended to be backwards-compatible with pre-0.03 code, but
328 will issue warnings about your usage of deprecated features/methods.
329
330 B<All of these deprecated methods will dissappear in version 0.04000>,
331 and converting code that uses these methods should be trivial.
332
333 =head2 load_from_connection
334
335 This deprecated method is now roughly an alias for L</loader_options>.
336
337 For now, using this method will invoke the legacy behavior for
338 backwards compatibility, and merely emit a warning about upgrading
339 your code.
340
341 It also reverts the default inflection scheme to
342 use L<Lingua::EN::Inflect> just like pre-0.03 versions of this
343 module did.
344
345 You can force these legacy inflections with the
346 option L<DBIx::Class::Schema::Loader::Base/legacy_default_inflections>,
347 even after switch over to the preferred L</loader_options> way of doing
348 things.  That option will not go away until at least 0.05.
349
350 See the source of this method for more details.
351
352 =cut
353
354 sub load_from_connection {
355     my ($self, %args) = @_;
356
357     my $cmds_ver = $Catalyst::Model::DBIC::Schema::VERSION;
358     if($cmds_ver) {
359         if($cmds_ver < 0.14) {
360             warn 'You should upgrade your installation of'
361                . ' Catalyst::Model::DBIC::Schema to 0.14 or higher, then:';
362         }
363         warn 'You should regenerate your Model files, which may eliminate'
364            . ' the following deprecation warning:';
365     }
366     warn 'load_from_connection deprecated, and will dissappear in 0.04000, '
367        . 'please [re-]read the [new] DBIx::Class::Schema::Loader '
368        . 'documentation';
369
370     # Support the old connect_info / dsn / etc args...
371     $args{connect_info} = [
372         delete $args{dsn},
373         delete $args{user},
374         delete $args{password},
375         delete $args{options},
376     ] if $args{dsn};
377
378     $self->connection(@{delete $args{connect_info}})
379         if $args{connect_info};
380
381     $self->loader_options('legacy_default_inflections' => 1, %args);
382 }
383
384 =head2 loader
385
386 This is an accessor in the generated Schema class for accessing
387 the L<DBIx::Class::Schema::Loader::Base> -based loader object
388 that was used during construction.  See the
389 L<DBIx::Class::Schema::Loader::Base> docs for more information
390 on the available loader methods there.
391
392 This accessor is deprecated.  Do not use it.  Anything you can
393 get from C<loader>, you can get via the normal L<DBIx::Class::Schema>
394 methods, and your code will be more robust and forward-thinking
395 for doing so.
396
397 If you're already using C<loader> in your code, make an effort
398 to get rid of it.  If you think you've found a situation where it
399 is necessary, let me know and we'll see what we can do to remedy
400 that situation.
401
402 In some future version, this accessor *will* disappear.  It was
403 apparently quite a design/API mistake to ever have exposed it to
404 user-land in the first place, all things considered.
405
406 =head1 KNOWN ISSUES
407
408 =head2 Multiple Database Schemas
409
410 Currently the loader is limited to working within a single schema
411 (using the database vendors' definition of "schema").  If you
412 have a multi-schema database with inter-schema relationships (which
413 is easy to do in PostgreSQL or DB2 for instance), you only get to
414 automatically load the tables of one schema, and any relationships
415 to tables in other schemas will be silently ignored.
416
417 At some point in the future, an intelligent way around this might be
418 devised, probably by allowing the C<db_schema> option to be an
419 arrayref of schemas to load.
420
421 In "normal" L<DBIx::Class::Schema> usage, manually-defined
422 source classes and relationships have no problems crossing vendor schemas.
423
424 =head1 AUTHOR
425
426 Brandon Black, C<blblack@gmail.com>
427
428 Based on L<DBIx::Class::Loader> by Sebastian Riedel
429
430 Based upon the work of IKEBE Tomohiro
431
432 =head1 THANK YOU
433
434 Matt S Trout, all of the #dbix-class folks, and everyone who's ever sent
435 in a bug report or suggestion.
436
437 =head1 LICENSE
438
439 This library is free software; you can redistribute it and/or modify it under
440 the same terms as Perl itself.
441
442 =head1 SEE ALSO
443
444 L<DBIx::Class>, L<DBIx::Class::Manual::ExampleSchema>
445
446 =cut
447
448 1;