1package DBIx::Class::Schema::Loader; 2 3use strict; 4use warnings; 5use base qw/DBIx::Class::Schema Class::Accessor::Grouped/; 6use MRO::Compat; 7use mro 'c3'; 8use Carp::Clan qw/^DBIx::Class/; 9use Scalar::Util 'weaken'; 10use Sub::Name 'subname'; 11use DBIx::Class::Schema::Loader::Utils 'array_eq'; 12use Try::Tiny; 13use Hash::Merge 'merge'; 14use namespace::clean; 15 16# Always remember to do all digits for the version even if they're 0 17# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports 18# brain damage and presumably various other packaging systems too 19our $VERSION = '0.07033'; 20 21__PACKAGE__->mk_group_accessors('inherited', qw/ 22 _loader_args 23 dump_to_dir 24 _loader_invoked 25 _loader 26 loader_class 27 naming 28 use_namespaces 29/); 30__PACKAGE__->_loader_args({}); 31 32=encoding UTF-8 33 34=head1 NAME 35 36DBIx::Class::Schema::Loader - Create a DBIx::Class::Schema based on a database 37 38=head1 SYNOPSIS 39 40 ### use this module to generate a set of class files 41 42 # in a script 43 use DBIx::Class::Schema::Loader qw/ make_schema_at /; 44 make_schema_at( 45 'My::Schema', 46 { debug => 1, 47 dump_directory => './lib', 48 }, 49 [ 'dbi:Pg:dbname="foo"', 'myuser', 'mypassword', 50 { loader_class => 'MyLoader' } # optionally 51 ], 52 ); 53 54 # from the command line or a shell script with dbicdump (distributed 55 # with this module). Do `perldoc dbicdump` for usage. 56 dbicdump -o dump_directory=./lib \ 57 -o components='["InflateColumn::DateTime"]' \ 58 -o debug=1 \ 59 My::Schema \ 60 'dbi:Pg:dbname=foo' \ 61 myuser \ 62 mypassword 63 64 ### or generate and load classes at runtime 65 # note: this technique is not recommended 66 # for use in production code 67 68 package My::Schema; 69 use base qw/DBIx::Class::Schema::Loader/; 70 71 __PACKAGE__->loader_options( 72 constraint => '^foo.*', 73 # debug => 1, 74 ); 75 76 #### in application code elsewhere: 77 78 use My::Schema; 79 80 my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs); 81 # -or- 82 my $schema1 = "My::Schema"; $schema1->connection(as above); 83 84=head1 DESCRIPTION 85 86DBIx::Class::Schema::Loader automates the definition of a 87L<DBIx::Class::Schema> by scanning database table definitions and setting up 88the columns, primary keys, unique constraints and relationships. 89 90See L<dbicdump> for the C<dbicdump> utility. 91 92DBIx::Class::Schema::Loader currently supports only the DBI storage type. It 93has explicit support for L<DBD::Pg>, L<DBD::mysql>, L<DBD::DB2>, 94L<DBD::Firebird>, L<DBD::InterBase>, L<DBD::Informix>, L<DBD::SQLAnywhere>, 95L<DBD::SQLite>, L<DBD::Sybase> (for Sybase ASE and MSSSQL), L<DBD::ODBC> (for 96MSSQL, MSAccess, Firebird and SQL Anywhere) L<DBD::ADO> (for MSSQL and 97MSAccess) and L<DBD::Oracle>. Other DBI drivers may function to a greater or 98lesser degree with this loader, depending on how much of the DBI spec they 99implement, and how standard their implementation is. 100 101Patches to make other DBDs work correctly welcome. 102 103See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing 104your own vendor-specific subclass for an unsupported DBD driver. 105 106This module requires L<DBIx::Class> 0.08127 or later, and obsoletes the older 107L<DBIx::Class::Loader>. 108 109See L<DBIx::Class::Schema::Loader::Base> for available options. 110 111=head1 METHODS 112 113=head2 loader 114 115The loader object, as class data on your Schema. For methods available see 116L<DBIx::Class::Schema::Loader::Base> and L<DBIx::Class::Schema::Loader::DBI>. 117 118=cut 119 120sub loader { 121 my $self = shift; 122 $self->_loader(@_); 123} 124 125=head2 loader_class 126 127=over 4 128 129=item Argument: $loader_class 130 131=back 132 133Set the loader class to be instantiated when L</connection> is called. 134If the classname starts with "::", "DBIx::Class::Schema::Loader" is 135prepended. Defaults to L<DBIx::Class::Schema/storage_type> (which must 136start with "::" when using L<DBIx::Class::Schema::Loader>). 137 138This is mostly useful for subclassing existing loaders or in conjunction 139with L</dump_to_dir>. 140 141=head2 loader_options 142 143=over 4 144 145=item Argument: \%loader_options 146 147=back 148 149Example in Synopsis above demonstrates a few common arguments. For 150detailed information on all of the arguments, most of which are 151only useful in fairly complex scenarios, see the 152L<DBIx::Class::Schema::Loader::Base> documentation. 153 154If you intend to use C<loader_options>, you must call 155C<loader_options> before any connection is made, or embed the 156C<loader_options> in the connection information itself as shown 157below. Setting C<loader_options> after the connection has 158already been made is useless. 159 160=cut 161 162sub loader_options { 163 my $self = shift; 164 165 my %args = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_; 166 $self->_loader_args(\%args); 167 168 $self; 169} 170 171sub _invoke_loader { 172 my $self = shift; 173 my $class = ref $self || $self; 174 175 my $args = $self->_loader_args; 176 177 # temporarily copy $self's storage to class 178 my $class_storage = $class->storage; 179 if (ref $self) { 180 $class->storage($self->storage); 181 $class->storage->set_schema($class); 182 } 183 184 $args->{schema} = $class; 185 $args->{schema_class} = $class; 186 $args->{dump_directory} ||= $self->dump_to_dir; 187 $args->{naming} = $self->naming if $self->naming; 188 $args->{use_namespaces} = $self->use_namespaces if defined $self->use_namespaces; 189 190 # XXX this only works for relative storage_type, like ::DBI ... 191 my $loader_class = $self->loader_class; 192 if ($loader_class) { 193 $loader_class = "DBIx::Class::Schema::Loader${loader_class}" if $loader_class =~ /^::/; 194 $args->{loader_class} = $loader_class; 195 }; 196 197 my $impl = $loader_class || "DBIx::Class::Schema::Loader" . $self->storage_type; 198 try { 199 $self->ensure_class_loaded($impl) 200 } 201 catch { 202 croak qq/Could not load loader_class "$impl": "$_"/; 203 }; 204 205 $class->loader($impl->new(%$args)); 206 $class->loader->load; 207 $class->_loader_invoked(1); 208 209 # copy to $self 210 if (ref $self) { 211 $self->loader($class->loader); 212 $self->_loader_invoked(1); 213 214 $self->_merge_state_from($class); 215 } 216 217 # restore $class's storage 218 $class->storage($class_storage); 219 220 return $self; 221} 222 223# FIXME This needs to be moved into DBIC at some point, otherwise we are 224# maintaining things to do with DBIC guts, which we have no business of 225# maintaining. But at the moment it would be just dead code in DBIC, so we'll 226# maintain it here. 227sub _merge_state_from { 228 my ($self, $from) = @_; 229 230 my $orig_class_mappings = $self->class_mappings; 231 my $orig_source_registrations = $self->source_registrations; 232 233 $self->_copy_state_from($from); 234 235 $self->class_mappings(merge($orig_class_mappings, $self->class_mappings)) 236 if $orig_class_mappings; 237 238 $self->source_registrations(merge($orig_source_registrations, $self->source_registrations)) 239 if $orig_source_registrations; 240} 241 242sub _copy_state_from { 243 my $self = shift; 244 my ($from) = @_; 245 246 # older DBIC's do not have this method 247 if (try { DBIx::Class->VERSION('0.08197'); 1 }) { 248 return $self->next::method(@_); 249 } 250 else { 251 # this is a copy from DBIC git master pre 0.08197 252 $self->class_mappings({ %{$from->class_mappings} }); 253 $self->source_registrations({ %{$from->source_registrations} }); 254 255 foreach my $moniker ($from->sources) { 256 my $source = $from->source($moniker); 257 my $new = $source->new($source); 258 # we use extra here as we want to leave the class_mappings as they are 259 # but overwrite the source_registrations entry with the new source 260 $self->register_extra_source($moniker => $new); 261 } 262 263 if ($from->storage) { 264 $self->storage($from->storage); 265 $self->storage->set_schema($self); 266 } 267 } 268} 269 270=head2 connection 271 272=over 4 273 274=item Arguments: @args 275 276=item Return Value: $new_schema 277 278=back 279 280See L<DBIx::Class::Schema/connection> for basic usage. 281 282If the final argument is a hashref, and it contains the keys C<loader_options> 283or C<loader_class>, those keys will be deleted, and their values value will be 284used for the loader options or class, respectively, just as if set via the 285L</loader_options> or L</loader_class> methods above. 286 287The actual auto-loading operation (the heart of this module) will be invoked 288as soon as the connection information is defined. 289 290=cut 291 292sub connection { 293 my $self = shift; 294 my $class = ref $self || $self; 295 296 if($_[-1] && ref $_[-1] eq 'HASH') { 297 for my $option (qw/loader_class loader_options/) { 298 if(my $value = delete $_[-1]->{$option}) { 299 $self->$option($value); 300 } 301 } 302 pop @_ if !keys %{$_[-1]}; 303 } 304 305 # Make sure we inherit from schema_base_class and load schema_components 306 # before connecting. 307 require DBIx::Class::Schema::Loader::Base; 308 my $temp_loader = DBIx::Class::Schema::Loader::Base->new( 309 %{ $self->_loader_args }, 310 schema => $self, 311 naming => 'current', 312 use_namespaces => 1, 313 ); 314 315 my $modify_isa = 0; 316 my @components; 317 318 if ($temp_loader->schema_base_class || $temp_loader->schema_components) { 319 @components = @{ $temp_loader->schema_components } 320 if $temp_loader->schema_components; 321 322 push @components, ('+'.$temp_loader->schema_base_class) 323 if $temp_loader->schema_base_class; 324 325 my $class_isa = do { 326 no strict 'refs'; 327 \@{"${class}::ISA"}; 328 }; 329 330 my @component_classes = map { 331 /^\+/ ? substr($_, 1, length($_) - 1) : "DBIx::Class::$_" 332 } @components; 333 334 $modify_isa++ if not array_eq([ @$class_isa[0..(@components-1)] ], \@component_classes) 335 } 336 337 if ($modify_isa) { 338 $class->load_components(@components); 339 340 # This hack is necessary because we changed @ISA of $self through 341 # ->load_components and we are now in a different place in the mro. 342 no warnings 'redefine'; 343 344 local *connection = subname __PACKAGE__.'::connection' => sub { 345 my $self = shift; 346 $self->next::method(@_); 347 }; 348 349 my @linear_isa = @{ mro::get_linear_isa($class) }; 350 351 my $next_method; 352 353 foreach my $i (1..$#linear_isa) { 354 no strict 'refs'; 355 $next_method = *{$linear_isa[$i].'::connection'}{CODE}; 356 last if $next_method; 357 } 358 359 $self = $self->$next_method(@_); 360 } 361 else { 362 $self = $self->next::method(@_); 363 } 364 365 if(!$class->_loader_invoked) { 366 $self->_invoke_loader 367 } 368 369 return $self; 370} 371 372=head2 clone 373 374See L<DBIx::Class::Schema/clone>. 375 376=cut 377 378sub clone { 379 my $self = shift; 380 381 my $clone = $self->next::method(@_); 382 383 if($clone->_loader_args) { 384 $clone->_loader_args->{schema} = $clone; 385 weaken($clone->_loader_args->{schema}); 386 } 387 388 $clone; 389} 390 391=head2 dump_to_dir 392 393=over 4 394 395=item Argument: $directory 396 397=back 398 399Calling this as a class method on either L<DBIx::Class::Schema::Loader> 400or any derived schema class will cause all schemas to dump 401manual versions of themselves to the named directory when they are 402loaded. In order to be effective, this must be set before defining a 403connection on this schema class or any derived object (as the loading 404happens as soon as both a connection and loader_options are set, and 405only once per class). 406 407See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more 408details on the dumping mechanism. 409 410This can also be set at module import time via the import option 411C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where 412C</foo/bar> is the target directory. 413 414Examples: 415 416 # My::Schema isa DBIx::Class::Schema::Loader, and has connection info 417 # hardcoded in the class itself: 418 perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1 419 420 # Same, but no hard-coded connection, so we must provide one: 421 perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)' 422 423 # Or as a class method, as long as you get it done *before* defining a 424 # connection on this schema class or any derived object: 425 use My::Schema; 426 My::Schema->dump_to_dir('/foo/bar'); 427 My::Schema->connection(........); 428 429 # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all 430 # derived schemas 431 use My::Schema; 432 use My::OtherSchema; 433 DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar'); 434 My::Schema->connection(.......); 435 My::OtherSchema->connection(.......); 436 437 # Another alternative to the above: 438 use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |; 439 use My::Schema; 440 use My::OtherSchema; 441 My::Schema->connection(.......); 442 My::OtherSchema->connection(.......); 443 444=cut 445 446sub import { 447 my $self = shift; 448 449 return if !@_; 450 451 my $cpkg = (caller)[0]; 452 453 foreach my $opt (@_) { 454 if($opt =~ m{^dump_to_dir:(.*)$}) { 455 $self->dump_to_dir($1) 456 } 457 elsif($opt eq 'make_schema_at') { 458 no strict 'refs'; 459 *{"${cpkg}::make_schema_at"} = \&make_schema_at; 460 } 461 elsif($opt eq 'naming') { 462 no strict 'refs'; 463 *{"${cpkg}::naming"} = sub { $self->naming(@_) }; 464 } 465 elsif($opt eq 'use_namespaces') { 466 no strict 'refs'; 467 *{"${cpkg}::use_namespaces"} = sub { $self->use_namespaces(@_) }; 468 } 469 } 470} 471 472=head2 make_schema_at 473 474=over 4 475 476=item Arguments: $schema_class_name, \%loader_options, \@connect_info 477 478=item Return Value: $schema_class_name 479 480=back 481 482This function creates a DBIx::Class schema from an existing RDBMS 483schema. With the C<dump_directory> option, generates a set of 484DBIx::Class classes from an existing database schema read from the 485given dsn. Without a C<dump_directory>, creates schema classes in 486memory at runtime without generating on-disk class files. 487 488For a complete list of supported loader_options, see 489L<DBIx::Class::Schema::Loader::Base> 490 491The last hashref in the C<\@connect_info> can specify the L</loader_class>. 492 493This function can be imported in the usual way, as illustrated in 494these Examples: 495 496 # Simple example, creates as a new class 'New::Schema::Name' in 497 # memory in the running perl interpreter. 498 use DBIx::Class::Schema::Loader qw/ make_schema_at /; 499 make_schema_at( 500 'New::Schema::Name', 501 { debug => 1 }, 502 [ 'dbi:Pg:dbname="foo"','postgres','', 503 { loader_class => 'MyLoader' } # optionally 504 ], 505 ); 506 507 # Inside a script, specifying a dump directory in which to write 508 # class files 509 use DBIx::Class::Schema::Loader qw/ make_schema_at /; 510 make_schema_at( 511 'New::Schema::Name', 512 { debug => 1, dump_directory => './lib' }, 513 [ 'dbi:Pg:dbname="foo"','postgres','', 514 { loader_class => 'MyLoader' } # optionally 515 ], 516 ); 517 518The last hashref in the C<\@connect_info> is checked for loader arguments such 519as C<loader_options> and C<loader_class>, see L</connection> for more details. 520 521=cut 522 523sub make_schema_at { 524 my ($target, $opts, $connect_info) = @_; 525 526 { 527 no strict 'refs'; 528 @{$target . '::ISA'} = qw/DBIx::Class::Schema::Loader/; 529 } 530 531 $target->_loader_invoked(0); 532 533 $target->loader_options($opts); 534 535 my $temp_schema = $target->connect(@$connect_info); 536 537 $target->storage($temp_schema->storage); 538 $target->storage->set_schema($target); 539 540 return $target; 541} 542 543=head2 rescan 544 545=over 4 546 547=item Return Value: @new_monikers 548 549=back 550 551Re-scans the database for newly added tables since the initial 552load, and adds them to the schema at runtime, including relationships, 553etc. Does not process drops or changes. 554 555Returns a list of the new monikers added. 556 557=cut 558 559sub rescan { my $self = shift; $self->loader->rescan($self) } 560 561=head2 naming 562 563=over 4 564 565=item Arguments: \%opts | $ver 566 567=back 568 569Controls the naming options for backward compatibility, see 570L<DBIx::Class::Schema::Loader::Base/naming> for details. 571 572To upgrade a dynamic schema, use: 573 574 __PACKAGE__->naming('current'); 575 576Can be imported into your dump script and called as a function as well: 577 578 naming('v4'); 579 580=head2 use_namespaces 581 582=over 4 583 584=item Arguments: 1|0 585 586=back 587 588Controls the use_namespaces options for backward compatibility, see 589L<DBIx::Class::Schema::Loader::Base/use_namespaces> for details. 590 591To upgrade a dynamic schema, use: 592 593 __PACKAGE__->use_namespaces(1); 594 595Can be imported into your dump script and called as a function as well: 596 597 use_namespaces(1); 598 599=head1 KNOWN ISSUES 600 601=head2 Multiple Database Schemas 602 603See L<DBIx::Class::Schema::Loader::Base/db_schema>. 604 605=head1 ACKNOWLEDGEMENTS 606 607Matt S Trout, all of the #dbix-class folks, and everyone who's ever sent 608in a bug report or suggestion. 609 610Based on L<DBIx::Class::Loader> by Sebastian Riedel 611 612Based upon the work of IKEBE Tomohiro 613 614=head1 AUTHOR 615 616blblack: Brandon Black <blblack@gmail.com> 617 618=head1 CONTRIBUTORS 619 620ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org> 621 622arcanez: Justin Hunter <justin.d.hunter@gmail.com> 623 624ash: Ash Berlin <ash@cpan.org> 625 626btilly: Ben Tilly <btilly@gmail.com> 627 628Caelum: Rafael Kitover <rkitover@cpan.org> 629 630TSUNODA Kazuya <drk@drk7.jp> 631 632rbo: Robert Bohne <rbo@cpan.org> 633 634ribasushi: Peter Rabbitson <ribasushi@cpan.org> 635 636gugu: Andrey Kostenko <a.kostenko@rambler-co.ru> 637 638jhannah: Jay Hannah <jay@jays.net> 639 640jnap: John Napiorkowski <jjn1056@yahoo.com> 641 642rbuels: Robert Buels <rbuels@gmail.com> 643 644timbunce: Tim Bunce <timb@cpan.org> 645 646mst: Matt S. Trout <mst@shadowcatsystems.co.uk> 647 648mstratman: Mark A. Stratman <stratman@gmail.com> 649 650kane: Jos Boumans <kane@cpan.org> 651 652waawaamilk: Nigel McNie <nigel@mcnie.name> 653 654acmoore: Andrew Moore <amoore@cpan.org> 655 656bphillips: Brian Phillips <bphillips@cpan.org> 657 658schwern: Michael G. Schwern <mschwern@cpan.org> 659 660SineSwiper: Brendan Byrd <byrd.b@insightcom.com> 661 662hobbs: Andrew Rodland <arodland@cpan.org> 663 664domm: Thomas Klausner <domm@plix.at> 665 666spb: Stephen Bennett <spb@exherbo.org> 667 668Matias E. Fernandez <mfernandez@pisco.ch> 669 670alnewkirk: Al Newkirk <awncorp@cpan.org> 671 672angelixd: Paul C. Mantz <pcmantz@cpan.org> 673 674andrewalker: André Walker <andre@andrewalker.net> 675 676... and lots of other folks. If we forgot you, please write the current 677maintainer or RT. 678 679=head1 COPYRIGHT & LICENSE 680 681Copyright (c) 2006 - 2009 by the aforementioned 682L<DBIx::Class::Schema::Loader/AUTHOR> and 683L<DBIx::Class::Schema::Loader/CONTRIBUTORS>. 684 685This library is free software; you can redistribute it and/or modify it under 686the same terms as Perl itself. 687 688=head1 SEE ALSO 689 690L<DBIx::Class>, L<DBIx::Class::Manual::Intro>, L<DBIx::Class::Tutorial>, 691L<DBIx::Class::Schema::Loader::Base> 692 693=cut 694 6951; 696# vim:et sts=4 sw=4 tw=0: 697