use connection hack only for schema_base_class
[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;
65e705c3 5use base qw/DBIx::Class::Schema Class::Accessor::Grouped/;
cc15b78f 6use MRO::Compat;
942bd5e0 7use mro 'c3';
39d5612f 8use Carp::Clan qw/^DBIx::Class/;
9use Scalar::Util 'weaken';
cc15b78f 10use Sub::Name 'subname';
39d5612f 11use namespace::clean;
3980d69c 12
a4a19f3c 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
4295c4b4 16our $VERSION = '0.07010';
457eb8a6 17
65e705c3 18__PACKAGE__->mk_group_accessors('inherited', qw/
19 _loader_args
20 dump_to_dir
21 _loader_invoked
22 _loader
23 loader_class
24 naming
f22644d7 25 use_namespaces
a8d229ff 26/);
65e705c3 27__PACKAGE__->_loader_args({});
a78e3fed 28
29=head1 NAME
30
227cea92 31DBIx::Class::Schema::Loader - Create a DBIx::Class::Schema based on a database
a78e3fed 32
33=head1 SYNOPSIS
34
707fb247 35 ### use this module to generate a set of class files
36
37 # in a script
38 use DBIx::Class::Schema::Loader qw/ make_schema_at /;
39 make_schema_at(
40 'My::Schema',
41 { debug => 1,
42 dump_directory => './lib',
43 },
35a87f06 44 [ 'dbi:Pg:dbname="foo"', 'myuser', 'mypassword',
45 { loader_class => 'MyLoader' } # optionally
46 ],
707fb247 47 );
48
49 # from the command line or a shell script with dbicdump (distributed
50 # with this module). Do `perldoc dbicdump` for usage.
51 dbicdump -o dump_directory=./lib \
227cea92 52 -o components='["InflateColumn::DateTime"]' \
707fb247 53 -o debug=1 \
54 My::Schema \
55 'dbi:Pg:dbname=foo' \
56 myuser \
57 mypassword
58
59 ### or generate and load classes at runtime
60 # note: this technique is not recommended
61 # for use in production code
62
a4a19f3c 63 package My::Schema;
64 use base qw/DBIx::Class::Schema::Loader/;
a78e3fed 65
996be9ee 66 __PACKAGE__->loader_options(
996be9ee 67 constraint => '^foo.*',
68 # debug => 1,
a78e3fed 69 );
af6c2665 70
707fb247 71 #### in application code elsewhere:
a78e3fed 72
a4a19f3c 73 use My::Schema;
a78e3fed 74
a4a19f3c 75 my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs);
76 # -or-
996be9ee 77 my $schema1 = "My::Schema"; $schema1->connection(as above);
074e81cd 78
996be9ee 79=head1 DESCRIPTION
074e81cd 80
fbd83464 81DBIx::Class::Schema::Loader automates the definition of a
227cea92 82L<DBIx::Class::Schema> by scanning database table definitions and setting up
83the columns, primary keys, unique constraints and relationships.
a78e3fed 84
700658a5 85See L<dbicdump> for the C<dbicdump> utility.
86
227cea92 87DBIx::Class::Schema::Loader currently supports only the DBI storage type. It
1065db64 88has explicit support for L<DBD::Pg>, L<DBD::mysql>, L<DBD::DB2>,
227cea92 89L<DBD::Firebird>, L<DBD::InterBase>, L<DBD::Informix>, L<DBD::SQLAnywhere>,
6b0e47fc 90L<DBD::SQLite>, L<DBD::Sybase> (for Sybase ASE and MSSSQL), L<DBD::ODBC> (for
227cea92 91MSSQL, MSAccess, Firebird and SQL Anywhere) L<DBD::ADO> (for MSSQL and
92MSAccess) and L<DBD::Oracle>. Other DBI drivers may function to a greater or
6b0e47fc 93lesser degree with this loader, depending on how much of the DBI spec they
94implement, and how standard their implementation is.
3fe9c5d9 95
96Patches to make other DBDs work correctly welcome.
a78e3fed 97
996be9ee 98See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing
99your own vendor-specific subclass for an unsupported DBD driver.
a78e3fed 100
227cea92 101This module requires L<DBIx::Class> 0.08127 or later, and obsoletes the older
102L<DBIx::Class::Loader>.
89ecd854 103
227cea92 104See L<DBIx::Class::Schema::Loader::Base> for available options.
89ecd854 105
a78e3fed 106=head1 METHODS
107
39d5612f 108=head2 loader
109
227cea92 110The loader object, as class data on your Schema. For methods available see
111L<DBIx::Class::Schema::Loader::Base> and L<DBIx::Class::Schema::Loader::DBI>.
39d5612f 112
113=cut
114
115sub loader {
116 my $self = shift;
117 $self->_loader(@_);
118}
119
29ddb54c 120=head2 loader_class
121
530e0bf6 122=over 4
123
124=item Argument: $loader_class
125
126=back
127
29ddb54c 128Set the loader class to be instantiated when L</connection> is called.
129If the classname starts with "::", "DBIx::Class::Schema::Loader" is
130prepended. Defaults to L<DBIx::Class::Schema/storage_type> (which must
131start with "::" when using L<DBIx::Class::Schema::Loader>).
132
133This is mostly useful for subclassing existing loaders or in conjunction
134with L</dump_to_dir>.
135
996be9ee 136=head2 loader_options
a78e3fed 137
530e0bf6 138=over 4
139
140=item Argument: \%loader_options
141
142=back
143
996be9ee 144Example in Synopsis above demonstrates a few common arguments. For
145detailed information on all of the arguments, most of which are
146only useful in fairly complex scenarios, see the
147L<DBIx::Class::Schema::Loader::Base> documentation.
a78e3fed 148
3fe9c5d9 149If you intend to use C<loader_options>, you must call
150C<loader_options> before any connection is made, or embed the
151C<loader_options> in the connection information itself as shown
152below. Setting C<loader_options> after the connection has
59cfa251 153already been made is useless.
a78e3fed 154
996be9ee 155=cut
1031d4f6 156
996be9ee 157sub loader_options {
158 my $self = shift;
65e705c3 159
d65cda9e 160 my %args = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
996be9ee 161 $self->_loader_args(\%args);
996be9ee 162
163 $self;
164}
165
166sub _invoke_loader {
167 my $self = shift;
168 my $class = ref $self || $self;
169
59cfa251 170 my $args = $self->_loader_args;
171
172 # set up the schema/schema_class arguments
173 $args->{schema} = $self;
174 $args->{schema_class} = $class;
175 weaken($args->{schema}) if ref $self;
176 $args->{dump_directory} ||= $self->dump_to_dir;
a0e0a56a 177 $args->{naming} = $self->naming if $self->naming;
42ea7b88 178 $args->{use_namespaces} = $self->use_namespaces if defined $self->use_namespaces;
af6c2665 179
996be9ee 180 # XXX this only works for relative storage_type, like ::DBI ...
71a6e88a 181 my $loader_class = $self->loader_class;
182 if ($loader_class) {
183 $loader_class = "DBIx::Class::Schema::Loader${loader_class}" if $loader_class =~ /^::/;
184 $args->{loader_class} = $loader_class;
185 };
186
187 my $impl = $loader_class || "DBIx::Class::Schema::Loader" . $self->storage_type;
6ae3f335 188 eval { $self->ensure_class_loaded($impl) };
517a30e2 189 croak qq/Could not load loader_class "$impl": "$@"/ if $@;
af6c2665 190
39d5612f 191 $self->loader($impl->new(%$args));
192 $self->loader->load;
59cfa251 193 $self->_loader_invoked(1);
996be9ee 194
996be9ee 195 $self;
196}
197
198=head2 connection
199
530e0bf6 200=over 4
201
202=item Arguments: @args
203
204=item Return Value: $new_schema
205
206=back
207
208See L<DBIx::Class::Schema/connection> for basic usage.
d65cda9e 209
29ddb54c 210If the final argument is a hashref, and it contains the keys C<loader_options>
211or C<loader_class>, those keys will be deleted, and their values value will be
212used for the loader options or class, respectively, just as if set via the
213L</loader_options> or L</loader_class> methods above.
d65cda9e 214
215The actual auto-loading operation (the heart of this module) will be invoked
216as soon as the connection information is defined.
996be9ee 217
218=cut
219
220sub connection {
d65cda9e 221 my $self = shift;
222
223 if($_[-1] && ref $_[-1] eq 'HASH') {
cc15b78f 224 for my $option (qw/loader_class loader_options/) {
29ddb54c 225 if(my $value = delete $_[-1]->{$option}) {
226 $self->$option($value);
227 }
d65cda9e 228 }
29ddb54c 229 pop @_ if !keys %{$_[-1]};
d65cda9e 230 }
231
cc15b78f 232 # Make sure we inherit from schema_base_class and load schema_components
233 # before connecting.
234 require DBIx::Class::Schema::Loader::Base;
235 my $temp_loader = DBIx::Class::Schema::Loader::Base->new(
236 %{ $self->_loader_args }
237 );
238
239 if ($temp_loader->schema_base_class || $temp_loader->schema_components) {
240 my @components = @{ $temp_loader->schema_components }
241 if $temp_loader->schema_components;
242
243 push @components, ('+'.$temp_loader->schema_base_class)
244 if $temp_loader->schema_base_class;
245
246 $self->load_components(@components);
cc15b78f 247
a1781f7f 248 # This hack is necessary because we changed @ISA of $self through
249 # ->load_components.
cc15b78f 250 no warnings 'redefine';
251
252 local *connection = subname __PACKAGE__.'::connection' => sub {
253 my $self = shift;
254 $self->next::method(@_);
255 };
256
257 $self = $self->connection(@_);
258 }
a1781f7f 259 else {
260 $self = $self->next::method(@_);
261 }
996be9ee 262
263 my $class = ref $self || $self;
59cfa251 264 if(!$class->_loader_invoked) {
fa994d3c 265 $self->_invoke_loader
266 }
996be9ee 267
268 return $self;
269}
270
271=head2 clone
272
530e0bf6 273See L<DBIx::Class::Schema/clone>.
996be9ee 274
275=cut
276
277sub clone {
278 my $self = shift;
279
280 my $clone = $self->next::method(@_);
281
fa994d3c 282 if($clone->_loader_args) {
283 $clone->_loader_args->{schema} = $clone;
284 weaken($clone->_loader_args->{schema});
285 }
996be9ee 286
287 $clone;
288}
289
290=head2 dump_to_dir
291
530e0bf6 292=over 4
293
294=item Argument: $directory
295
296=back
996be9ee 297
298Calling this as a class method on either L<DBIx::Class::Schema::Loader>
707fb247 299or any derived schema class will cause all schemas to dump
996be9ee 300manual versions of themselves to the named directory when they are
301loaded. In order to be effective, this must be set before defining a
302connection on this schema class or any derived object (as the loading
074e81cd 303happens as soon as both a connection and loader_options are set, and
304only once per class).
996be9ee 305
306See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more
307details on the dumping mechanism.
308
309This can also be set at module import time via the import option
310C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where
311C</foo/bar> is the target directory.
312
313Examples:
314
315 # My::Schema isa DBIx::Class::Schema::Loader, and has connection info
316 # hardcoded in the class itself:
317 perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1
318
319 # Same, but no hard-coded connection, so we must provide one:
320 perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)'
321
322 # Or as a class method, as long as you get it done *before* defining a
323 # connection on this schema class or any derived object:
324 use My::Schema;
325 My::Schema->dump_to_dir('/foo/bar');
326 My::Schema->connection(........);
327
328 # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all
329 # derived schemas
330 use My::Schema;
331 use My::OtherSchema;
332 DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar');
333 My::Schema->connection(.......);
334 My::OtherSchema->connection(.......);
335
336 # Another alternative to the above:
337 use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |;
338 use My::Schema;
339 use My::OtherSchema;
340 My::Schema->connection(.......);
341 My::OtherSchema->connection(.......);
342
343=cut
344
345sub import {
346 my $self = shift;
a8d229ff 347
996be9ee 348 return if !@_;
a8d229ff 349
350 my $cpkg = (caller)[0];
351
996be9ee 352 foreach my $opt (@_) {
353 if($opt =~ m{^dump_to_dir:(.*)$}) {
354 $self->dump_to_dir($1)
355 }
356 elsif($opt eq 'make_schema_at') {
357 no strict 'refs';
996be9ee 358 *{"${cpkg}::make_schema_at"} = \&make_schema_at;
359 }
a8d229ff 360 elsif($opt eq 'naming') {
361 no strict 'refs';
362 *{"${cpkg}::naming"} = sub { $self->naming(@_) };
363 }
f22644d7 364 elsif($opt eq 'use_namespaces') {
365 no strict 'refs';
366 *{"${cpkg}::use_namespaces"} = sub { $self->use_namespaces(@_) };
367 }
996be9ee 368 }
369}
370
371=head2 make_schema_at
372
530e0bf6 373=over 4
374
707fb247 375=item Arguments: $schema_class_name, \%loader_options, \@connect_info
530e0bf6 376
707fb247 377=item Return Value: $schema_class_name
530e0bf6 378
379=back
380
707fb247 381This function creates a DBIx::Class schema from an existing RDBMS
382schema. With the C<dump_directory> option, generates a set of
383DBIx::Class classes from an existing database schema read from the
384given dsn. Without a C<dump_directory>, creates schema classes in
385memory at runtime without generating on-disk class files.
996be9ee 386
707fb247 387For a complete list of supported loader_options, see
388L<DBIx::Class::Schema::Loader::Base>
483987b9 389
35a87f06 390The last hashref in the C<\@connect_info> can specify the L</loader_class>.
391
707fb247 392This function can be imported in the usual way, as illustrated in
393these Examples:
996be9ee 394
5223f24a 395 # Simple example, creates as a new class 'New::Schema::Name' in
396 # memory in the running perl interpreter.
996be9ee 397 use DBIx::Class::Schema::Loader qw/ make_schema_at /;
398 make_schema_at(
399 'New::Schema::Name',
59cfa251 400 { debug => 1 },
35a87f06 401 [ 'dbi:Pg:dbname="foo"','postgres','',
402 { loader_class => 'MyLoader' } # optionally
403 ],
996be9ee 404 );
405
707fb247 406 # Inside a script, specifying a dump directory in which to write
407 # class files
996be9ee 408 use DBIx::Class::Schema::Loader qw/ make_schema_at /;
409 make_schema_at(
410 'New::Schema::Name',
59cfa251 411 { debug => 1, dump_directory => './lib' },
35a87f06 412 [ 'dbi:Pg:dbname="foo"','postgres','',
413 { loader_class => 'MyLoader' } # optionally
414 ],
996be9ee 415 );
416
b486b265 417The last hashref in the C<\@connect_info> is checked for loader arguments such
418as C<loader_options> and C<loader_class>, see L</connection> for more details.
419
996be9ee 420=cut
421
422sub make_schema_at {
423 my ($target, $opts, $connect_info) = @_;
424
483987b9 425 {
426 no strict 'refs';
427 @{$target . '::ISA'} = qw/DBIx::Class::Schema::Loader/;
428 }
429
71a6e88a 430 eval { $target->_loader_invoked(0) };
431
483987b9 432 $target->loader_options($opts);
433 $target->connection(@$connect_info);
996be9ee 434}
435
b97c2c1e 436=head2 rescan
437
530e0bf6 438=over 4
439
440=item Return Value: @new_monikers
441
442=back
443
b97c2c1e 444Re-scans the database for newly added tables since the initial
445load, and adds them to the schema at runtime, including relationships,
446etc. Does not process drops or changes.
447
a60b5b8d 448Returns a list of the new monikers added.
449
b97c2c1e 450=cut
451
39d5612f 452sub rescan { my $self = shift; $self->loader->rescan($self) }
b97c2c1e 453
a8d229ff 454=head2 naming
455
456=over 4
457
458=item Arguments: \%opts | $ver
459
460=back
461
462Controls the naming options for backward compatibility, see
463L<DBIx::Class::Schema::Loader::Base/naming> for details.
464
465To upgrade a dynamic schema, use:
466
467 __PACKAGE__->naming('current');
468
469Can be imported into your dump script and called as a function as well:
470
471 naming('v4');
996be9ee 472
f22644d7 473=head2 use_namespaces
474
475=over 4
476
477=item Arguments: 1|0
478
479=back
480
481Controls the use_namespaces options for backward compatibility, see
482L<DBIx::Class::Schema::Loader::Base/use_namespaces> for details.
483
484To upgrade a dynamic schema, use:
485
486 __PACKAGE__->use_namespaces(1);
487
488Can be imported into your dump script and called as a function as well:
489
490 use_namespaces(1);
491
996be9ee 492=head1 KNOWN ISSUES
493
494=head2 Multiple Database Schemas
495
c4a69b87 496See L<DBIx::Class::Schema::Loader::Base/db_schema>.
89ecd854 497
be80bba7 498=head1 ACKNOWLEDGEMENTS
a78e3fed 499
be80bba7 500Matt S Trout, all of the #dbix-class folks, and everyone who's ever sent
501in a bug report or suggestion.
fbd83464 502
8a6b44ef 503Based on L<DBIx::Class::Loader> by Sebastian Riedel
a78e3fed 504
505Based upon the work of IKEBE Tomohiro
506
be80bba7 507=head1 AUTHOR
a78e3fed 508
be80bba7 509blblack: Brandon Black <blblack@gmail.com>
510
511=head1 CONTRIBUTORS
512
a41f1fd4 513ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
be80bba7 514
515arcanez: Justin Hunter <justin.d.hunter@gmail.com>
516
517ash: Ash Berlin <ash@cpan.org>
518
412638fa 519btilly: Ben Tilly <btilly@gmail.com>
59388920 520
be80bba7 521Caelum: Rafael Kitover <rkitover@cpan.org>
522
523TSUNODA Kazuya <drk@drk7.jp>
524
f84a7413 525rbo: Robert Bohne <rbo@cpan.org>
be80bba7 526
69fca474 527ribasushi: Peter Rabbitson <ribasushi@cpan.org>
1f625792 528
fdd8ff16 529gugu: Andrey Kostenko <a.kostenko@rambler-co.ru>
530
65e705c3 531jhannah: Jay Hannah <jay@jays.net>
532
7b505bbd 533rbuels: Robert Buels <rmb32@cornell.edu>
534
accc9e96 535timbunce: Tim Bunce <timb@cpan.org>
da21e0cf 536
c21bfb92 537mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
538
d36c8734 539mstratman: Mark A. Stratman <stratman@gmail.com>
540
827dff19 541kane: Jos Boumans <kane@cpan.org>
542
43b982ea 543waawaamilk: Nigel McNie <nigel@mcnie.name>
544
96f68869 545acmoore: Andrew Moore <amoore@cpan.org>
546
2a5dcfb3 547bphillips: Brian Phillips <bphillips@cpan.org>
548
8763ffda 549schwern: Michael G. Schwern <mschwern@cpan.org>
550
9fd0726a 551hobbs: Andrew Rodland <arodland@cpan.org>
552
c9cf9b4d 553domm: Thomas Klausner <domm@plix.at>
554
12333562 555spb: Stephen Bennett <spb@exherbo.org>
556
71687093 557Matias E. Fernandez <mfernandez@pisco.ch>
558
07f39b47 559Al Newkirk <awncorp@cpan.org>
560
be80bba7 561... and lots of other folks. If we forgot you, please write the current
562maintainer or RT.
a78e3fed 563
9cc8e7e1 564=head1 COPYRIGHT & LICENSE
565
566Copyright (c) 2006 - 2009 by the aforementioned
567L<DBIx::Class::Schema::Loader/AUTHOR> and
568L<DBIx::Class::Schema::Loader/CONTRIBUTORS>.
a78e3fed 569
570This library is free software; you can redistribute it and/or modify it under
571the same terms as Perl itself.
572
573=head1 SEE ALSO
574
996be9ee 575L<DBIx::Class>, L<DBIx::Class::Manual::ExampleSchema>
a78e3fed 576
577=cut
578
5791;
71a6e88a 580# vim:et sts=4 sw=4 tw=0: