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