1 package DBIx::Class::Schema;
6 use base 'DBIx::Class';
11 use Scalar::Util qw/weaken blessed/;
12 use DBIx::Class::_Util qw(
13 refcount quote_sub scope_guard
14 is_exception dbic_internal_try
17 use Devel::GlobalDestruction;
20 __PACKAGE__->mk_group_accessors( inherited => qw( storage exception_action ) );
21 __PACKAGE__->mk_classaccessor('class_mappings' => {});
22 __PACKAGE__->mk_classaccessor('source_registrations' => {});
23 __PACKAGE__->mk_classaccessor('storage_type' => '::DBI');
24 __PACKAGE__->mk_classaccessor('stacktrace' => $ENV{DBIC_TRACE} || 0);
25 __PACKAGE__->mk_classaccessor('default_resultset_attributes' => {});
29 DBIx::Class::Schema - composable schemas
33 package Library::Schema;
34 use base qw/DBIx::Class::Schema/;
36 # load all Result classes in Library/Schema/Result/
37 __PACKAGE__->load_namespaces();
39 package Library::Schema::Result::CD;
40 use base qw/DBIx::Class::Core/;
42 __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
43 __PACKAGE__->table('cd');
45 # Elsewhere in your code:
46 my $schema1 = Library::Schema->connect(
53 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
55 # fetch objects using Library::Schema::Result::DVD
56 my $resultset = $schema1->resultset('DVD')->search( ... );
57 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
61 Creates database classes based on a schema. This is the recommended way to
62 use L<DBIx::Class> and allows you to use more than one concurrent connection
65 NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
66 carefully, as DBIx::Class does things a little differently. Note in
67 particular which module inherits off which.
71 =head2 load_namespaces
75 =item Arguments: %options?
79 package MyApp::Schema;
80 __PACKAGE__->load_namespaces();
82 __PACKAGE__->load_namespaces(
83 result_namespace => 'Res',
84 resultset_namespace => 'RSet',
85 default_resultset_class => '+MyApp::Othernamespace::RSet',
88 With no arguments, this method uses L<Module::Find> to load all of the
89 Result and ResultSet classes under the namespace of the schema from
90 which it is called. For example, C<My::Schema> will by default find
91 and load Result classes named C<My::Schema::Result::*> and ResultSet
92 classes named C<My::Schema::ResultSet::*>.
94 ResultSet classes are associated with Result class of the same name.
95 For example, C<My::Schema::Result::CD> will get the ResultSet class
96 C<My::Schema::ResultSet::CD> if it is present.
98 Both Result and ResultSet namespaces are configurable via the
99 C<result_namespace> and C<resultset_namespace> options.
101 Another option, C<default_resultset_class> specifies a custom default
102 ResultSet class for Result classes with no corresponding ResultSet.
104 All of the namespace and classname options are by default relative to
105 the schema classname. To specify a fully-qualified name, prefix it
106 with a literal C<+>. For example, C<+Other::NameSpace::Result>.
110 You will be warned if ResultSet classes are discovered for which there
111 are no matching Result classes like this:
113 load_namespaces found ResultSet class $classname with no corresponding Result class
115 If a ResultSource instance is found to already have a ResultSet class set
116 using L<resultset_class|DBIx::Class::ResultSource/resultset_class> to some
117 other class, you will be warned like this:
119 We found ResultSet class '$rs_class' for '$result_class', but it seems
120 that you had already set '$result_class' to use '$rs_set' instead
124 # load My::Schema::Result::CD, My::Schema::Result::Artist,
125 # My::Schema::ResultSet::CD, etc...
126 My::Schema->load_namespaces;
128 # Override everything to use ugly names.
129 # In this example, if there is a My::Schema::Res::Foo, but no matching
130 # My::Schema::RSets::Foo, then Foo will have its
131 # resultset_class set to My::Schema::RSetBase
132 My::Schema->load_namespaces(
133 result_namespace => 'Res',
134 resultset_namespace => 'RSets',
135 default_resultset_class => 'RSetBase',
138 # Put things in other namespaces
139 My::Schema->load_namespaces(
140 result_namespace => '+Some::Place::Results',
141 resultset_namespace => '+Another::Place::RSets',
144 To search multiple namespaces for either Result or ResultSet classes,
145 use an arrayref of namespaces for that option. In the case that the
146 same result (or resultset) class exists in multiple namespaces, later
147 entries in the list of namespaces will override earlier ones.
149 My::Schema->load_namespaces(
150 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
151 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
152 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
157 # Pre-pends our classname to the given relative classname or
158 # class namespace, unless there is a '+' prefix, which will
160 sub _expand_relative_name {
161 my ($class, $name) = @_;
162 $name =~ s/^\+// or $name = "${class}::${name}";
166 # Finds all modules in the supplied namespace, or if omitted in the
167 # namespace of $class. Untaints all findings as they can be assumed
170 require Module::Find;
172 { $_ =~ /(.+)/ } # untaint result
173 Module::Find::findallmod( $_[1] || ref $_[0] || $_[0] )
177 # returns a hash of $shortname => $fullname for every package
178 # found in the given namespaces ($shortname is with the $fullname's
179 # namespace stripped off)
180 sub _map_namespaces {
181 my ($me, $namespaces) = @_;
184 for my $ns (@$namespaces) {
185 $res{ substr($_, length "${ns}::") } = $_
186 for $me->_findallmod($ns);
192 # returns the result_source_instance for the passed class/object,
193 # or dies with an informative message (used by load_namespaces)
194 sub _ns_get_rsrc_instance {
196 my $rs_class = ref ($_[0]) || $_[0];
198 return dbic_internal_try {
199 $rs_class->result_source_instance
201 $me->throw_exception (
202 "Attempt to load_namespaces() class $rs_class failed - are you sure this is a real Result Class?: $_"
207 sub load_namespaces {
208 my ($class, %args) = @_;
210 my $result_namespace = delete $args{result_namespace} || 'Result';
211 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
213 my $default_resultset_class = delete $args{default_resultset_class};
215 $default_resultset_class = $class->_expand_relative_name($default_resultset_class)
216 if $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 for my $arg ($result_namespace, $resultset_namespace) {
223 $arg = [ $arg ] if ( $arg and ! ref $arg );
225 $class->throw_exception('load_namespaces: namespace arguments must be '
226 . 'a simple string or an arrayref')
227 if ref($arg) ne 'ARRAY';
229 $_ = $class->_expand_relative_name($_) for (@$arg);
232 my $results_by_source_name = $class->_map_namespaces($result_namespace);
233 my $resultsets_by_source_name = $class->_map_namespaces($resultset_namespace);
237 no warnings qw/redefine/;
238 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
239 use warnings qw/redefine/;
241 # ensure classes are loaded and attached in inheritance order
242 for my $result_class (values %$results_by_source_name) {
243 $class->ensure_class_loaded($result_class);
246 my @source_names_by_subclass_last = sort {
249 scalar @{mro::get_linear_isa( $results_by_source_name->{$a} )}
255 scalar @{mro::get_linear_isa( $results_by_source_name->{$b} )}
258 } keys(%$results_by_source_name);
260 foreach my $source_name (@source_names_by_subclass_last) {
261 my $result_class = $results_by_source_name->{$source_name};
263 my $preset_resultset_class = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
264 my $found_resultset_class = delete $resultsets_by_source_name->{$source_name};
266 if($preset_resultset_class && $preset_resultset_class ne 'DBIx::Class::ResultSet') {
267 if($found_resultset_class && $found_resultset_class ne $preset_resultset_class) {
268 carp "We found ResultSet class '$found_resultset_class' matching '$results_by_source_name->{$source_name}', but it seems "
269 . "that you had already set the '$results_by_source_name->{$source_name}' resultet to '$preset_resultset_class' instead";
272 # elsif - there may be *no* default_resultset_class, in which case we fallback to
273 # DBIx::Class::Resultset and there is nothing to check
274 elsif($found_resultset_class ||= $default_resultset_class) {
275 $class->ensure_class_loaded($found_resultset_class);
276 if(!$found_resultset_class->isa("DBIx::Class::ResultSet")) {
277 carp "load_namespaces found ResultSet class '$found_resultset_class' that does not subclass DBIx::Class::ResultSet";
280 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($found_resultset_class);
283 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $source_name;
285 push(@to_register, [ $source_name, $result_class ]);
289 foreach (sort keys %$resultsets_by_source_name) {
290 carp "load_namespaces found ResultSet class '$resultsets_by_source_name->{$_}' "
291 .'with no corresponding Result class';
294 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
296 $class->register_class(@$_) for (@to_register);
305 =item Arguments: @classes?, { $namespace => [ @classes ] }+
309 L</load_classes> is an alternative method to L</load_namespaces>, both of
310 which serve similar purposes, each with different advantages and disadvantages.
311 In the general case you should use L</load_namespaces>, unless you need to
312 be able to specify that only specific classes are loaded at runtime.
314 With no arguments, this method uses L<Module::Find> to find all classes under
315 the schema's namespace. Otherwise, this method loads the classes you specify
316 (using L<use>), and registers them (using L</"register_class">).
318 It is possible to comment out classes with a leading C<#>, but note that perl
319 will think it's a mistake (trying to use a comment in a qw list), so you'll
320 need to add C<no warnings 'qw';> before your load_classes call.
322 If any classes found do not appear to be Result class files, you will
323 get the following warning:
325 Failed to load $comp_class. Can't find source_name method. Is
326 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
327 or make your load_classes call more specific.
331 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
332 # etc. (anything under the My::Schema namespace)
334 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
335 # not Other::Namespace::LinerNotes nor My::Schema::Track
336 My::Schema->load_classes(qw/ CD Artist #Track /, {
337 Other::Namespace => [qw/ Producer #LinerNotes /],
343 my ($class, @params) = @_;
348 foreach my $param (@params) {
349 if (ref $param eq 'ARRAY') {
350 # filter out commented entries
351 my @modules = grep { $_ !~ /^#/ } @$param;
353 push (@{$comps_for{$class}}, @modules);
355 elsif (ref $param eq 'HASH') {
356 # more than one namespace possible
357 for my $comp ( keys %$param ) {
358 # filter out commented entries
359 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
361 push (@{$comps_for{$comp}}, @modules);
365 # filter out commented entries
366 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
370 my @comp = map { substr $_, length "${class}::" }
371 $class->_findallmod($class);
372 $comps_for{$class} = \@comp;
377 no warnings qw/redefine/;
378 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
379 use warnings qw/redefine/;
381 foreach my $prefix (keys %comps_for) {
382 foreach my $comp (@{$comps_for{$prefix}||[]}) {
383 my $comp_class = "${prefix}::${comp}";
384 $class->ensure_class_loaded($comp_class);
386 my $snsub = $comp_class->can('source_name');
388 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.";
391 $comp = $snsub->($comp_class) || $comp;
393 push(@to_register, [ $comp, $comp_class ]);
397 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
399 foreach my $to (@to_register) {
400 $class->register_class(@$to);
408 =item Arguments: $storage_type|{$storage_type, \%args}
410 =item Return Value: $storage_type|{$storage_type, \%args}
412 =item Default value: DBIx::Class::Storage::DBI
416 Set the storage class that will be instantiated when L</connect> is called.
417 If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
418 assumed by L</connect>.
420 You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
421 in cases where the appropriate subclass is not autodetected.
423 If your storage type requires instantiation arguments, those are
424 defined as a second argument in the form of a hashref and the entire
425 value needs to be wrapped into an arrayref or a hashref. We support
426 both types of refs here in order to play nice with your
427 Config::[class] or your choice. See
428 L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
430 =head2 exception_action
434 =item Arguments: $code_reference
436 =item Return Value: $code_reference
438 =item Default value: None
442 When L</throw_exception> is invoked and L</exception_action> is set to a code
443 reference, this reference will be called instead of
444 L<DBIx::Class::Exception/throw>, with the exception message passed as the only
447 Your custom throw code B<must> rethrow the exception, as L</throw_exception> is
448 an integral part of DBIC's internal execution control flow.
453 use base qw/DBIx::Class::Schema/;
454 use My::ExceptionClass;
455 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
456 __PACKAGE__->load_classes;
459 my $schema_obj = My::Schema->connect( .... );
460 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
466 =item Arguments: boolean
470 Whether L</throw_exception> should include stack trace information.
471 Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
474 =head2 sqlt_deploy_hook
478 =item Arguments: $sqlt_schema
482 An optional sub which you can declare in your own Schema class that will get
483 passed the L<SQL::Translator::Schema> object when you deploy the schema via
484 L</create_ddl_dir> or L</deploy>.
486 For an example of what you can do with this, see
487 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
489 Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
490 is called before L</deploy>. Therefore the hook can be used only to manipulate
491 the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
492 database. If you want to execute post-deploy statements which can not be generated
493 by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
494 and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
502 =item Arguments: @connectinfo
504 =item Return Value: $new_schema
508 Creates and returns a new Schema object. The connection info set on it
509 is used to create a new instance of the storage backend and set it on
512 See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
513 syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
516 Note that C<connect_info> expects an arrayref of arguments, but
517 C<connect> does not. C<connect> wraps its arguments in an arrayref
518 before passing them to C<connect_info>.
522 C<connect> is a convenience method. It is equivalent to calling
523 $schema->clone->connection(@connectinfo). To write your own overloaded
524 version, overload L</connection> instead.
529 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
530 shift->clone->connection(@_);
537 =item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
539 =item Return Value: L<$resultset|DBIx::Class::ResultSet>
543 my $rs = $schema->resultset('DVD');
545 Returns the L<DBIx::Class::ResultSet> object for the registered source
551 my ($self, $source_name) = @_;
552 $self->throw_exception('resultset() expects a source name')
553 unless defined $source_name;
554 return $self->source($source_name)->resultset;
561 =item Return Value: L<@source_names|DBIx::Class::ResultSource/source_name>
565 my @source_names = $schema->sources;
567 Lists names of all the sources registered on this Schema object.
571 sub sources { keys %{shift->source_registrations} }
577 =item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
579 =item Return Value: L<$result_source|DBIx::Class::ResultSource>
583 my $source = $schema->source('Book');
585 Returns the L<DBIx::Class::ResultSource> object for the registered
593 $self->throw_exception("source() expects a source name")
596 my $source_name = shift;
598 my $sreg = $self->source_registrations;
599 return $sreg->{$source_name} if exists $sreg->{$source_name};
601 # if we got here, they probably passed a full class name
602 my $mapped = $self->class_mappings->{$source_name};
603 $self->throw_exception("Can't find source for ${source_name}")
604 unless $mapped && exists $sreg->{$mapped};
605 return $sreg->{$mapped};
612 =item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
614 =item Return Value: $classname
618 my $class = $schema->class('CD');
620 Retrieves the Result class name for the given source name.
625 return shift->source(shift)->result_class;
632 =item Arguments: C<$coderef>, @coderef_args?
634 =item Return Value: The return value of $coderef
638 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
639 returning its result (if any). Equivalent to calling $schema->storage->txn_do.
640 See L<DBIx::Class::Storage/"txn_do"> for more information.
642 This interface is preferred over using the individual methods L</txn_begin>,
643 L</txn_commit>, and L</txn_rollback> below.
645 WARNING: If you are connected with C<< AutoCommit => 0 >> the transaction is
646 considered nested, and you will still need to call L</txn_commit> to write your
647 changes when appropriate. You will also want to connect with C<< auto_savepoint =>
648 1 >> to get partial rollback to work, if the storage driver for your database
651 Connecting with C<< AutoCommit => 1 >> is recommended.
658 $self->storage or $self->throw_exception
659 ('txn_do called on $schema without storage');
661 $self->storage->txn_do(@_);
664 =head2 txn_scope_guard
666 Runs C<txn_scope_guard> on the schema's storage. See
667 L<DBIx::Class::Storage/txn_scope_guard>.
671 sub txn_scope_guard {
674 $self->storage or $self->throw_exception
675 ('txn_scope_guard called on $schema without storage');
677 $self->storage->txn_scope_guard(@_);
682 Begins a transaction (does nothing if AutoCommit is off). Equivalent to
683 calling $schema->storage->txn_begin. See
684 L<DBIx::Class::Storage/"txn_begin"> for more information.
691 $self->storage or $self->throw_exception
692 ('txn_begin called on $schema without storage');
694 $self->storage->txn_begin;
699 Commits the current transaction. Equivalent to calling
700 $schema->storage->txn_commit. See L<DBIx::Class::Storage/"txn_commit">
701 for more information.
708 $self->storage or $self->throw_exception
709 ('txn_commit called on $schema without storage');
711 $self->storage->txn_commit;
716 Rolls back the current transaction. Equivalent to calling
717 $schema->storage->txn_rollback. See
718 L<DBIx::Class::Storage/"txn_rollback"> for more information.
725 $self->storage or $self->throw_exception
726 ('txn_rollback called on $schema without storage');
728 $self->storage->txn_rollback;
733 my $storage = $schema->storage;
735 Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
736 if you want to turn on SQL statement debugging at runtime, or set the
737 quote character. For the default storage, the documentation can be
738 found in L<DBIx::Class::Storage::DBI>.
744 =item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>, [ \@column_list, \@row_values+ ] | [ \%col_data+ ]
746 =item Return Value: L<\@result_objects|DBIx::Class::Manual::ResultClass> (scalar context) | L<@result_objects|DBIx::Class::Manual::ResultClass> (list context)
750 A convenience shortcut to L<DBIx::Class::ResultSet/populate>. Equivalent to:
752 $schema->resultset($source_name)->populate([...]);
758 The context of this method call has an important effect on what is
759 submitted to storage. In void context data is fed directly to fastpath
760 insertion routines provided by the underlying storage (most often
761 L<DBI/execute_for_fetch>), bypassing the L<new|DBIx::Class::Row/new> and
762 L<insert|DBIx::Class::Row/insert> calls on the
763 L<Result|DBIx::Class::Manual::ResultClass> class, including any
764 augmentation of these methods provided by components. For example if you
765 are using something like L<DBIx::Class::UUIDColumns> to create primary
766 keys for you, you will find that your PKs are empty. In this case you
767 will have to explicitly force scalar or list context in order to create
775 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
777 my ($self, $name, $data) = @_;
778 my $rs = $self->resultset($name)
779 or $self->throw_exception("'$name' is not a resultset");
781 return $rs->populate($data);
788 =item Arguments: @args
790 =item Return Value: $new_schema
794 Similar to L</connect> except sets the storage object and connection
795 data in-place on the Schema class. You should probably be calling
796 L</connect> to get a proper Schema object instead.
800 Overload C<connection> to change the behaviour of C<connect>.
805 my ($self, @info) = @_;
806 return $self if !@info && $self->storage;
808 my ($storage_class, $args) = ref $self->storage_type
809 ? $self->_normalize_storage_type($self->storage_type)
810 : $self->storage_type
813 $storage_class =~ s/^::/DBIx::Class::Storage::/;
816 $self->ensure_class_loaded ($storage_class);
819 $self->throw_exception(
820 "Unable to load storage class ${storage_class}: $_"
824 my $storage = $storage_class->new( $self => $args||{} );
825 $storage->connect_info(\@info);
826 $self->storage($storage);
830 sub _normalize_storage_type {
831 my ($self, $storage_type) = @_;
832 if(ref $storage_type eq 'ARRAY') {
833 return @$storage_type;
834 } elsif(ref $storage_type eq 'HASH') {
835 return %$storage_type;
837 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
841 =head2 compose_namespace
845 =item Arguments: $target_namespace, $additional_base_class?
847 =item Return Value: $new_schema
851 For each L<DBIx::Class::ResultSource> in the schema, this method creates a
852 class in the target namespace (e.g. $target_namespace::CD,
853 $target_namespace::Artist) that inherits from the corresponding classes
854 attached to the current schema.
856 It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
857 new $schema object. If C<$additional_base_class> is given, the new composed
858 classes will inherit from first the corresponding class from the current
859 schema then the base class.
861 For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
863 $schema->compose_namespace('My::DB', 'Base::Class');
864 print join (', ', @My::DB::CD::ISA) . "\n";
865 print join (', ', @My::DB::Artist::ISA) ."\n";
867 will produce the output
869 My::Schema::CD, Base::Class
870 My::Schema::Artist, Base::Class
874 sub compose_namespace {
875 my ($self, $target, $base) = @_;
877 my $schema = $self->clone;
879 $schema->source_registrations({});
881 # the original class-mappings must remain - otherwise
882 # reverse_relationship_info will not work
883 #$schema->class_mappings({});
886 no warnings qw/redefine/;
887 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
888 use warnings qw/redefine/;
890 foreach my $source_name ($self->sources) {
891 my $orig_source = $self->source($source_name);
893 my $target_class = "${target}::${source_name}";
894 $self->inject_base($target_class, $orig_source->result_class, ($base || ()) );
896 # register_source examines result_class, and then returns us a clone
897 my $new_source = $schema->register_source($source_name, bless
898 { %$orig_source, result_class => $target_class },
902 if ($target_class->can('result_source_instance')) {
903 # give the class a schema-less source copy
904 $target_class->result_source_instance( bless
905 { %$new_source, schema => ref $new_source->{schema} || $new_source->{schema} },
911 # Legacy stuff, not inserting INDIRECT assertions
912 quote_sub "${target}::${_}" => "shift->schema->$_(\@_)"
913 for qw(class source resultset);
916 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
921 sub setup_connection_class {
922 my ($class, $target, @info) = @_;
923 $class->inject_base($target => 'DBIx::Class::DB');
924 #$target->load_components('DB');
925 $target->connection(@info);
930 Creates a new savepoint (does nothing outside a transaction).
931 Equivalent to calling $schema->storage->svp_begin. See
932 L<DBIx::Class::Storage/"svp_begin"> for more information.
937 my ($self, $name) = @_;
939 $self->storage or $self->throw_exception
940 ('svp_begin called on $schema without storage');
942 $self->storage->svp_begin($name);
947 Releases a savepoint (does nothing outside a transaction).
948 Equivalent to calling $schema->storage->svp_release. See
949 L<DBIx::Class::Storage/"svp_release"> for more information.
954 my ($self, $name) = @_;
956 $self->storage or $self->throw_exception
957 ('svp_release called on $schema without storage');
959 $self->storage->svp_release($name);
964 Rollback to a savepoint (does nothing outside a transaction).
965 Equivalent to calling $schema->storage->svp_rollback. See
966 L<DBIx::Class::Storage/"svp_rollback"> for more information.
971 my ($self, $name) = @_;
973 $self->storage or $self->throw_exception
974 ('svp_rollback called on $schema without storage');
976 $self->storage->svp_rollback($name);
983 =item Arguments: %attrs?
985 =item Return Value: $new_schema
989 Clones the schema and its associated result_source objects and returns the
990 copy. The resulting copy will have the same attributes as the source schema,
991 except for those attributes explicitly overridden by the provided C<%attrs>.
999 (ref $self ? %$self : ()),
1000 (@_ == 1 && ref $_[0] eq 'HASH' ? %{ $_[0] } : @_),
1002 bless $clone, (ref $self || $self);
1004 $clone->$_(undef) for qw/class_mappings source_registrations storage/;
1006 $clone->_copy_state_from($self);
1011 # Needed in Schema::Loader - if you refactor, please make a compatibility shim
1013 sub _copy_state_from {
1014 my ($self, $from) = @_;
1016 $self->class_mappings({ %{$from->class_mappings} });
1017 $self->source_registrations({ %{$from->source_registrations} });
1019 foreach my $source_name ($from->sources) {
1020 my $source = $from->source($source_name);
1021 my $new = $source->new($source);
1022 # we use extra here as we want to leave the class_mappings as they are
1023 # but overwrite the source_registrations entry with the new source
1024 $self->register_extra_source($source_name => $new);
1027 if ($from->storage) {
1028 $self->storage($from->storage);
1029 $self->storage->set_schema($self);
1033 =head2 throw_exception
1037 =item Arguments: $message
1041 Throws an exception. Obeys the exemption rules of L<DBIx::Class::Carp> to report
1042 errors from outer-user's perspective. See L</exception_action> for details on overriding
1043 this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1044 default behavior will provide a detailed stack trace.
1048 sub throw_exception {
1049 my ($self, @args) = @_;
1052 ! DBIx::Class::_Util::in_internal_try()
1054 my $act = $self->exception_action
1059 my $guard = scope_guard {
1060 return if $guard_disarmed;
1061 local $SIG{__WARN__};
1063 !!! DBIx::Class INTERNAL PANIC !!!
1065 The exception_action() handler installed on '$self'
1066 aborted the stacktrace below via a longjmp (either via Return::Multilevel or
1067 plain goto, or Scope::Upper or something equally nefarious). There currently
1068 is nothing safe DBIx::Class can do, aside from displaying this error. A future
1069 version ( 0.082900, when available ) will reduce the cases in which the
1070 handler is invoked, but this is neither a complete solution, nor can it do
1071 anything for other software that might be affected by a similar problem.
1073 !!! FIX YOUR ERROR HANDLING !!!
1075 This guard was activated beginning"
1080 # if it throws - good, we'll assign to @args in the end
1081 # if it doesn't - do different things depending on RV truthiness
1082 if( $act->(@args) ) {
1084 "Invocation of the exception_action handler installed on $self did *not*"
1085 .' result in an exception. DBIx::Class is unable to function without a reliable'
1086 .' exception mechanism, ensure your exception_action does not hide exceptions'
1087 ." (original error: $args[0])"
1092 "The exception_action handler installed on $self returned false instead"
1093 .' of throwing an exception. This behavior has been deprecated, adjust your'
1094 .' handler to always rethrow the supplied error'
1101 # We call this to get the necessary warnings emitted and disregard the RV
1102 # as it's definitely an exception if we got as far as this catch{} block
1108 # Done guarding against https://github.com/PerlDancer/Dancer2/issues/1125
1109 $guard_disarmed = 1;
1112 DBIx::Class::Exception->throw( $args[0], $self->stacktrace );
1119 =item Arguments: \%sqlt_args, $dir
1123 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
1125 See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1126 The most common value for this would be C<< { add_drop_table => 1 } >>
1127 to have the SQL produced include a C<DROP TABLE> statement for each table
1128 created. For quoting purposes supply C<quote_identifiers>.
1130 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1131 ref or an array ref, containing a list of source to deploy. If present, then
1132 only the sources listed will get deployed. Furthermore, you can use the
1133 C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1139 my ($self, $sqltargs, $dir) = @_;
1140 $self->throw_exception("Can't deploy without storage") unless $self->storage;
1141 $self->storage->deploy($self, undef, $sqltargs, $dir);
1144 =head2 deployment_statements
1148 =item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
1150 =item Return Value: $listofstatements
1154 A convenient shortcut to
1155 C<< $self->storage->deployment_statements($self, @args) >>.
1156 Returns the statements used by L</deploy> and
1157 L<DBIx::Class::Storage/deploy>.
1161 sub deployment_statements {
1164 $self->throw_exception("Can't generate deployment statements without a storage")
1165 if not $self->storage;
1167 $self->storage->deployment_statements($self, @_);
1170 =head2 create_ddl_dir
1174 =item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
1178 A convenient shortcut to
1179 C<< $self->storage->create_ddl_dir($self, @args) >>.
1181 Creates an SQL file based on the Schema, for each of the specified
1182 database types, in the given directory.
1186 sub create_ddl_dir {
1189 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1190 $self->storage->create_ddl_dir($self, @_);
1197 =item Arguments: $database-type, $version, $directory, $preversion
1199 =item Return Value: $normalised_filename
1203 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
1205 This method is called by C<create_ddl_dir> to compose a file name out of
1206 the supplied directory, database type and version number. The default file
1207 name format is: C<$dir$schema-$version-$type.sql>.
1209 You may override this method in your schema if you wish to use a different
1214 Prior to DBIx::Class version 0.08100 this method had a different signature:
1216 my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1218 In recent versions variables $dir and $version were reversed in order to
1219 bring the signature in line with other Schema/Storage methods. If you
1220 really need to maintain backward compatibility, you can do the following
1221 in any overriding methods:
1223 ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1228 my ($self, $type, $version, $dir, $preversion) = @_;
1230 $version = "$preversion-$version" if $preversion;
1232 my $class = blessed($self) || $self;
1235 return "$dir/$class-$version-$type.sql";
1240 Provided as the recommended way of thawing schema objects. You can call
1241 C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1242 reference to any schema, so are rather useless.
1247 my ($self, $obj) = @_;
1248 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1249 return Storable::thaw($obj);
1254 This doesn't actually do anything beyond calling L<nfreeze|Storable/SYNOPSIS>,
1255 it is just provided here for symmetry.
1260 return Storable::nfreeze($_[1]);
1267 =item Arguments: $object
1269 =item Return Value: dcloned $object
1273 Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1274 objects so their references to the schema object
1275 (which itself is B<not> cloned) are properly maintained.
1280 my ($self, $obj) = @_;
1281 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1282 return Storable::dclone($obj);
1285 =head2 schema_version
1287 Returns the current schema class' $VERSION in a normalised way.
1291 sub schema_version {
1293 my $class = ref($self)||$self;
1295 # does -not- use $schema->VERSION
1296 # since that varies in results depending on if version.pm is installed, and if
1297 # so the perl or XS versions. If you want this to change, bug the version.pm
1298 # author to make vpp and vxs behave the same.
1303 $version = ${"${class}::VERSION"};
1309 =head2 register_class
1313 =item Arguments: $source_name, $component_class
1317 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.
1319 You will only need this method if you have your Result classes in
1320 files which are not named after the packages (or all in the same
1321 file). You may also need it to register classes at runtime.
1323 Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1326 $schema->register_source($source_name, $component_class->result_source_instance);
1330 sub register_class {
1331 my ($self, $source_name, $to_register) = @_;
1332 $self->register_source($source_name => $to_register->result_source_instance);
1335 =head2 register_source
1339 =item Arguments: $source_name, L<$result_source|DBIx::Class::ResultSource>
1343 This method is called by L</register_class>.
1345 Registers the L<DBIx::Class::ResultSource> in the schema with the given
1350 sub register_source { shift->_register_source(@_) }
1352 =head2 unregister_source
1356 =item Arguments: $source_name
1360 Removes the L<DBIx::Class::ResultSource> from the schema for the given source name.
1364 sub unregister_source { shift->_unregister_source(@_) }
1366 =head2 register_extra_source
1370 =item Arguments: $source_name, L<$result_source|DBIx::Class::ResultSource>
1374 As L</register_source> but should be used if the result class already
1375 has a source and you want to register an extra one.
1379 sub register_extra_source { shift->_register_source(@_, { extra => 1 }) }
1381 sub _register_source {
1382 my ($self, $source_name, $source, $params) = @_;
1384 $source = $source->new({ %$source, source_name => $source_name });
1386 $source->schema($self);
1387 weaken $source->{schema} if ref($self);
1389 my %reg = %{$self->source_registrations};
1390 $reg{$source_name} = $source;
1391 $self->source_registrations(\%reg);
1393 return $source if $params->{extra};
1395 my $rs_class = $source->result_class;
1396 if ($rs_class and my $rsrc = dbic_internal_try { $rs_class->result_source_instance } ) {
1397 my %map = %{$self->class_mappings};
1399 exists $map{$rs_class}
1401 $map{$rs_class} ne $source_name
1403 $rsrc ne $_[2] # orig_source
1406 "$rs_class already had a registered source which was replaced by this call. "
1407 . 'Perhaps you wanted register_extra_source(), though it is more likely you did '
1408 . 'something wrong.'
1412 $map{$rs_class} = $source_name;
1413 $self->class_mappings(\%map);
1419 my $global_phase_destroy;
1421 ### NO detected_reinvoked_destructor check
1422 ### This code very much relies on being called multuple times
1424 return if $global_phase_destroy ||= in_global_destruction;
1427 my $srcs = $self->source_registrations;
1429 for my $source_name (keys %$srcs) {
1430 # find first source that is not about to be GCed (someone other than $self
1431 # holds a reference to it) and reattach to it, weakening our own link
1433 # during global destruction (if we have not yet bailed out) this should throw
1434 # which will serve as a signal to not try doing anything else
1435 # however beware - on older perls the exception seems randomly untrappable
1436 # due to some weird race condition during thread joining :(((
1437 if (length ref $srcs->{$source_name} and refcount($srcs->{$source_name}) > 1) {
1438 local $SIG{__DIE__} if $SIG{__DIE__};
1441 $srcs->{$source_name}->schema($self);
1442 weaken $srcs->{$source_name};
1445 $global_phase_destroy = 1;
1452 # Dummy NEXTSTATE ensuring the all temporaries on the stack are garbage
1453 # collected before leaving this scope. Depending on the code above, this
1454 # may very well be just a preventive measure guarding future modifications
1458 sub _unregister_source {
1459 my ($self, $source_name) = @_;
1460 my %reg = %{$self->source_registrations};
1462 my $source = delete $reg{$source_name};
1463 $self->source_registrations(\%reg);
1464 if ($source->result_class) {
1465 my %map = %{$self->class_mappings};
1466 delete $map{$source->result_class};
1467 $self->class_mappings(\%map);
1472 =head2 compose_connection (DEPRECATED)
1476 =item Arguments: $target_namespace, @db_info
1478 =item Return Value: $new_schema
1482 DEPRECATED. You probably wanted compose_namespace.
1484 Actually, you probably just wanted to call connect.
1488 (hidden due to deprecation)
1490 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1491 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1492 then injects the L<DBix::Class::ResultSetProxy> component and a
1493 resultset_instance classdata entry on all the new classes, in order to support
1494 $target_namespaces::$class->search(...) method calls.
1496 This is primarily useful when you have a specific need for class method access
1497 to a connection. In normal usage it is preferred to call
1498 L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1499 on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1506 sub compose_connection {
1507 my ($self, $target, @info) = @_;
1509 carp_once "compose_connection deprecated as of 0.08000"
1510 unless $INC{"DBIx/Class/CDBICompat.pm"};
1513 require DBIx::Class::ResultSetProxy;
1516 $self->throw_exception
1517 ("No arguments to load_classes and couldn't load DBIx::Class::ResultSetProxy ($_)")
1520 if ($self eq $target) {
1521 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1522 foreach my $source_name ($self->sources) {
1523 my $source = $self->source($source_name);
1524 my $class = $source->result_class;
1525 $self->inject_base($class, 'DBIx::Class::ResultSetProxy');
1526 $class->mk_classaccessor(resultset_instance => $source->resultset);
1527 $class->mk_classaccessor(class_resolver => $self);
1529 $self->connection(@info);
1533 my $schema = $self->compose_namespace($target, 'DBIx::Class::ResultSetProxy');
1534 quote_sub "${target}::schema", '$s', { '$s' => \$schema };
1536 $schema->connection(@info);
1537 foreach my $source_name ($schema->sources) {
1538 my $source = $schema->source($source_name);
1539 my $class = $source->result_class;
1540 #warn "$source_name $class $source ".$source->storage;
1541 $class->mk_classaccessor(result_source_instance => $source);
1542 $class->mk_classaccessor(resultset_instance => $source->resultset);
1543 $class->mk_classaccessor(class_resolver => $schema);
1548 =head1 FURTHER QUESTIONS?
1550 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1552 =head1 COPYRIGHT AND LICENSE
1554 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1555 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1556 redistribute it and/or modify it under the same terms as the
1557 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.