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