1 package DBIx::Class::Schema;
6 use DBIx::Class::Exception;
9 use Scalar::Util 'weaken';
10 use Sub::Name 'subname';
11 use B 'svref_2object';
14 use base qw/DBIx::Class/;
16 __PACKAGE__->mk_classdata('class_mappings' => {});
17 __PACKAGE__->mk_classdata('source_registrations' => {});
18 __PACKAGE__->mk_classdata('storage_type' => '::DBI');
19 __PACKAGE__->mk_classdata('storage');
20 __PACKAGE__->mk_classdata('exception_action');
21 __PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
22 __PACKAGE__->mk_classdata('default_resultset_attributes' => {});
26 DBIx::Class::Schema - composable schemas
30 package Library::Schema;
31 use base qw/DBIx::Class::Schema/;
33 # load all Result classes in Library/Schema/Result/
34 __PACKAGE__->load_namespaces();
36 package Library::Schema::Result::CD;
37 use base qw/DBIx::Class::Core/;
39 __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
40 __PACKAGE__->table('cd');
42 # Elsewhere in your code:
43 my $schema1 = Library::Schema->connect(
50 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
52 # fetch objects using Library::Schema::Result::DVD
53 my $resultset = $schema1->resultset('DVD')->search( ... );
54 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
58 Creates database classes based on a schema. This is the recommended way to
59 use L<DBIx::Class> and allows you to use more than one concurrent connection
62 NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
63 carefully, as DBIx::Class does things a little differently. Note in
64 particular which module inherits off which.
68 =head2 load_namespaces
72 =item Arguments: %options?
76 __PACKAGE__->load_namespaces();
78 __PACKAGE__->load_namespaces(
79 result_namespace => 'Res',
80 resultset_namespace => 'RSet',
81 default_resultset_class => '+MyDB::Othernamespace::RSet',
84 With no arguments, this method uses L<Module::Find> to load all of the
85 Result and ResultSet classes under the namespace of the schema from
86 which it is called. For example, C<My::Schema> will by default find
87 and load Result classes named C<My::Schema::Result::*> and ResultSet
88 classes named C<My::Schema::ResultSet::*>.
90 ResultSet classes are associated with Result class of the same name.
91 For example, C<My::Schema::Result::CD> will get the ResultSet class
92 C<My::Schema::ResultSet::CD> if it is present.
94 Both Result and ResultSet namespaces are configurable via the
95 C<result_namespace> and C<resultset_namespace> options.
97 Another option, C<default_resultset_class> specifies a custom default
98 ResultSet class for Result classes with no corresponding ResultSet.
100 All of the namespace and classname options are by default relative to
101 the schema classname. To specify a fully-qualified name, prefix it
102 with a literal C<+>. For example, C<+Other::NameSpace::Result>.
106 You will be warned if ResultSet classes are discovered for which there
107 are no matching Result classes like this:
109 load_namespaces found ResultSet class $classname with no corresponding Result class
111 If a Result class is found to already have a ResultSet class set using
112 L</resultset_class> to some other class, you will be warned like this:
114 We found ResultSet class '$rs_class' for '$result', but it seems
115 that you had already set '$result' to use '$rs_set' instead
119 # load My::Schema::Result::CD, My::Schema::Result::Artist,
120 # My::Schema::ResultSet::CD, etc...
121 My::Schema->load_namespaces;
123 # Override everything to use ugly names.
124 # In this example, if there is a My::Schema::Res::Foo, but no matching
125 # My::Schema::RSets::Foo, then Foo will have its
126 # resultset_class set to My::Schema::RSetBase
127 My::Schema->load_namespaces(
128 result_namespace => 'Res',
129 resultset_namespace => 'RSets',
130 default_resultset_class => 'RSetBase',
133 # Put things in other namespaces
134 My::Schema->load_namespaces(
135 result_namespace => '+Some::Place::Results',
136 resultset_namespace => '+Another::Place::RSets',
139 To search multiple namespaces for either Result or ResultSet classes,
140 use an arrayref of namespaces for that option. In the case that the
141 same result (or resultset) class exists in multiple namespaces, later
142 entries in the list of namespaces will override earlier ones.
144 My::Schema->load_namespaces(
145 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
146 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
147 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
152 # Pre-pends our classname to the given relative classname or
153 # class namespace, unless there is a '+' prefix, which will
155 sub _expand_relative_name {
156 my ($class, $name) = @_;
158 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
162 # Finds all modules in the supplied namespace, or if omitted in the
163 # namespace of $class. Untaints all findings as they can be assumed
167 my $ns = shift || ref $proto || $proto;
169 require Module::Find;
170 my @mods = Module::Find::findallmod($ns);
172 # try to untaint module names. mods where this fails
173 # are left alone so we don't have to change the old behavior
174 no locale; # localized \w doesn't untaint expression
175 return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
178 # returns a hash of $shortname => $fullname for every package
179 # found in the given namespaces ($shortname is with the $fullname's
180 # namespace stripped off)
181 sub _map_namespaces {
182 my ($class, @namespaces) = @_;
185 foreach my $namespace (@namespaces) {
188 map { (substr($_, length "${namespace}::"), $_) }
189 $class->_findallmod($namespace)
196 # returns the result_source_instance for the passed class/object,
197 # or dies with an informative message (used by load_namespaces)
198 sub _ns_get_rsrc_instance {
200 my $rs_class = ref ($_[0]) || $_[0];
203 $rs_class->result_source_instance
205 $me->throw_exception (
206 "Attempt to load_namespaces() class $rs_class failed - are you sure this is a real Result Class?: $_"
211 sub load_namespaces {
212 my ($class, %args) = @_;
214 my $result_namespace = delete $args{result_namespace} || 'Result';
215 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
216 my $default_resultset_class = delete $args{default_resultset_class};
218 $class->throw_exception('load_namespaces: unknown option(s): '
219 . join(q{,}, map { qq{'$_'} } keys %args))
220 if scalar keys %args;
222 $default_resultset_class
223 = $class->_expand_relative_name($default_resultset_class);
225 for my $arg ($result_namespace, $resultset_namespace) {
226 $arg = [ $arg ] if !ref($arg) && $arg;
228 $class->throw_exception('load_namespaces: namespace arguments must be '
229 . 'a simple string or an arrayref')
230 if ref($arg) ne 'ARRAY';
232 $_ = $class->_expand_relative_name($_) for (@$arg);
235 my %results = $class->_map_namespaces(@$result_namespace);
236 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
240 no warnings qw/redefine/;
241 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
242 use warnings qw/redefine/;
244 # ensure classes are loaded and attached in inheritance order
245 for my $res (values %results) {
246 $class->ensure_class_loaded($res);
249 my @subclass_last = sort {
252 scalar @{mro::get_linear_isa( $results{$a} )}
258 scalar @{mro::get_linear_isa( $results{$b} )}
263 foreach my $result (@subclass_last) {
264 my $result_class = $results{$result};
266 my $rs_class = delete $resultsets{$result};
267 my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
269 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
270 if($rs_class && $rs_class ne $rs_set) {
271 carp "We found ResultSet class '$rs_class' for '$result', but it seems "
272 . "that you had already set '$result' to use '$rs_set' instead";
275 elsif($rs_class ||= $default_resultset_class) {
276 $class->ensure_class_loaded($rs_class);
277 if(!$rs_class->isa("DBIx::Class::ResultSet")) {
278 carp "load_namespaces found ResultSet class $rs_class that does not subclass DBIx::Class::ResultSet";
281 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($rs_class);
284 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $result;
286 push(@to_register, [ $source_name, $result_class ]);
290 foreach (sort keys %resultsets) {
291 carp "load_namespaces found ResultSet class $_ with no "
292 . 'corresponding Result class';
295 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
297 $class->register_class(@$_) for (@to_register);
306 =item Arguments: @classes?, { $namespace => [ @classes ] }+
310 L</load_classes> is an alternative method to L</load_namespaces>, both of
311 which serve similar purposes, each with different advantages and disadvantages.
312 In the general case you should use L</load_namespaces>, unless you need to
313 be able to specify that only specific classes are loaded at runtime.
315 With no arguments, this method uses L<Module::Find> to find all classes under
316 the schema's namespace. Otherwise, this method loads the classes you specify
317 (using L<use>), and registers them (using L</"register_class">).
319 It is possible to comment out classes with a leading C<#>, but note that perl
320 will think it's a mistake (trying to use a comment in a qw list), so you'll
321 need to add C<no warnings 'qw';> before your load_classes call.
323 If any classes found do not appear to be Result class files, you will
324 get the following warning:
326 Failed to load $comp_class. Can't find source_name method. Is
327 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
328 or make your load_classes call more specific.
332 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
333 # etc. (anything under the My::Schema namespace)
335 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
336 # not Other::Namespace::LinerNotes nor My::Schema::Track
337 My::Schema->load_classes(qw/ CD Artist #Track /, {
338 Other::Namespace => [qw/ Producer #LinerNotes /],
344 my ($class, @params) = @_;
349 foreach my $param (@params) {
350 if (ref $param eq 'ARRAY') {
351 # filter out commented entries
352 my @modules = grep { $_ !~ /^#/ } @$param;
354 push (@{$comps_for{$class}}, @modules);
356 elsif (ref $param eq 'HASH') {
357 # more than one namespace possible
358 for my $comp ( keys %$param ) {
359 # filter out commented entries
360 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
362 push (@{$comps_for{$comp}}, @modules);
366 # filter out commented entries
367 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
371 my @comp = map { substr $_, length "${class}::" }
373 $comps_for{$class} = \@comp;
378 no warnings qw/redefine/;
379 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
380 use warnings qw/redefine/;
382 foreach my $prefix (keys %comps_for) {
383 foreach my $comp (@{$comps_for{$prefix}||[]}) {
384 my $comp_class = "${prefix}::${comp}";
385 $class->ensure_class_loaded($comp_class);
387 my $snsub = $comp_class->can('source_name');
389 carp "Failed to load $comp_class. Can't find source_name method. Is $comp_class really a full DBIC result class? Fix it, move it elsewhere, or make your load_classes call more specific.";
392 $comp = $snsub->($comp_class) || $comp;
394 push(@to_register, [ $comp, $comp_class ]);
398 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
400 foreach my $to (@to_register) {
401 $class->register_class(@$to);
409 =item Arguments: $storage_type|{$storage_type, \%args}
411 =item Return value: $storage_type|{$storage_type, \%args}
413 =item Default value: DBIx::Class::Storage::DBI
417 Set the storage class that will be instantiated when L</connect> is called.
418 If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
419 assumed by L</connect>.
421 You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
422 in cases where the appropriate subclass is not autodetected.
424 If your storage type requires instantiation arguments, those are
425 defined as a second argument in the form of a hashref and the entire
426 value needs to be wrapped into an arrayref or a hashref. We support
427 both types of refs here in order to play nice with your
428 Config::[class] or your choice. See
429 L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
431 =head2 exception_action
435 =item Arguments: $code_reference
437 =item Return value: $code_reference
439 =item Default value: None
443 When L</throw_exception> is invoked and L</exception_action> is set to a code
444 reference, this reference will be called instead of
445 L<DBIx::Class::Exception/throw>, with the exception message passed as the only
448 Your custom throw code B<must> rethrow the exception, as L</throw_exception> is
449 an integral part of DBIC's internal execution control flow.
454 use base qw/DBIx::Class::Schema/;
455 use My::ExceptionClass;
456 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
457 __PACKAGE__->load_classes;
460 my $schema_obj = My::Schema->connect( .... );
461 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
467 =item Arguments: boolean
471 Whether L</throw_exception> should include stack trace information.
472 Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
475 =head2 sqlt_deploy_hook
479 =item Arguments: $sqlt_schema
483 An optional sub which you can declare in your own Schema class that will get
484 passed the L<SQL::Translator::Schema> object when you deploy the schema via
485 L</create_ddl_dir> or L</deploy>.
487 For an example of what you can do with this, see
488 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
490 Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
491 is called before L</deploy>. Therefore the hook can be used only to manipulate
492 the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
493 database. If you want to execute post-deploy statements which can not be generated
494 by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
495 and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
503 =item Arguments: @connectinfo
505 =item Return Value: $new_schema
509 Creates and returns a new Schema object. The connection info set on it
510 is used to create a new instance of the storage backend and set it on
513 See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
514 syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
517 Note that C<connect_info> expects an arrayref of arguments, but
518 C<connect> does not. C<connect> wraps its arguments in an arrayref
519 before passing them to C<connect_info>.
523 C<connect> is a convenience method. It is equivalent to calling
524 $schema->clone->connection(@connectinfo). To write your own overloaded
525 version, overload L</connection> instead.
529 sub connect { shift->clone->connection(@_) }
535 =item Arguments: $source_name
537 =item Return Value: $resultset
541 my $rs = $schema->resultset('DVD');
543 Returns the L<DBIx::Class::ResultSet> object for the registered source
549 my ($self, $moniker) = @_;
550 $self->throw_exception('resultset() expects a source name')
551 unless defined $moniker;
552 return $self->source($moniker)->resultset;
559 =item Return Value: @source_names
563 my @source_names = $schema->sources;
565 Lists names of all the sources registered on this Schema object.
569 sub sources { return keys %{shift->source_registrations}; }
575 =item Arguments: $source_name
577 =item Return Value: $result_source
581 my $source = $schema->source('Book');
583 Returns the L<DBIx::Class::ResultSource> object for the registered
591 $self->throw_exception("source() expects a source name")
596 my $sreg = $self->source_registrations;
597 return $sreg->{$moniker} if exists $sreg->{$moniker};
599 # if we got here, they probably passed a full class name
600 my $mapped = $self->class_mappings->{$moniker};
601 $self->throw_exception("Can't find source for ${moniker}")
602 unless $mapped && exists $sreg->{$mapped};
603 return $sreg->{$mapped};
610 =item Arguments: $source_name
612 =item Return Value: $classname
616 my $class = $schema->class('CD');
618 Retrieves the Result class name for the given source name.
623 my ($self, $moniker) = @_;
624 return $self->source($moniker)->result_class;
631 =item Arguments: C<$coderef>, @coderef_args?
633 =item Return Value: The return value of $coderef
637 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
638 returning its result (if any). Equivalent to calling $schema->storage->txn_do.
639 See L<DBIx::Class::Storage/"txn_do"> for more information.
641 This interface is preferred over using the individual methods L</txn_begin>,
642 L</txn_commit>, and L</txn_rollback> below.
644 WARNING: If you are connected with C<< AutoCommit => 0 >> the transaction is
645 considered nested, and you will still need to call L</txn_commit> to write your
646 changes when appropriate. You will also want to connect with C<< auto_savepoint =>
647 1 >> to get partial rollback to work, if the storage driver for your database
650 Connecting with C<< AutoCommit => 1 >> is recommended.
657 $self->storage or $self->throw_exception
658 ('txn_do called on $schema without storage');
660 $self->storage->txn_do(@_);
663 =head2 txn_scope_guard
665 Runs C<txn_scope_guard> on the schema's storage. See
666 L<DBIx::Class::Storage/txn_scope_guard>.
670 sub txn_scope_guard {
673 $self->storage or $self->throw_exception
674 ('txn_scope_guard called on $schema without storage');
676 $self->storage->txn_scope_guard(@_);
681 Begins a transaction (does nothing if AutoCommit is off). Equivalent to
682 calling $schema->storage->txn_begin. See
683 L<DBIx::Class::Storage/"txn_begin"> for more information.
690 $self->storage or $self->throw_exception
691 ('txn_begin called on $schema without storage');
693 $self->storage->txn_begin;
698 Commits the current transaction. Equivalent to calling
699 $schema->storage->txn_commit. See L<DBIx::Class::Storage/"txn_commit">
700 for more information.
707 $self->storage or $self->throw_exception
708 ('txn_commit called on $schema without storage');
710 $self->storage->txn_commit;
715 Rolls back the current transaction. Equivalent to calling
716 $schema->storage->txn_rollback. See
717 L<DBIx::Class::Storage/"txn_rollback"> for more information.
724 $self->storage or $self->throw_exception
725 ('txn_rollback called on $schema without storage');
727 $self->storage->txn_rollback;
732 my $storage = $schema->storage;
734 Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
735 if you want to turn on SQL statement debugging at runtime, or set the
736 quote character. For the default storage, the documentation can be
737 found in L<DBIx::Class::Storage::DBI>.
743 =item Arguments: $source_name, \@data;
745 =item Return value: \@$objects | nothing
749 Pass this method a resultsource name, and an arrayref of
750 arrayrefs. The arrayrefs should contain a list of column names,
751 followed by one or many sets of matching data for the given columns.
753 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
754 to insert the data, as this is a fast method. However, insert_bulk currently
755 assumes that your datasets all contain the same type of values, using scalar
756 references in a column in one row, and not in another will probably not work.
758 Otherwise, each set of data is inserted into the database using
759 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
764 $schema->populate('Artist', [
765 [ qw/artistid name/ ],
766 [ 1, 'Popular Band' ],
771 Since wantarray context is basically the same as looping over $rs->create(...)
772 you won't see any performance benefits and in this case the method is more for
773 convenience. Void context sends the column information directly to storage
774 using <DBI>s bulk insert method. So the performance will be much better for
775 storages that support this method.
777 Because of this difference in the way void context inserts rows into your
778 database you need to note how this will effect any loaded components that
779 override or augment insert. For example if you are using a component such
780 as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
781 wantarray context if you want the PKs automatically created.
786 my ($self, $name, $data) = @_;
787 if(my $rs = $self->resultset($name)) {
788 if(defined wantarray) {
789 return $rs->populate($data);
791 $rs->populate($data);
794 $self->throw_exception("$name is not a resultset");
802 =item Arguments: @args
804 =item Return Value: $new_schema
808 Similar to L</connect> except sets the storage object and connection
809 data in-place on the Schema class. You should probably be calling
810 L</connect> to get a proper Schema object instead.
814 Overload C<connection> to change the behaviour of C<connect>.
819 my ($self, @info) = @_;
820 return $self if !@info && $self->storage;
822 my ($storage_class, $args) = ref $self->storage_type ?
823 ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
825 $storage_class = 'DBIx::Class::Storage'.$storage_class
826 if $storage_class =~ m/^::/;
828 $self->ensure_class_loaded ($storage_class);
831 $self->throw_exception(
832 "Unable to load storage class ${storage_class}: $_"
835 my $storage = $storage_class->new($self=>$args);
836 $storage->connect_info(\@info);
837 $self->storage($storage);
841 sub _normalize_storage_type {
842 my ($self, $storage_type) = @_;
843 if(ref $storage_type eq 'ARRAY') {
844 return @$storage_type;
845 } elsif(ref $storage_type eq 'HASH') {
846 return %$storage_type;
848 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
852 =head2 compose_namespace
856 =item Arguments: $target_namespace, $additional_base_class?
858 =item Retur Value: $new_schema
862 For each L<DBIx::Class::ResultSource> in the schema, this method creates a
863 class in the target namespace (e.g. $target_namespace::CD,
864 $target_namespace::Artist) that inherits from the corresponding classes
865 attached to the current schema.
867 It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
868 new $schema object. If C<$additional_base_class> is given, the new composed
869 classes will inherit from first the corresponding class from the current
870 schema then the base class.
872 For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
874 $schema->compose_namespace('My::DB', 'Base::Class');
875 print join (', ', @My::DB::CD::ISA) . "\n";
876 print join (', ', @My::DB::Artist::ISA) ."\n";
878 will produce the output
880 My::Schema::CD, Base::Class
881 My::Schema::Artist, Base::Class
885 # this might be oversimplified
886 # sub compose_namespace {
887 # my ($self, $target, $base) = @_;
889 # my $schema = $self->clone;
890 # foreach my $moniker ($schema->sources) {
891 # my $source = $schema->source($moniker);
892 # my $target_class = "${target}::${moniker}";
893 # $self->inject_base(
894 # $target_class => $source->result_class, ($base ? $base : ())
896 # $source->result_class($target_class);
897 # $target_class->result_source_instance($source)
898 # if $target_class->can('result_source_instance');
899 # $schema->register_source($moniker, $source);
904 sub compose_namespace {
905 my ($self, $target, $base) = @_;
907 my $schema = $self->clone;
909 $schema->source_registrations({});
911 # the original class-mappings must remain - otherwise
912 # reverse_relationship_info will not work
913 #$schema->class_mappings({});
916 no warnings qw/redefine/;
917 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
918 use warnings qw/redefine/;
921 foreach my $moniker ($self->sources) {
922 my $orig_source = $self->source($moniker);
924 my $target_class = "${target}::${moniker}";
925 $self->inject_base($target_class, $orig_source->result_class, ($base || ()) );
927 # register_source examines result_class, and then returns us a clone
928 my $new_source = $schema->register_source($moniker, bless
929 { %$orig_source, result_class => $target_class },
933 if ($target_class->can('result_source_instance')) {
934 # give the class a schema-less source copy
935 $target_class->result_source_instance( bless
936 { %$new_source, schema => ref $new_source->{schema} || $new_source->{schema} },
942 foreach my $meth (qw/class source resultset/) {
943 no warnings 'redefine';
944 *{"${target}::${meth}"} = subname "${target}::${meth}" =>
945 sub { shift->schema->$meth(@_) };
949 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
954 sub setup_connection_class {
955 my ($class, $target, @info) = @_;
956 $class->inject_base($target => 'DBIx::Class::DB');
957 #$target->load_components('DB');
958 $target->connection(@info);
963 Creates a new savepoint (does nothing outside a transaction).
964 Equivalent to calling $schema->storage->svp_begin. See
965 L<DBIx::Class::Storage/"svp_begin"> for more information.
970 my ($self, $name) = @_;
972 $self->storage or $self->throw_exception
973 ('svp_begin called on $schema without storage');
975 $self->storage->svp_begin($name);
980 Releases a savepoint (does nothing outside a transaction).
981 Equivalent to calling $schema->storage->svp_release. See
982 L<DBIx::Class::Storage/"svp_release"> for more information.
987 my ($self, $name) = @_;
989 $self->storage or $self->throw_exception
990 ('svp_release called on $schema without storage');
992 $self->storage->svp_release($name);
997 Rollback to a savepoint (does nothing outside a transaction).
998 Equivalent to calling $schema->storage->svp_rollback. See
999 L<DBIx::Class::Storage/"svp_rollback"> for more information.
1004 my ($self, $name) = @_;
1006 $self->storage or $self->throw_exception
1007 ('svp_rollback called on $schema without storage');
1009 $self->storage->svp_rollback($name);
1016 =item Arguments: %attrs?
1018 =item Return Value: $new_schema
1022 Clones the schema and its associated result_source objects and returns the
1023 copy. The resulting copy will have the same attributes as the source schema,
1024 except for those attributes explicitly overriden by the provided C<%attrs>.
1032 (ref $self ? %$self : ()),
1033 (@_ == 1 && ref $_[0] eq 'HASH' ? %{ $_[0] } : @_),
1035 bless $clone, (ref $self || $self);
1037 $clone->class_mappings({ %{$clone->class_mappings} });
1038 $clone->source_registrations({ %{$clone->source_registrations} });
1039 foreach my $moniker ($self->sources) {
1040 my $source = $self->source($moniker);
1041 my $new = $source->new($source);
1042 # we use extra here as we want to leave the class_mappings as they are
1043 # but overwrite the source_registrations entry with the new source
1044 $clone->register_extra_source($moniker => $new);
1046 $clone->storage->set_schema($clone) if $clone->storage;
1051 =head2 throw_exception
1055 =item Arguments: $message
1059 Throws an exception. Obeys the exemption rules of L<DBIx::Class::Carp> to report
1060 errors from outer-user's perspective. See L</exception_action> for details on overriding
1061 this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1062 default behavior will provide a detailed stack trace.
1066 my $false_exception_action_warned;
1067 sub throw_exception {
1070 if (my $act = $self->exception_action) {
1072 DBIx::Class::Exception->throw(
1073 "Invocation of the exception_action handler installed on $self did *not*"
1074 .' result in an exception. DBIx::Class is unable to function without a reliable'
1075 .' exception mechanism, ensure that exception_action does not hide exceptions'
1076 ." (original error: $_[0])"
1079 elsif(! $false_exception_action_warned++) {
1081 "The exception_action handler installed on $self returned false instead"
1082 .' of throwing an exception. This behavior has been deprecated, adjust your'
1083 .' handler to always rethrow the supplied error.'
1088 DBIx::Class::Exception->throw($_[0], $self->stacktrace);
1095 =item Arguments: \%sqlt_args, $dir
1099 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
1101 See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1102 The most common value for this would be C<< { add_drop_table => 1 } >>
1103 to have the SQL produced include a C<DROP TABLE> statement for each table
1104 created. For quoting purposes supply C<quote_table_names> and
1105 C<quote_field_names>.
1107 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1108 ref or an array ref, containing a list of source to deploy. If present, then
1109 only the sources listed will get deployed. Furthermore, you can use the
1110 C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1116 my ($self, $sqltargs, $dir) = @_;
1117 $self->throw_exception("Can't deploy without storage") unless $self->storage;
1118 $self->storage->deploy($self, undef, $sqltargs, $dir);
1121 =head2 deployment_statements
1125 =item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
1127 =item Return value: $listofstatements
1131 A convenient shortcut to
1132 C<< $self->storage->deployment_statements($self, @args) >>.
1133 Returns the SQL statements used by L</deploy> and
1134 L<DBIx::Class::Schema::Storage/deploy>.
1138 sub deployment_statements {
1141 $self->throw_exception("Can't generate deployment statements without a storage")
1142 if not $self->storage;
1144 $self->storage->deployment_statements($self, @_);
1147 =head2 create_ddl_dir
1151 =item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
1155 A convenient shortcut to
1156 C<< $self->storage->create_ddl_dir($self, @args) >>.
1158 Creates an SQL file based on the Schema, for each of the specified
1159 database types, in the given directory.
1163 sub create_ddl_dir {
1166 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1167 $self->storage->create_ddl_dir($self, @_);
1174 =item Arguments: $database-type, $version, $directory, $preversion
1176 =item Return value: $normalised_filename
1180 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
1182 This method is called by C<create_ddl_dir> to compose a file name out of
1183 the supplied directory, database type and version number. The default file
1184 name format is: C<$dir$schema-$version-$type.sql>.
1186 You may override this method in your schema if you wish to use a different
1191 Prior to DBIx::Class version 0.08100 this method had a different signature:
1193 my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1195 In recent versions variables $dir and $version were reversed in order to
1196 bring the signature in line with other Schema/Storage methods. If you
1197 really need to maintain backward compatibility, you can do the following
1198 in any overriding methods:
1200 ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1205 my ($self, $type, $version, $dir, $preversion) = @_;
1209 my $filename = ref($self);
1210 $filename =~ s/::/-/g;
1211 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1212 $filename =~ s/$version/$preversion-$version/ if($preversion);
1219 Provided as the recommended way of thawing schema objects. You can call
1220 C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1221 reference to any schema, so are rather useless.
1226 my ($self, $obj) = @_;
1227 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1229 return Storable::thaw($obj);
1234 This doesn't actually do anything more than call L<Storable/nfreeze>, it is just
1235 provided here for symmetry.
1241 return Storable::nfreeze($_[1]);
1248 =item Arguments: $object
1250 =item Return Value: dcloned $object
1254 Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1255 objects so their references to the schema object
1256 (which itself is B<not> cloned) are properly maintained.
1261 my ($self, $obj) = @_;
1262 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1264 return Storable::dclone($obj);
1267 =head2 schema_version
1269 Returns the current schema class' $VERSION in a normalised way.
1273 sub schema_version {
1275 my $class = ref($self)||$self;
1277 # does -not- use $schema->VERSION
1278 # since that varies in results depending on if version.pm is installed, and if
1279 # so the perl or XS versions. If you want this to change, bug the version.pm
1280 # author to make vpp and vxs behave the same.
1285 $version = ${"${class}::VERSION"};
1291 =head2 register_class
1295 =item Arguments: $moniker, $component_class
1299 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.
1301 You will only need this method if you have your Result classes in
1302 files which are not named after the packages (or all in the same
1303 file). You may also need it to register classes at runtime.
1305 Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1308 $schema->register_source($moniker, $component_class->result_source_instance);
1312 sub register_class {
1313 my ($self, $moniker, $to_register) = @_;
1314 $self->register_source($moniker => $to_register->result_source_instance);
1317 =head2 register_source
1321 =item Arguments: $moniker, $result_source
1325 This method is called by L</register_class>.
1327 Registers the L<DBIx::Class::ResultSource> in the schema with the given
1332 sub register_source { shift->_register_source(@_) }
1334 =head2 unregister_source
1338 =item Arguments: $moniker
1342 Removes the L<DBIx::Class::ResultSource> from the schema for the given moniker.
1346 sub unregister_source { shift->_unregister_source(@_) }
1348 =head2 register_extra_source
1352 =item Arguments: $moniker, $result_source
1356 As L</register_source> but should be used if the result class already
1357 has a source and you want to register an extra one.
1361 sub register_extra_source { shift->_register_source(@_, { extra => 1 }) }
1363 sub _register_source {
1364 my ($self, $moniker, $source, $params) = @_;
1366 $source = $source->new({ %$source, source_name => $moniker });
1368 $source->schema($self);
1369 weaken $source->{schema} if ref($self);
1371 my %reg = %{$self->source_registrations};
1372 $reg{$moniker} = $source;
1373 $self->source_registrations(\%reg);
1375 return $source if $params->{extra};
1377 my $rs_class = $source->result_class;
1378 if ($rs_class and my $rsrc = try { $rs_class->result_source_instance } ) {
1379 my %map = %{$self->class_mappings};
1381 exists $map{$rs_class}
1383 $map{$rs_class} ne $moniker
1385 $rsrc ne $_[2] # orig_source
1388 "$rs_class already had a registered source which was replaced by this call. "
1389 . 'Perhaps you wanted register_extra_source(), though it is more likely you did '
1390 . 'something wrong.'
1394 $map{$rs_class} = $moniker;
1395 $self->class_mappings(\%map);
1402 my $global_phase_destroy;
1404 # SpeedyCGI runs END blocks every cycle but keeps object instances
1405 # hence we have to disable the globaldestroy hatch, and rely on the
1406 # eval trap below (which appears to work, but is risky done so late)
1407 END { $global_phase_destroy = 1 unless $CGI::SpeedyCGI::i_am_speedy }
1410 return if $global_phase_destroy;
1413 my $srcs = $self->source_registrations;
1415 for my $moniker (keys %$srcs) {
1416 # find first source that is not about to be GCed (someone other than $self
1417 # holds a reference to it) and reattach to it, weakening our own link
1419 # during global destruction (if we have not yet bailed out) this will throw
1420 # which will serve as a signal to not try doing anything else
1421 if (ref $srcs->{$moniker} and svref_2object($srcs->{$moniker})->REFCNT > 1) {
1424 $srcs->{$moniker}->schema($self);
1427 $global_phase_destroy = 1;
1431 weaken $srcs->{$moniker};
1438 sub _unregister_source {
1439 my ($self, $moniker) = @_;
1440 my %reg = %{$self->source_registrations};
1442 my $source = delete $reg{$moniker};
1443 $self->source_registrations(\%reg);
1444 if ($source->result_class) {
1445 my %map = %{$self->class_mappings};
1446 delete $map{$source->result_class};
1447 $self->class_mappings(\%map);
1452 =head2 compose_connection (DEPRECATED)
1456 =item Arguments: $target_namespace, @db_info
1458 =item Return Value: $new_schema
1462 DEPRECATED. You probably wanted compose_namespace.
1464 Actually, you probably just wanted to call connect.
1468 (hidden due to deprecation)
1470 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1471 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1472 then injects the L<DBix::Class::ResultSetProxy> component and a
1473 resultset_instance classdata entry on all the new classes, in order to support
1474 $target_namespaces::$class->search(...) method calls.
1476 This is primarily useful when you have a specific need for class method access
1477 to a connection. In normal usage it is preferred to call
1478 L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1479 on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1486 sub compose_connection {
1487 my ($self, $target, @info) = @_;
1489 carp_once "compose_connection deprecated as of 0.08000"
1490 unless $INC{"DBIx/Class/CDBICompat.pm"};
1492 my $base = 'DBIx::Class::ResultSetProxy';
1494 eval "require ${base};"
1497 $self->throw_exception
1498 ("No arguments to load_classes and couldn't load ${base} ($_)")
1501 if ($self eq $target) {
1502 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1503 foreach my $moniker ($self->sources) {
1504 my $source = $self->source($moniker);
1505 my $class = $source->result_class;
1506 $self->inject_base($class, $base);
1507 $class->mk_classdata(resultset_instance => $source->resultset);
1508 $class->mk_classdata(class_resolver => $self);
1510 $self->connection(@info);
1514 my $schema = $self->compose_namespace($target, $base);
1517 my $name = join '::', $target, 'schema';
1518 *$name = subname $name, sub { $schema };
1521 $schema->connection(@info);
1522 foreach my $moniker ($schema->sources) {
1523 my $source = $schema->source($moniker);
1524 my $class = $source->result_class;
1525 #warn "$moniker $class $source ".$source->storage;
1526 $class->mk_classdata(result_source_instance => $source);
1527 $class->mk_classdata(resultset_instance => $source->resultset);
1528 $class->mk_classdata(class_resolver => $schema);
1537 Matt S. Trout <mst@shadowcatsystems.co.uk>
1541 You may distribute this code under the same terms as Perl itself.