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