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