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