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