Introduce M.A.D. within the schema/source instance linkage
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Schema.pm
1 package DBIx::Class::Schema;
2
3 use strict;
4 use warnings;
5
6 use DBIx::Class::Exception;
7 use Carp::Clan qw/^DBIx::Class|^Try::Tiny/;
8 use Try::Tiny;
9 use Scalar::Util 'weaken';
10 use File::Spec;
11 use Sub::Name 'subname';
12 use Module::Find();
13 use Storable();
14 use B qw/svref_2object/;
15 use namespace::clean;
16
17 use base qw/DBIx::Class/;
18
19 __PACKAGE__->mk_classdata('class_mappings' => {});
20 __PACKAGE__->mk_classdata('source_registrations' => {});
21 __PACKAGE__->mk_classdata('storage_type' => '::DBI');
22 __PACKAGE__->mk_classdata('storage');
23 __PACKAGE__->mk_classdata('exception_action');
24 __PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
25 __PACKAGE__->mk_classdata('default_resultset_attributes' => {});
26
27 =head1 NAME
28
29 DBIx::Class::Schema - composable schemas
30
31 =head1 SYNOPSIS
32
33   package Library::Schema;
34   use base qw/DBIx::Class::Schema/;
35
36   # load all Result classes in Library/Schema/Result/
37   __PACKAGE__->load_namespaces();
38
39   package Library::Schema::Result::CD;
40   use base qw/DBIx::Class::Core/;
41
42   __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
43   __PACKAGE__->table('cd');
44
45   # Elsewhere in your code:
46   my $schema1 = Library::Schema->connect(
47     $dsn,
48     $user,
49     $password,
50     { AutoCommit => 1 },
51   );
52
53   my $schema2 = Library::Schema->connect($coderef_returning_dbh);
54
55   # fetch objects using Library::Schema::Result::DVD
56   my $resultset = $schema1->resultset('DVD')->search( ... );
57   my @dvd_objects = $schema2->resultset('DVD')->search( ... );
58
59 =head1 DESCRIPTION
60
61 Creates database classes based on a schema. This is the recommended way to
62 use L<DBIx::Class> and allows you to use more than one concurrent connection
63 with your classes.
64
65 NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
66 carefully, as DBIx::Class does things a little differently. Note in
67 particular which module inherits off which.
68
69 =head1 SETUP METHODS
70
71 =head2 load_namespaces
72
73 =over 4
74
75 =item Arguments: %options?
76
77 =back
78
79   __PACKAGE__->load_namespaces();
80
81   __PACKAGE__->load_namespaces(
82    result_namespace => 'Res',
83    resultset_namespace => 'RSet',
84    default_resultset_class => '+MyDB::Othernamespace::RSet',
85  );
86
87 With no arguments, this method uses L<Module::Find> to load all your
88 Result classes from a sub-namespace F<Result> under your Schema class'
89 namespace, i.e. with a Schema of I<MyDB::Schema> all files in
90 I<MyDB::Schema::Result> are assumed to be Result classes.
91
92 It also finds all ResultSet classes in the namespace F<ResultSet> and
93 loads them into the appropriate Result classes using for you. The
94 matching is done by assuming the package name of the ResultSet class
95 is the same as that of the Result class.
96
97 You will be warned if ResultSet classes are discovered for which there
98 are no matching Result classes like this:
99
100   load_namespaces found ResultSet class $classname with no corresponding Result class
101
102 If a Result class is found to already have a ResultSet class set using
103 L</resultset_class> to some other class, you will be warned like this:
104
105   We found ResultSet class '$rs_class' for '$result', but it seems
106   that you had already set '$result' to use '$rs_set' instead
107
108 Both of the sub-namespaces are configurable if you don't like the defaults,
109 via the options C<result_namespace> and C<resultset_namespace>.
110
111 If (and only if) you specify the option C<default_resultset_class>, any found
112 Result classes for which we do not find a corresponding
113 ResultSet class will have their C<resultset_class> set to
114 C<default_resultset_class>.
115
116 All of the namespace and classname options to this method are relative to
117 the schema classname by default.  To specify a fully-qualified name, prefix
118 it with a literal C<+>.
119
120 Examples:
121
122   # load My::Schema::Result::CD, My::Schema::Result::Artist,
123   #    My::Schema::ResultSet::CD, etc...
124   My::Schema->load_namespaces;
125
126   # Override everything to use ugly names.
127   # In this example, if there is a My::Schema::Res::Foo, but no matching
128   #   My::Schema::RSets::Foo, then Foo will have its
129   #   resultset_class set to My::Schema::RSetBase
130   My::Schema->load_namespaces(
131     result_namespace => 'Res',
132     resultset_namespace => 'RSets',
133     default_resultset_class => 'RSetBase',
134   );
135
136   # Put things in other namespaces
137   My::Schema->load_namespaces(
138     result_namespace => '+Some::Place::Results',
139     resultset_namespace => '+Another::Place::RSets',
140   );
141
142 If you'd like to use multiple namespaces of each type, simply use an arrayref
143 of namespaces for that option.  In the case that the same result
144 (or resultset) class exists in multiple namespaces, the latter entries in
145 your list of namespaces will override earlier ones.
146
147   My::Schema->load_namespaces(
148     # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
149     result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
150     resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
151   );
152
153 =cut
154
155 # Pre-pends our classname to the given relative classname or
156 #   class namespace, unless there is a '+' prefix, which will
157 #   be stripped.
158 sub _expand_relative_name {
159   my ($class, $name) = @_;
160   return if !$name;
161   $name = $class . '::' . $name if ! ($name =~ s/^\+//);
162   return $name;
163 }
164
165 # Finds all modules in the supplied namespace, or if omitted in the
166 # namespace of $class. Untaints all findings as they can be assumed
167 # to be safe
168 sub _findallmod {
169   my $proto = shift;
170   my $ns = shift || ref $proto || $proto;
171
172   my @mods = Module::Find::findallmod($ns);
173
174   # try to untaint module names. mods where this fails
175   # are left alone so we don't have to change the old behavior
176   no locale; # localized \w doesn't untaint expression
177   return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
178 }
179
180 # returns a hash of $shortname => $fullname for every package
181 # found in the given namespaces ($shortname is with the $fullname's
182 # namespace stripped off)
183 sub _map_namespaces {
184   my ($class, @namespaces) = @_;
185
186   my @results_hash;
187   foreach my $namespace (@namespaces) {
188     push(
189       @results_hash,
190       map { (substr($_, length "${namespace}::"), $_) }
191       $class->_findallmod($namespace)
192     );
193   }
194
195   @results_hash;
196 }
197
198 # returns the result_source_instance for the passed class/object,
199 # or dies with an informative message (used by load_namespaces)
200 sub _ns_get_rsrc_instance {
201   my $class = shift;
202   my $rs = ref ($_[0]) || $_[0];
203
204   if ($rs->can ('result_source_instance') ) {
205     return $rs->result_source_instance;
206   }
207   else {
208     $class->throw_exception (
209       "Attempt to load_namespaces() class $rs failed - are you sure this is a real Result Class?"
210     );
211   }
212 }
213
214 sub load_namespaces {
215   my ($class, %args) = @_;
216
217   my $result_namespace = delete $args{result_namespace} || 'Result';
218   my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
219   my $default_resultset_class = delete $args{default_resultset_class};
220
221   $class->throw_exception('load_namespaces: unknown option(s): '
222     . join(q{,}, map { qq{'$_'} } keys %args))
223       if scalar keys %args;
224
225   $default_resultset_class
226     = $class->_expand_relative_name($default_resultset_class);
227
228   for my $arg ($result_namespace, $resultset_namespace) {
229     $arg = [ $arg ] if !ref($arg) && $arg;
230
231     $class->throw_exception('load_namespaces: namespace arguments must be '
232       . 'a simple string or an arrayref')
233         if ref($arg) ne 'ARRAY';
234
235     $_ = $class->_expand_relative_name($_) for (@$arg);
236   }
237
238   my %results = $class->_map_namespaces(@$result_namespace);
239   my %resultsets = $class->_map_namespaces(@$resultset_namespace);
240
241   my @to_register;
242   {
243     no warnings 'redefine';
244     local *Class::C3::reinitialize = sub { };
245     use warnings 'redefine';
246
247     # ensure classes are loaded and attached in inheritance order
248     for my $res (values %results) {
249       $class->ensure_class_loaded($res);
250     }
251     my %inh_idx;
252     my @subclass_last = sort {
253
254       ($inh_idx{$a} ||=
255         scalar @{mro::get_linear_isa( $results{$a} )}
256       )
257
258           <=>
259
260       ($inh_idx{$b} ||=
261         scalar @{mro::get_linear_isa( $results{$b} )}
262       )
263
264     } keys(%results);
265
266     foreach my $result (@subclass_last) {
267       my $result_class = $results{$result};
268
269       my $rs_class = delete $resultsets{$result};
270       my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
271
272       if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
273         if($rs_class && $rs_class ne $rs_set) {
274           carp "We found ResultSet class '$rs_class' for '$result', but it seems "
275              . "that you had already set '$result' to use '$rs_set' instead";
276         }
277       }
278       elsif($rs_class ||= $default_resultset_class) {
279         $class->ensure_class_loaded($rs_class);
280         if(!$rs_class->isa("DBIx::Class::ResultSet")) {
281             carp "load_namespaces found ResultSet class $rs_class that does not subclass DBIx::Class::ResultSet";
282         }
283
284         $class->_ns_get_rsrc_instance ($result_class)->resultset_class($rs_class);
285       }
286
287       my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $result;
288
289       push(@to_register, [ $source_name, $result_class ]);
290     }
291   }
292
293   foreach (sort keys %resultsets) {
294     carp "load_namespaces found ResultSet class $_ with no "
295       . 'corresponding Result class';
296   }
297
298   Class::C3->reinitialize;
299   $class->register_class(@$_) for (@to_register);
300
301   return;
302 }
303
304 =head2 load_classes
305
306 =over 4
307
308 =item Arguments: @classes?, { $namespace => [ @classes ] }+
309
310 =back
311
312 L</load_classes> is an alternative method to L</load_namespaces>, both of
313 which serve similar purposes, each with different advantages and disadvantages.
314 In the general case you should use L</load_namespaces>, unless you need to
315 be able to specify that only specific classes are loaded at runtime.
316
317 With no arguments, this method uses L<Module::Find> to find all classes under
318 the schema's namespace. Otherwise, this method loads the classes you specify
319 (using L<use>), and registers them (using L</"register_class">).
320
321 It is possible to comment out classes with a leading C<#>, but note that perl
322 will think it's a mistake (trying to use a comment in a qw list), so you'll
323 need to add C<no warnings 'qw';> before your load_classes call.
324
325 If any classes found do not appear to be Result class files, you will
326 get the following warning:
327
328    Failed to load $comp_class. Can't find source_name method. Is
329    $comp_class really a full DBIC result class? Fix it, move it elsewhere,
330    or make your load_classes call more specific.
331
332 Example:
333
334   My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
335                               # etc. (anything under the My::Schema namespace)
336
337   # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
338   # not Other::Namespace::LinerNotes nor My::Schema::Track
339   My::Schema->load_classes(qw/ CD Artist #Track /, {
340     Other::Namespace => [qw/ Producer #LinerNotes /],
341   });
342
343 =cut
344
345 sub load_classes {
346   my ($class, @params) = @_;
347
348   my %comps_for;
349
350   if (@params) {
351     foreach my $param (@params) {
352       if (ref $param eq 'ARRAY') {
353         # filter out commented entries
354         my @modules = grep { $_ !~ /^#/ } @$param;
355
356         push (@{$comps_for{$class}}, @modules);
357       }
358       elsif (ref $param eq 'HASH') {
359         # more than one namespace possible
360         for my $comp ( keys %$param ) {
361           # filter out commented entries
362           my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
363
364           push (@{$comps_for{$comp}}, @modules);
365         }
366       }
367       else {
368         # filter out commented entries
369         push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
370       }
371     }
372   } else {
373     my @comp = map { substr $_, length "${class}::"  }
374                  $class->_findallmod;
375     $comps_for{$class} = \@comp;
376   }
377
378   my @to_register;
379   {
380     no warnings qw/redefine/;
381     local *Class::C3::reinitialize = sub { };
382     foreach my $prefix (keys %comps_for) {
383       foreach my $comp (@{$comps_for{$prefix}||[]}) {
384         my $comp_class = "${prefix}::${comp}";
385         $class->ensure_class_loaded($comp_class);
386
387         my $snsub = $comp_class->can('source_name');
388         if(! $snsub ) {
389           carp "Failed to load $comp_class. Can't find source_name method. Is $comp_class really a full DBIC result class? Fix it, move it elsewhere, or make your load_classes call more specific.";
390           next;
391         }
392         $comp = $snsub->($comp_class) || $comp;
393
394         push(@to_register, [ $comp, $comp_class ]);
395       }
396     }
397   }
398   Class::C3->reinitialize;
399
400   foreach my $to (@to_register) {
401     $class->register_class(@$to);
402     #  if $class->can('result_source_instance');
403   }
404 }
405
406 =head2 storage_type
407
408 =over 4
409
410 =item Arguments: $storage_type|{$storage_type, \%args}
411
412 =item Return value: $storage_type|{$storage_type, \%args}
413
414 =item Default value: DBIx::Class::Storage::DBI
415
416 =back
417
418 Set the storage class that will be instantiated when L</connect> is called.
419 If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
420 assumed by L</connect>.
421
422 You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
423 in cases where the appropriate subclass is not autodetected.
424
425 If your storage type requires instantiation arguments, those are
426 defined as a second argument in the form of a hashref and the entire
427 value needs to be wrapped into an arrayref or a hashref.  We support
428 both types of refs here in order to play nice with your
429 Config::[class] or your choice. See
430 L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
431
432 =head2 exception_action
433
434 =over 4
435
436 =item Arguments: $code_reference
437
438 =item Return value: $code_reference
439
440 =item Default value: None
441
442 =back
443
444 When L</throw_exception> is invoked and L</exception_action> is set to a code
445 reference, this reference will be called instead of
446 L<DBIx::Class::Exception/throw>, with the exception message passed as the only
447 argument.
448
449 Your custom throw code B<must> rethrow the exception, as L</throw_exception> is
450 an integral part of DBIC's internal execution control flow.
451
452 Example:
453
454    package My::Schema;
455    use base qw/DBIx::Class::Schema/;
456    use My::ExceptionClass;
457    __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
458    __PACKAGE__->load_classes;
459
460    # or:
461    my $schema_obj = My::Schema->connect( .... );
462    $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
463
464 =head2 stacktrace
465
466 =over 4
467
468 =item Arguments: boolean
469
470 =back
471
472 Whether L</throw_exception> should include stack trace information.
473 Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
474 is true.
475
476 =head2 sqlt_deploy_hook
477
478 =over
479
480 =item Arguments: $sqlt_schema
481
482 =back
483
484 An optional sub which you can declare in your own Schema class that will get
485 passed the L<SQL::Translator::Schema> object when you deploy the schema via
486 L</create_ddl_dir> or L</deploy>.
487
488 For an example of what you can do with this, see
489 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
490
491 Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
492 is called before L</deploy>. Therefore the hook can be used only to manipulate
493 the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
494 database. If you want to execute post-deploy statements which can not be generated
495 by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
496 and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
497
498 =head1 METHODS
499
500 =head2 connect
501
502 =over 4
503
504 =item Arguments: @connectinfo
505
506 =item Return Value: $new_schema
507
508 =back
509
510 Creates and returns a new Schema object. The connection info set on it
511 is used to create a new instance of the storage backend and set it on
512 the Schema object.
513
514 See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
515 syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
516 general.
517
518 Note that C<connect_info> expects an arrayref of arguments, but
519 C<connect> does not. C<connect> wraps its arguments in an arrayref
520 before passing them to C<connect_info>.
521
522 =head3 Overloading
523
524 C<connect> is a convenience method. It is equivalent to calling
525 $schema->clone->connection(@connectinfo). To write your own overloaded
526 version, overload L</connection> instead.
527
528 =cut
529
530 sub connect { shift->clone->connection(@_) }
531
532 =head2 resultset
533
534 =over 4
535
536 =item Arguments: $source_name
537
538 =item Return Value: $resultset
539
540 =back
541
542   my $rs = $schema->resultset('DVD');
543
544 Returns the L<DBIx::Class::ResultSet> object for the registered source
545 name.
546
547 =cut
548
549 sub resultset {
550   my ($self, $moniker) = @_;
551   $self->throw_exception('resultset() expects a source name')
552     unless defined $moniker;
553   return $self->source($moniker)->resultset;
554 }
555
556 =head2 sources
557
558 =over 4
559
560 =item Return Value: @source_names
561
562 =back
563
564   my @source_names = $schema->sources;
565
566 Lists names of all the sources registered on this Schema object.
567
568 =cut
569
570 sub sources { return keys %{shift->source_registrations}; }
571
572 =head2 source
573
574 =over 4
575
576 =item Arguments: $source_name
577
578 =item Return Value: $result_source
579
580 =back
581
582   my $source = $schema->source('Book');
583
584 Returns the L<DBIx::Class::ResultSource> object for the registered
585 source name.
586
587 =cut
588
589 sub source {
590   my ($self, $moniker) = @_;
591   my $sreg = $self->source_registrations;
592   return $sreg->{$moniker} if exists $sreg->{$moniker};
593
594   # if we got here, they probably passed a full class name
595   my $mapped = $self->class_mappings->{$moniker};
596   $self->throw_exception("Can't find source for ${moniker}")
597     unless $mapped && exists $sreg->{$mapped};
598   return $sreg->{$mapped};
599 }
600
601 =head2 class
602
603 =over 4
604
605 =item Arguments: $source_name
606
607 =item Return Value: $classname
608
609 =back
610
611   my $class = $schema->class('CD');
612
613 Retrieves the Result class name for the given source name.
614
615 =cut
616
617 sub class {
618   my ($self, $moniker) = @_;
619   return $self->source($moniker)->result_class;
620 }
621
622 =head2 txn_do
623
624 =over 4
625
626 =item Arguments: C<$coderef>, @coderef_args?
627
628 =item Return Value: The return value of $coderef
629
630 =back
631
632 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
633 returning its result (if any). Equivalent to calling $schema->storage->txn_do.
634 See L<DBIx::Class::Storage/"txn_do"> for more information.
635
636 This interface is preferred over using the individual methods L</txn_begin>,
637 L</txn_commit>, and L</txn_rollback> below.
638
639 WARNING: If you are connected with C<< AutoCommit => 0 >> the transaction is
640 considered nested, and you will still need to call L</txn_commit> to write your
641 changes when appropriate. You will also want to connect with C<< auto_savepoint =>
642 1 >> to get partial rollback to work, if the storage driver for your database
643 supports it.
644
645 Connecting with C<< AutoCommit => 1 >> is recommended.
646
647 =cut
648
649 sub txn_do {
650   my $self = shift;
651
652   $self->storage or $self->throw_exception
653     ('txn_do called on $schema without storage');
654
655   $self->storage->txn_do(@_);
656 }
657
658 =head2 txn_scope_guard
659
660 Runs C<txn_scope_guard> on the schema's storage. See
661 L<DBIx::Class::Storage/txn_scope_guard>.
662
663 =cut
664
665 sub txn_scope_guard {
666   my $self = shift;
667
668   $self->storage or $self->throw_exception
669     ('txn_scope_guard called on $schema without storage');
670
671   $self->storage->txn_scope_guard(@_);
672 }
673
674 =head2 txn_begin
675
676 Begins a transaction (does nothing if AutoCommit is off). Equivalent to
677 calling $schema->storage->txn_begin. See
678 L<DBIx::Class::Storage/"txn_begin"> for more information.
679
680 =cut
681
682 sub txn_begin {
683   my $self = shift;
684
685   $self->storage or $self->throw_exception
686     ('txn_begin called on $schema without storage');
687
688   $self->storage->txn_begin;
689 }
690
691 =head2 txn_commit
692
693 Commits the current transaction. Equivalent to calling
694 $schema->storage->txn_commit. See L<DBIx::Class::Storage/"txn_commit">
695 for more information.
696
697 =cut
698
699 sub txn_commit {
700   my $self = shift;
701
702   $self->storage or $self->throw_exception
703     ('txn_commit called on $schema without storage');
704
705   $self->storage->txn_commit;
706 }
707
708 =head2 txn_rollback
709
710 Rolls back the current transaction. Equivalent to calling
711 $schema->storage->txn_rollback. See
712 L<DBIx::Class::Storage/"txn_rollback"> for more information.
713
714 =cut
715
716 sub txn_rollback {
717   my $self = shift;
718
719   $self->storage or $self->throw_exception
720     ('txn_rollback called on $schema without storage');
721
722   $self->storage->txn_rollback;
723 }
724
725 =head2 storage
726
727   my $storage = $schema->storage;
728
729 Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
730 if you want to turn on SQL statement debugging at runtime, or set the
731 quote character. For the default storage, the documentation can be
732 found in L<DBIx::Class::Storage::DBI>.
733
734 =head2 populate
735
736 =over 4
737
738 =item Arguments: $source_name, \@data;
739
740 =item Return value: \@$objects | nothing
741
742 =back
743
744 Pass this method a resultsource name, and an arrayref of
745 arrayrefs. The arrayrefs should contain a list of column names,
746 followed by one or many sets of matching data for the given columns.
747
748 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
749 to insert the data, as this is a fast method. However, insert_bulk currently
750 assumes that your datasets all contain the same type of values, using scalar
751 references in a column in one row, and not in another will probably not work.
752
753 Otherwise, each set of data is inserted into the database using
754 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
755 objects is returned.
756
757 e.g.
758
759   $schema->populate('Artist', [
760     [ qw/artistid name/ ],
761     [ 1, 'Popular Band' ],
762     [ 2, 'Indie Band' ],
763     ...
764   ]);
765
766 Since wantarray context is basically the same as looping over $rs->create(...)
767 you won't see any performance benefits and in this case the method is more for
768 convenience. Void context sends the column information directly to storage
769 using <DBI>s bulk insert method. So the performance will be much better for
770 storages that support this method.
771
772 Because of this difference in the way void context inserts rows into your
773 database you need to note how this will effect any loaded components that
774 override or augment insert.  For example if you are using a component such
775 as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
776 wantarray context if you want the PKs automatically created.
777
778 =cut
779
780 sub populate {
781   my ($self, $name, $data) = @_;
782   if(my $rs = $self->resultset($name)) {
783     if(defined wantarray) {
784         return $rs->populate($data);
785     } else {
786         $rs->populate($data);
787     }
788   } else {
789       $self->throw_exception("$name is not a resultset");
790   }
791 }
792
793 =head2 connection
794
795 =over 4
796
797 =item Arguments: @args
798
799 =item Return Value: $new_schema
800
801 =back
802
803 Similar to L</connect> except sets the storage object and connection
804 data in-place on the Schema class. You should probably be calling
805 L</connect> to get a proper Schema object instead.
806
807 =head3 Overloading
808
809 Overload C<connection> to change the behaviour of C<connect>.
810
811 =cut
812
813 sub connection {
814   my ($self, @info) = @_;
815   return $self if !@info && $self->storage;
816
817   my ($storage_class, $args) = ref $self->storage_type ?
818     ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
819
820   $storage_class = 'DBIx::Class::Storage'.$storage_class
821     if $storage_class =~ m/^::/;
822   try {
823     $self->ensure_class_loaded ($storage_class);
824   }
825   catch {
826     $self->throw_exception(
827       "No arguments to load_classes and couldn't load ${storage_class} ($_)"
828     );
829   };
830   my $storage = $storage_class->new($self=>$args);
831   $storage->connect_info(\@info);
832   $self->storage($storage);
833   return $self;
834 }
835
836 sub _normalize_storage_type {
837   my ($self, $storage_type) = @_;
838   if(ref $storage_type eq 'ARRAY') {
839     return @$storage_type;
840   } elsif(ref $storage_type eq 'HASH') {
841     return %$storage_type;
842   } else {
843     $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
844   }
845 }
846
847 =head2 compose_namespace
848
849 =over 4
850
851 =item Arguments: $target_namespace, $additional_base_class?
852
853 =item Retur Value: $new_schema
854
855 =back
856
857 For each L<DBIx::Class::ResultSource> in the schema, this method creates a
858 class in the target namespace (e.g. $target_namespace::CD,
859 $target_namespace::Artist) that inherits from the corresponding classes
860 attached to the current schema.
861
862 It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
863 new $schema object. If C<$additional_base_class> is given, the new composed
864 classes will inherit from first the corresponding class from the current
865 schema then the base class.
866
867 For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
868
869   $schema->compose_namespace('My::DB', 'Base::Class');
870   print join (', ', @My::DB::CD::ISA) . "\n";
871   print join (', ', @My::DB::Artist::ISA) ."\n";
872
873 will produce the output
874
875   My::Schema::CD, Base::Class
876   My::Schema::Artist, Base::Class
877
878 =cut
879
880 # this might be oversimplified
881 # sub compose_namespace {
882 #   my ($self, $target, $base) = @_;
883
884 #   my $schema = $self->clone;
885 #   foreach my $moniker ($schema->sources) {
886 #     my $source = $schema->source($moniker);
887 #     my $target_class = "${target}::${moniker}";
888 #     $self->inject_base(
889 #       $target_class => $source->result_class, ($base ? $base : ())
890 #     );
891 #     $source->result_class($target_class);
892 #     $target_class->result_source_instance($source)
893 #       if $target_class->can('result_source_instance');
894 #     $schema->register_source($moniker, $source);
895 #   }
896 #   return $schema;
897 # }
898
899 sub compose_namespace {
900   my ($self, $target, $base) = @_;
901   my $schema = $self->clone;
902   {
903     no warnings qw/redefine/;
904     no strict qw/refs/;
905 #    local *Class::C3::reinitialize = sub { };
906     foreach my $moniker ($schema->sources) {
907       my $source = $schema->source($moniker);
908       my $target_class = "${target}::${moniker}";
909       $self->inject_base(
910         $target_class => $source->result_class, ($base ? $base : ())
911       );
912       $source->result_class($target_class);
913       if ($target_class->can('result_source_instance')) {
914
915         # since the newly created classes are registered only with
916         # the instance of $schema, it should be safe to weaken
917         # the ref (it will GC when $schema is destroyed)
918         $target_class->result_source_instance($source);
919         weaken ${"${target_class}::__cag_result_source_instance"};
920       }
921      $schema->register_source($moniker, $source);
922     }
923   }
924 #  Class::C3->reinitialize();
925   {
926     no strict 'refs';
927     no warnings 'redefine';
928     foreach my $meth (qw/class source resultset/) {
929       *{"${target}::${meth}"} = subname "${target}::${meth}" =>
930         sub { shift->schema->$meth(@_) };
931     }
932   }
933   return $schema;
934 }
935
936 sub setup_connection_class {
937   my ($class, $target, @info) = @_;
938   $class->inject_base($target => 'DBIx::Class::DB');
939   #$target->load_components('DB');
940   $target->connection(@info);
941 }
942
943 =head2 svp_begin
944
945 Creates a new savepoint (does nothing outside a transaction).
946 Equivalent to calling $schema->storage->svp_begin.  See
947 L<DBIx::Class::Storage/"svp_begin"> for more information.
948
949 =cut
950
951 sub svp_begin {
952   my ($self, $name) = @_;
953
954   $self->storage or $self->throw_exception
955     ('svp_begin called on $schema without storage');
956
957   $self->storage->svp_begin($name);
958 }
959
960 =head2 svp_release
961
962 Releases a savepoint (does nothing outside a transaction).
963 Equivalent to calling $schema->storage->svp_release.  See
964 L<DBIx::Class::Storage/"svp_release"> for more information.
965
966 =cut
967
968 sub svp_release {
969   my ($self, $name) = @_;
970
971   $self->storage or $self->throw_exception
972     ('svp_release called on $schema without storage');
973
974   $self->storage->svp_release($name);
975 }
976
977 =head2 svp_rollback
978
979 Rollback to a savepoint (does nothing outside a transaction).
980 Equivalent to calling $schema->storage->svp_rollback.  See
981 L<DBIx::Class::Storage/"svp_rollback"> for more information.
982
983 =cut
984
985 sub svp_rollback {
986   my ($self, $name) = @_;
987
988   $self->storage or $self->throw_exception
989     ('svp_rollback called on $schema without storage');
990
991   $self->storage->svp_rollback($name);
992 }
993
994 =head2 clone
995
996 =over 4
997
998 =item Return Value: $new_schema
999
1000 =back
1001
1002 Clones the schema and its associated result_source objects and returns the
1003 copy.
1004
1005 =cut
1006
1007 sub clone {
1008   my ($self) = @_;
1009   my $clone = { (ref $self ? %$self : ()) };
1010   bless $clone, (ref $self || $self);
1011
1012   $clone->class_mappings({ %{$clone->class_mappings} });
1013   $clone->source_registrations({ %{$clone->source_registrations} });
1014   foreach my $moniker ($self->sources) {
1015     my $source = $self->source($moniker);
1016     my $new = $source->new($source);
1017     # we use extra here as we want to leave the class_mappings as they are
1018     # but overwrite the source_registrations entry with the new source
1019     $clone->register_extra_source($moniker => $new);
1020   }
1021   $clone->storage->set_schema($clone) if $clone->storage;
1022   return $clone;
1023 }
1024
1025 =head2 throw_exception
1026
1027 =over 4
1028
1029 =item Arguments: $message
1030
1031 =back
1032
1033 Throws an exception. Defaults to using L<Carp::Clan> to report errors from
1034 user's perspective.  See L</exception_action> for details on overriding
1035 this method's behavior.  If L</stacktrace> is turned on, C<throw_exception>'s
1036 default behavior will provide a detailed stack trace.
1037
1038 =cut
1039
1040 my $false_exception_action_warned;
1041 sub throw_exception {
1042   my $self = shift;
1043
1044   if (my $act = $self->exception_action) {
1045     if ($act->(@_)) {
1046       DBIx::Class::Exception->throw(
1047           "Invocation of the exception_action handler installed on $self did *not*"
1048         .' result in an exception. DBIx::Class is unable to function without a reliable'
1049         .' exception mechanism, ensure that exception_action does not hide exceptions'
1050         ." (original error: $_[0])"
1051       );
1052     }
1053     elsif(! $false_exception_action_warned++) {
1054       carp (
1055           "The exception_action handler installed on $self returned false instead"
1056         .' of throwing an exception. This behavior has been deprecated, adjust your'
1057         .' handler to always rethrow the supplied error.'
1058       );
1059     }
1060   }
1061
1062   DBIx::Class::Exception->throw($_[0], $self->stacktrace);
1063 }
1064
1065 =head2 deploy
1066
1067 =over 4
1068
1069 =item Arguments: \%sqlt_args, $dir
1070
1071 =back
1072
1073 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
1074
1075 See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1076 The most common value for this would be C<< { add_drop_table => 1 } >>
1077 to have the SQL produced include a C<DROP TABLE> statement for each table
1078 created. For quoting purposes supply C<quote_table_names> and
1079 C<quote_field_names>.
1080
1081 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1082 ref or an array ref, containing a list of source to deploy. If present, then
1083 only the sources listed will get deployed. Furthermore, you can use the
1084 C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1085 FK.
1086
1087 =cut
1088
1089 sub deploy {
1090   my ($self, $sqltargs, $dir) = @_;
1091   $self->throw_exception("Can't deploy without storage") unless $self->storage;
1092   $self->storage->deploy($self, undef, $sqltargs, $dir);
1093 }
1094
1095 =head2 deployment_statements
1096
1097 =over 4
1098
1099 =item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
1100
1101 =item Return value: $listofstatements
1102
1103 =back
1104
1105 A convenient shortcut to
1106 C<< $self->storage->deployment_statements($self, @args) >>.
1107 Returns the SQL statements used by L</deploy> and
1108 L<DBIx::Class::Schema::Storage/deploy>.
1109
1110 =cut
1111
1112 sub deployment_statements {
1113   my $self = shift;
1114
1115   $self->throw_exception("Can't generate deployment statements without a storage")
1116     if not $self->storage;
1117
1118   $self->storage->deployment_statements($self, @_);
1119 }
1120
1121 =head2 create_ddl_dir
1122
1123 =over 4
1124
1125 =item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
1126
1127 =back
1128
1129 A convenient shortcut to
1130 C<< $self->storage->create_ddl_dir($self, @args) >>.
1131
1132 Creates an SQL file based on the Schema, for each of the specified
1133 database types, in the given directory.
1134
1135 =cut
1136
1137 sub create_ddl_dir {
1138   my $self = shift;
1139
1140   $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1141   $self->storage->create_ddl_dir($self, @_);
1142 }
1143
1144 =head2 ddl_filename
1145
1146 =over 4
1147
1148 =item Arguments: $database-type, $version, $directory, $preversion
1149
1150 =item Return value: $normalised_filename
1151
1152 =back
1153
1154   my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
1155
1156 This method is called by C<create_ddl_dir> to compose a file name out of
1157 the supplied directory, database type and version number. The default file
1158 name format is: C<$dir$schema-$version-$type.sql>.
1159
1160 You may override this method in your schema if you wish to use a different
1161 format.
1162
1163  WARNING
1164
1165  Prior to DBIx::Class version 0.08100 this method had a different signature:
1166
1167     my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1168
1169  In recent versions variables $dir and $version were reversed in order to
1170  bring the signature in line with other Schema/Storage methods. If you
1171  really need to maintain backward compatibility, you can do the following
1172  in any overriding methods:
1173
1174     ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1175
1176 =cut
1177
1178 sub ddl_filename {
1179   my ($self, $type, $version, $dir, $preversion) = @_;
1180
1181   my $filename = ref($self);
1182   $filename =~ s/::/-/g;
1183   $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1184   $filename =~ s/$version/$preversion-$version/ if($preversion);
1185
1186   return $filename;
1187 }
1188
1189 =head2 thaw
1190
1191 Provided as the recommended way of thawing schema objects. You can call
1192 C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1193 reference to any schema, so are rather useless.
1194
1195 =cut
1196
1197 sub thaw {
1198   my ($self, $obj) = @_;
1199   local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1200   return Storable::thaw($obj);
1201 }
1202
1203 =head2 freeze
1204
1205 This doesn't actually do anything more than call L<Storable/nfreeze>, it is just
1206 provided here for symmetry.
1207
1208 =cut
1209
1210 sub freeze {
1211   return Storable::nfreeze($_[1]);
1212 }
1213
1214 =head2 dclone
1215
1216 =over 4
1217
1218 =item Arguments: $object
1219
1220 =item Return Value: dcloned $object
1221
1222 =back
1223
1224 Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1225 objects so their references to the schema object
1226 (which itself is B<not> cloned) are properly maintained.
1227
1228 =cut
1229
1230 sub dclone {
1231   my ($self, $obj) = @_;
1232   local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1233   return Storable::dclone($obj);
1234 }
1235
1236 =head2 schema_version
1237
1238 Returns the current schema class' $VERSION in a normalised way.
1239
1240 =cut
1241
1242 sub schema_version {
1243   my ($self) = @_;
1244   my $class = ref($self)||$self;
1245
1246   # does -not- use $schema->VERSION
1247   # since that varies in results depending on if version.pm is installed, and if
1248   # so the perl or XS versions. If you want this to change, bug the version.pm
1249   # author to make vpp and vxs behave the same.
1250
1251   my $version;
1252   {
1253     no strict 'refs';
1254     $version = ${"${class}::VERSION"};
1255   }
1256   return $version;
1257 }
1258
1259
1260 =head2 register_class
1261
1262 =over 4
1263
1264 =item Arguments: $moniker, $component_class
1265
1266 =back
1267
1268 This method is called by L</load_namespaces> and L</load_classes> to install the found classes into your Schema. You should be using those instead of this one.
1269
1270 You will only need this method if you have your Result classes in
1271 files which are not named after the packages (or all in the same
1272 file). You may also need it to register classes at runtime.
1273
1274 Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1275 calling:
1276
1277   $schema->register_source($moniker, $component_class->result_source_instance);
1278
1279 =cut
1280
1281 sub register_class {
1282   my ($self, $moniker, $to_register) = @_;
1283   $self->register_source($moniker => $to_register->result_source_instance);
1284 }
1285
1286 =head2 register_source
1287
1288 =over 4
1289
1290 =item Arguments: $moniker, $result_source
1291
1292 =back
1293
1294 This method is called by L</register_class>.
1295
1296 Registers the L<DBIx::Class::ResultSource> in the schema with the given
1297 moniker.
1298
1299 =cut
1300
1301 sub register_source {
1302   my $self = shift;
1303
1304   $self->_register_source(@_);
1305 }
1306
1307 =head2 unregister_source
1308
1309 =over 4
1310
1311 =item Arguments: $moniker
1312
1313 =back
1314
1315 Removes the L<DBIx::Class::ResultSource> from the schema for the given moniker.
1316
1317 =cut
1318
1319 sub unregister_source {
1320   my $self = shift;
1321
1322   $self->_unregister_source(@_);
1323 }
1324
1325 =head2 register_extra_source
1326
1327 =over 4
1328
1329 =item Arguments: $moniker, $result_source
1330
1331 =back
1332
1333 As L</register_source> but should be used if the result class already
1334 has a source and you want to register an extra one.
1335
1336 =cut
1337
1338 sub register_extra_source {
1339   my $self = shift;
1340
1341   $self->_register_source(@_, { extra => 1 });
1342 }
1343
1344 sub _register_source {
1345   my ($self, $moniker, $source, $params) = @_;
1346
1347   my $orig_source = $source;
1348
1349   $source = $source->new({ %$source, source_name => $moniker });
1350   $source->schema($self);
1351   weaken $source->{schema} if ref($self);
1352
1353   my $rs_class = $source->result_class;
1354
1355   my %reg = %{$self->source_registrations};
1356   $reg{$moniker} = $source;
1357   $self->source_registrations(\%reg);
1358
1359   return if ($params->{extra});
1360   return unless defined($rs_class) && $rs_class->can('result_source_instance');
1361
1362   my %map = %{$self->class_mappings};
1363   if (
1364     exists $map{$rs_class}
1365       and
1366     $map{$rs_class} ne $moniker
1367       and
1368     $rs_class->result_source_instance ne $orig_source
1369   ) {
1370     carp "$rs_class already has a source, use register_extra_source for additional sources";
1371   }
1372   $map{$rs_class} = $moniker;
1373   $self->class_mappings(\%map);
1374 }
1375
1376 {
1377   my $global_phase_destroy;
1378
1379   END { $global_phase_destroy++ }
1380
1381   sub DESTROY {
1382     return if $global_phase_destroy;
1383
1384     my $self = shift;
1385     my $srcs = $self->source_registrations;
1386
1387     for my $moniker (keys %$srcs) {
1388       # find first source that is not about to be GCed (someone other than $self
1389       # holds a reference to it) and reattach to it, weakening our own link
1390       if (ref $srcs->{$moniker} and svref_2object($srcs->{$moniker})->REFCNT > 1) {
1391         $srcs->{$moniker}->schema($self);
1392         weaken $srcs->{$moniker};
1393         last;
1394       }
1395     }
1396   }
1397 }
1398
1399 sub _unregister_source {
1400     my ($self, $moniker) = @_;
1401     my %reg = %{$self->source_registrations};
1402
1403     my $source = delete $reg{$moniker};
1404     $self->source_registrations(\%reg);
1405     if ($source->result_class) {
1406         my %map = %{$self->class_mappings};
1407         delete $map{$source->result_class};
1408         $self->class_mappings(\%map);
1409     }
1410 }
1411
1412
1413 =head2 compose_connection (DEPRECATED)
1414
1415 =over 4
1416
1417 =item Arguments: $target_namespace, @db_info
1418
1419 =item Return Value: $new_schema
1420
1421 =back
1422
1423 DEPRECATED. You probably wanted compose_namespace.
1424
1425 Actually, you probably just wanted to call connect.
1426
1427 =begin hidden
1428
1429 (hidden due to deprecation)
1430
1431 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1432 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1433 then injects the L<DBix::Class::ResultSetProxy> component and a
1434 resultset_instance classdata entry on all the new classes, in order to support
1435 $target_namespaces::$class->search(...) method calls.
1436
1437 This is primarily useful when you have a specific need for class method access
1438 to a connection. In normal usage it is preferred to call
1439 L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1440 on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1441 more information.
1442
1443 =end hidden
1444
1445 =cut
1446
1447 {
1448   my $warn;
1449
1450   sub compose_connection {
1451     my ($self, $target, @info) = @_;
1452
1453     carp "compose_connection deprecated as of 0.08000"
1454       unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1455
1456     my $base = 'DBIx::Class::ResultSetProxy';
1457     try {
1458       eval "require ${base};"
1459     }
1460     catch {
1461       $self->throw_exception
1462         ("No arguments to load_classes and couldn't load ${base} ($_)")
1463     };
1464
1465     if ($self eq $target) {
1466       # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1467       foreach my $moniker ($self->sources) {
1468         my $source = $self->source($moniker);
1469         my $class = $source->result_class;
1470         $self->inject_base($class, $base);
1471         $class->mk_classdata(resultset_instance => $source->resultset);
1472         $class->mk_classdata(class_resolver => $self);
1473       }
1474       $self->connection(@info);
1475       return $self;
1476     }
1477
1478     my $schema = $self->compose_namespace($target, $base);
1479     {
1480       no strict 'refs';
1481       my $name = join '::', $target, 'schema';
1482       *$name = subname $name, sub { $schema };
1483     }
1484
1485     $schema->connection(@info);
1486     foreach my $moniker ($schema->sources) {
1487       my $source = $schema->source($moniker);
1488       my $class = $source->result_class;
1489       #warn "$moniker $class $source ".$source->storage;
1490       $class->mk_classdata(result_source_instance => $source);
1491       $class->mk_classdata(resultset_instance => $source->resultset);
1492       $class->mk_classdata(class_resolver => $schema);
1493     }
1494     return $schema;
1495   }
1496 }
1497
1498 1;
1499
1500 =head1 AUTHORS
1501
1502 Matt S. Trout <mst@shadowcatsystems.co.uk>
1503
1504 =head1 LICENSE
1505
1506 You may distribute this code under the same terms as Perl itself.
1507
1508 =cut