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