Fill in missing documentation in ::Schema / ::ResultSource
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Schema.pm
CommitLineData
a02675cd 1package DBIx::Class::Schema;
2
3use strict;
4use warnings;
aa562407 5
64c50e81 6use base 'DBIx::Class';
d009cb7d 7use mro 'c3';
64c50e81 8
70c28808 9use DBIx::Class::Carp;
9780718f 10use Try::Tiny;
aea59b74 11use Scalar::Util qw/weaken blessed/;
ddcc02d1 12use DBIx::Class::_Util qw(
13 refcount quote_sub scope_guard
14 is_exception dbic_internal_try
e5053694 15 fail_on_internal_call
ddcc02d1 16);
d6b39e46 17use Devel::GlobalDestruction;
fd323bf1 18use namespace::clean;
a02675cd 19
e5053694 20__PACKAGE__->mk_group_accessors( inherited => qw( storage exception_action ) );
e5053694 21__PACKAGE__->mk_classaccessor('storage_type' => '::DBI');
22__PACKAGE__->mk_classaccessor('stacktrace' => $ENV{DBIC_TRACE} || 0);
23__PACKAGE__->mk_classaccessor('default_resultset_attributes' => {});
a02675cd 24
759a7f44 25# These two should have been private from the start but too late now
26# Undocumented on purpose, hopefully it won't ever be necessary to
27# screw with them
28__PACKAGE__->mk_classaccessor('class_mappings' => {});
29__PACKAGE__->mk_classaccessor('source_registrations' => {});
30
c2da098a 31=head1 NAME
32
33DBIx::Class::Schema - composable schemas
34
35=head1 SYNOPSIS
36
24d67825 37 package Library::Schema;
c2da098a 38 use base qw/DBIx::Class::Schema/;
bab77431 39
829517d4 40 # load all Result classes in Library/Schema/Result/
41 __PACKAGE__->load_namespaces();
c2da098a 42
829517d4 43 package Library::Schema::Result::CD;
d88ecca6 44 use base qw/DBIx::Class::Core/;
45
46 __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
24d67825 47 __PACKAGE__->table('cd');
c2da098a 48
5d9076f2 49 # Elsewhere in your code:
24d67825 50 my $schema1 = Library::Schema->connect(
a3d93194 51 $dsn,
52 $user,
53 $password,
ef131d82 54 { AutoCommit => 1 },
a3d93194 55 );
bab77431 56
24d67825 57 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
c2da098a 58
829517d4 59 # fetch objects using Library::Schema::Result::DVD
24d67825 60 my $resultset = $schema1->resultset('DVD')->search( ... );
61 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
c2da098a 62
63=head1 DESCRIPTION
64
a3d93194 65Creates database classes based on a schema. This is the recommended way to
66use L<DBIx::Class> and allows you to use more than one concurrent connection
67with your classes.
429bd4f1 68
03312470 69NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
2053ab2a 70carefully, as DBIx::Class does things a little differently. Note in
03312470 71particular which module inherits off which.
72
829517d4 73=head1 SETUP METHODS
c2da098a 74
829517d4 75=head2 load_namespaces
87c4e602 76
27f01d1f 77=over 4
78
829517d4 79=item Arguments: %options?
27f01d1f 80
81=back
076652e8 82
a5bd5d88 83 package MyApp::Schema;
829517d4 84 __PACKAGE__->load_namespaces();
66d9ef6b 85
829517d4 86 __PACKAGE__->load_namespaces(
6f731572 87 result_namespace => 'Res',
88 resultset_namespace => 'RSet',
a5bd5d88 89 default_resultset_class => '+MyApp::Othernamespace::RSet',
6f731572 90 );
91
92With no arguments, this method uses L<Module::Find> to load all of the
93Result and ResultSet classes under the namespace of the schema from
94which it is called. For example, C<My::Schema> will by default find
95and load Result classes named C<My::Schema::Result::*> and ResultSet
96classes named C<My::Schema::ResultSet::*>.
97
98ResultSet classes are associated with Result class of the same name.
99For example, C<My::Schema::Result::CD> will get the ResultSet class
100C<My::Schema::ResultSet::CD> if it is present.
101
102Both Result and ResultSet namespaces are configurable via the
103C<result_namespace> and C<resultset_namespace> options.
076652e8 104
6f731572 105Another option, C<default_resultset_class> specifies a custom default
106ResultSet class for Result classes with no corresponding ResultSet.
c2da098a 107
6f731572 108All of the namespace and classname options are by default relative to
109the schema classname. To specify a fully-qualified name, prefix it
110with a literal C<+>. For example, C<+Other::NameSpace::Result>.
111
112=head3 Warnings
74b92d9a 113
672687db 114You will be warned if ResultSet classes are discovered for which there
829517d4 115are no matching Result classes like this:
87c4e602 116
829517d4 117 load_namespaces found ResultSet class $classname with no corresponding Result class
27f01d1f 118
5529838f 119If a ResultSource instance is found to already have a ResultSet class set
120using L<resultset_class|DBIx::Class::ResultSource/resultset_class> to some
121other class, you will be warned like this:
27f01d1f 122
5529838f 123 We found ResultSet class '$rs_class' for '$result_class', but it seems
124 that you had already set '$result_class' to use '$rs_set' instead
076652e8 125
6f731572 126=head3 Examples
2a4d9487 127
829517d4 128 # load My::Schema::Result::CD, My::Schema::Result::Artist,
129 # My::Schema::ResultSet::CD, etc...
130 My::Schema->load_namespaces;
2a4d9487 131
829517d4 132 # Override everything to use ugly names.
133 # In this example, if there is a My::Schema::Res::Foo, but no matching
134 # My::Schema::RSets::Foo, then Foo will have its
135 # resultset_class set to My::Schema::RSetBase
136 My::Schema->load_namespaces(
137 result_namespace => 'Res',
138 resultset_namespace => 'RSets',
139 default_resultset_class => 'RSetBase',
140 );
2a4d9487 141
829517d4 142 # Put things in other namespaces
143 My::Schema->load_namespaces(
144 result_namespace => '+Some::Place::Results',
145 resultset_namespace => '+Another::Place::RSets',
146 );
2a4d9487 147
6f731572 148To search multiple namespaces for either Result or ResultSet classes,
149use an arrayref of namespaces for that option. In the case that the
150same result (or resultset) class exists in multiple namespaces, later
151entries in the list of namespaces will override earlier ones.
2a4d9487 152
829517d4 153 My::Schema->load_namespaces(
154 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
155 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
156 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
157 );
2a4d9487 158
159=cut
160
829517d4 161# Pre-pends our classname to the given relative classname or
162# class namespace, unless there is a '+' prefix, which will
163# be stripped.
164sub _expand_relative_name {
165 my ($class, $name) = @_;
93d7452f 166 $name =~ s/^\+// or $name = "${class}::${name}";
829517d4 167 return $name;
2a4d9487 168}
169
f3405058 170# Finds all modules in the supplied namespace, or if omitted in the
171# namespace of $class. Untaints all findings as they can be assumed
172# to be safe
173sub _findallmod {
3b80fa31 174 require Module::Find;
93d7452f 175 return map
176 { $_ =~ /(.+)/ } # untaint result
177 Module::Find::findallmod( $_[1] || ref $_[0] || $_[0] )
178 ;
f3405058 179}
180
829517d4 181# returns a hash of $shortname => $fullname for every package
b488020e 182# found in the given namespaces ($shortname is with the $fullname's
183# namespace stripped off)
829517d4 184sub _map_namespaces {
93d7452f 185 my ($me, $namespaces) = @_;
186
187 my %res;
188 for my $ns (@$namespaces) {
189 $res{ substr($_, length "${ns}::") } = $_
190 for $me->_findallmod($ns);
0dc79249 191 }
27f01d1f 192
93d7452f 193 \%res;
ea20d0fd 194}
195
b488020e 196# returns the result_source_instance for the passed class/object,
197# or dies with an informative message (used by load_namespaces)
198sub _ns_get_rsrc_instance {
dee99c24 199 my $me = shift;
200 my $rs_class = ref ($_[0]) || $_[0];
201
ddcc02d1 202 return dbic_internal_try {
dee99c24 203 $rs_class->result_source_instance
204 } catch {
205 $me->throw_exception (
206 "Attempt to load_namespaces() class $rs_class failed - are you sure this is a real Result Class?: $_"
b488020e 207 );
dee99c24 208 };
b488020e 209}
210
829517d4 211sub load_namespaces {
212 my ($class, %args) = @_;
0dc79249 213
829517d4 214 my $result_namespace = delete $args{result_namespace} || 'Result';
215 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
93d7452f 216
829517d4 217 my $default_resultset_class = delete $args{default_resultset_class};
0dc79249 218
93d7452f 219 $default_resultset_class = $class->_expand_relative_name($default_resultset_class)
220 if $default_resultset_class;
221
829517d4 222 $class->throw_exception('load_namespaces: unknown option(s): '
223 . join(q{,}, map { qq{'$_'} } keys %args))
224 if scalar keys %args;
0dc79249 225
829517d4 226 for my $arg ($result_namespace, $resultset_namespace) {
93d7452f 227 $arg = [ $arg ] if ( $arg and ! ref $arg );
9b1ba0f2 228
829517d4 229 $class->throw_exception('load_namespaces: namespace arguments must be '
230 . 'a simple string or an arrayref')
231 if ref($arg) ne 'ARRAY';
9b1ba0f2 232
829517d4 233 $_ = $class->_expand_relative_name($_) for (@$arg);
234 }
ea20d0fd 235
93d7452f 236 my $results_by_source_name = $class->_map_namespaces($result_namespace);
237 my $resultsets_by_source_name = $class->_map_namespaces($resultset_namespace);
27f01d1f 238
829517d4 239 my @to_register;
240 {
87bf71d5 241 no warnings qw/redefine/;
242 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
243 use warnings qw/redefine/;
27f01d1f 244
3988ce40 245 # ensure classes are loaded and attached in inheritance order
93d7452f 246 for my $result_class (values %$results_by_source_name) {
247 $class->ensure_class_loaded($result_class);
f5ef5fa1 248 }
3988ce40 249 my %inh_idx;
93d7452f 250 my @source_names_by_subclass_last = sort {
3988ce40 251
252 ($inh_idx{$a} ||=
93d7452f 253 scalar @{mro::get_linear_isa( $results_by_source_name->{$a} )}
3988ce40 254 )
255
256 <=>
257
258 ($inh_idx{$b} ||=
93d7452f 259 scalar @{mro::get_linear_isa( $results_by_source_name->{$b} )}
3988ce40 260 )
261
93d7452f 262 } keys(%$results_by_source_name);
3988ce40 263
93d7452f 264 foreach my $source_name (@source_names_by_subclass_last) {
265 my $result_class = $results_by_source_name->{$source_name};
82b01c38 266
93d7452f 267 my $preset_resultset_class = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
268 my $found_resultset_class = delete $resultsets_by_source_name->{$source_name};
3988ce40 269
93d7452f 270 if($preset_resultset_class && $preset_resultset_class ne 'DBIx::Class::ResultSet') {
271 if($found_resultset_class && $found_resultset_class ne $preset_resultset_class) {
272 carp "We found ResultSet class '$found_resultset_class' matching '$results_by_source_name->{$source_name}', but it seems "
273 . "that you had already set the '$results_by_source_name->{$source_name}' resultet to '$preset_resultset_class' instead";
829517d4 274 }
275 }
93d7452f 276 # elsif - there may be *no* default_resultset_class, in which case we fallback to
277 # DBIx::Class::Resultset and there is nothing to check
278 elsif($found_resultset_class ||= $default_resultset_class) {
279 $class->ensure_class_loaded($found_resultset_class);
280 if(!$found_resultset_class->isa("DBIx::Class::ResultSet")) {
281 carp "load_namespaces found ResultSet class '$found_resultset_class' that does not subclass DBIx::Class::ResultSet";
1d3108a4 282 }
283
93d7452f 284 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($found_resultset_class);
829517d4 285 }
82b01c38 286
93d7452f 287 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $source_name;
0e6c5d58 288
289 push(@to_register, [ $source_name, $result_class ]);
829517d4 290 }
291 }
ea20d0fd 292
93d7452f 293 foreach (sort keys %$resultsets_by_source_name) {
294 carp "load_namespaces found ResultSet class '$resultsets_by_source_name->{$_}' "
295 .'with no corresponding Result class';
829517d4 296 }
ea20d0fd 297
87bf71d5 298 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
299
829517d4 300 $class->register_class(@$_) for (@to_register);
ea20d0fd 301
829517d4 302 return;
ea20d0fd 303}
304
87c4e602 305=head2 load_classes
306
27f01d1f 307=over 4
308
309=item Arguments: @classes?, { $namespace => [ @classes ] }+
310
311=back
076652e8 312
1ab61457 313L</load_classes> is an alternative method to L</load_namespaces>, both of
314which serve similar purposes, each with different advantages and disadvantages.
315In the general case you should use L</load_namespaces>, unless you need to
316be able to specify that only specific classes are loaded at runtime.
829517d4 317
82b01c38 318With no arguments, this method uses L<Module::Find> to find all classes under
319the schema's namespace. Otherwise, this method loads the classes you specify
320(using L<use>), and registers them (using L</"register_class">).
076652e8 321
2053ab2a 322It is possible to comment out classes with a leading C<#>, but note that perl
323will think it's a mistake (trying to use a comment in a qw list), so you'll
324need to add C<no warnings 'qw';> before your load_classes call.
5ce32fc1 325
829517d4 326If any classes found do not appear to be Result class files, you will
327get the following warning:
328
fd323bf1 329 Failed to load $comp_class. Can't find source_name method. Is
829517d4 330 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
331 or make your load_classes call more specific.
332
2053ab2a 333Example:
82b01c38 334
335 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
75d07914 336 # etc. (anything under the My::Schema namespace)
82b01c38 337
338 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
339 # not Other::Namespace::LinerNotes nor My::Schema::Track
340 My::Schema->load_classes(qw/ CD Artist #Track /, {
341 Other::Namespace => [qw/ Producer #LinerNotes /],
342 });
343
076652e8 344=cut
345
a02675cd 346sub load_classes {
5ce32fc1 347 my ($class, @params) = @_;
bab77431 348
5ce32fc1 349 my %comps_for;
bab77431 350
5ce32fc1 351 if (@params) {
352 foreach my $param (@params) {
353 if (ref $param eq 'ARRAY') {
354 # filter out commented entries
355 my @modules = grep { $_ !~ /^#/ } @$param;
bab77431 356
5ce32fc1 357 push (@{$comps_for{$class}}, @modules);
358 }
359 elsif (ref $param eq 'HASH') {
360 # more than one namespace possible
361 for my $comp ( keys %$param ) {
362 # filter out commented entries
363 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
364
365 push (@{$comps_for{$comp}}, @modules);
366 }
367 }
368 else {
369 # filter out commented entries
370 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
371 }
372 }
373 } else {
bc0c9800 374 my @comp = map { substr $_, length "${class}::" }
93d7452f 375 $class->_findallmod($class);
5ce32fc1 376 $comps_for{$class} = \@comp;
41a6f8c0 377 }
5ce32fc1 378
e6efde04 379 my @to_register;
380 {
381 no warnings qw/redefine/;
87bf71d5 382 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
383 use warnings qw/redefine/;
384
e6efde04 385 foreach my $prefix (keys %comps_for) {
386 foreach my $comp (@{$comps_for{$prefix}||[]}) {
387 my $comp_class = "${prefix}::${comp}";
c037c03a 388 $class->ensure_class_loaded($comp_class);
bab77431 389
89271e56 390 my $snsub = $comp_class->can('source_name');
391 if(! $snsub ) {
341d5ede 392 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.";
89271e56 393 next;
394 }
395 $comp = $snsub->($comp_class) || $comp;
396
93405cf0 397 push(@to_register, [ $comp, $comp_class ]);
bfb2bd4f 398 }
5ce32fc1 399 }
a02675cd 400 }
87bf71d5 401 Class::C3->reinitialize if DBIx::Class::_ENV_::OLD_MRO;
e6efde04 402
403 foreach my $to (@to_register) {
404 $class->register_class(@$to);
e6efde04 405 }
a02675cd 406}
407
829517d4 408=head2 storage_type
2374c5ff 409
410=over 4
411
829517d4 412=item Arguments: $storage_type|{$storage_type, \%args}
413
fb13a49f 414=item Return Value: $storage_type|{$storage_type, \%args}
829517d4 415
416=item Default value: DBIx::Class::Storage::DBI
2374c5ff 417
418=back
419
829517d4 420Set the storage class that will be instantiated when L</connect> is called.
421If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
95787afe 422assumed by L</connect>.
2374c5ff 423
829517d4 424You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
95787afe 425in cases where the appropriate subclass is not autodetected.
85bd0538 426
829517d4 427If your storage type requires instantiation arguments, those are
428defined as a second argument in the form of a hashref and the entire
429value needs to be wrapped into an arrayref or a hashref. We support
430both types of refs here in order to play nice with your
431Config::[class] or your choice. See
432L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
0f4ec1d2 433
759a7f44 434=head2 default_resultset_attributes
435
436=over 4
437
438=item Arguments: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
439
440=item Return Value: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
441
442=item Default value: None
443
444=back
445
446Like L<DBIx::Class::ResultSource/resultset_attributes> stores a collection
447of resultset attributes, to be used as defaults for B<every> ResultSet
448instance schema-wide. The same list of CAVEATS and WARNINGS applies, with
449the extra downside of these defaults being practically inescapable: you will
450B<not> be able to derive a ResultSet instance with these attributes unset.
451
452Example:
453
454 package My::Schema;
455 use base qw/DBIx::Class::Schema/;
456 __PACKAGE__->default_resultset_attributes( { software_limit => 1 } );
457
829517d4 458=head2 exception_action
f017c022 459
829517d4 460=over 4
0f4ec1d2 461
829517d4 462=item Arguments: $code_reference
f017c022 463
fb13a49f 464=item Return Value: $code_reference
85bd0538 465
829517d4 466=item Default value: None
2374c5ff 467
829517d4 468=back
f017c022 469
c3e9f718 470When L</throw_exception> is invoked and L</exception_action> is set to a code
471reference, this reference will be called instead of
472L<DBIx::Class::Exception/throw>, with the exception message passed as the only
473argument.
f017c022 474
c3e9f718 475Your custom throw code B<must> rethrow the exception, as L</throw_exception> is
476an integral part of DBIC's internal execution control flow.
f017c022 477
829517d4 478Example:
f017c022 479
829517d4 480 package My::Schema;
481 use base qw/DBIx::Class::Schema/;
482 use My::ExceptionClass;
483 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
484 __PACKAGE__->load_classes;
2374c5ff 485
829517d4 486 # or:
487 my $schema_obj = My::Schema->connect( .... );
488 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
0f4ec1d2 489
829517d4 490=head2 stacktrace
f017c022 491
829517d4 492=over 4
2374c5ff 493
829517d4 494=item Arguments: boolean
2374c5ff 495
829517d4 496=back
2374c5ff 497
829517d4 498Whether L</throw_exception> should include stack trace information.
499Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
500is true.
0f4ec1d2 501
829517d4 502=head2 sqlt_deploy_hook
0f4ec1d2 503
829517d4 504=over
0f4ec1d2 505
829517d4 506=item Arguments: $sqlt_schema
2374c5ff 507
829517d4 508=back
2374c5ff 509
fd323bf1 510An optional sub which you can declare in your own Schema class that will get
829517d4 511passed the L<SQL::Translator::Schema> object when you deploy the schema via
512L</create_ddl_dir> or L</deploy>.
0f4ec1d2 513
fd323bf1 514For an example of what you can do with this, see
829517d4 515L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
fdcd8145 516
2d7d8459 517Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
518is called before L</deploy>. Therefore the hook can be used only to manipulate
519the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
520database. If you want to execute post-deploy statements which can not be generated
521by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
522and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
523
829517d4 524=head1 METHODS
2374c5ff 525
829517d4 526=head2 connect
87c4e602 527
27f01d1f 528=over 4
529
829517d4 530=item Arguments: @connectinfo
429bd4f1 531
d601dc88 532=item Return Value: $new_schema
27f01d1f 533
534=back
076652e8 535
829517d4 536Creates and returns a new Schema object. The connection info set on it
537is used to create a new instance of the storage backend and set it on
538the Schema object.
1c133e22 539
829517d4 540See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
5d52945a 541syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
829517d4 542general.
1c133e22 543
5d52945a 544Note that C<connect_info> expects an arrayref of arguments, but
faaba25f 545C<connect> does not. C<connect> wraps its arguments in an arrayref
5d52945a 546before passing them to C<connect_info>.
547
4c7d99ca 548=head3 Overloading
549
550C<connect> is a convenience method. It is equivalent to calling
551$schema->clone->connection(@connectinfo). To write your own overloaded
552version, overload L</connection> instead.
553
076652e8 554=cut
555
e5053694 556sub connect {
557 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
558 shift->clone->connection(@_);
559}
e678398e 560
829517d4 561=head2 resultset
77254782 562
27f01d1f 563=over 4
564
fb13a49f 565=item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
82b01c38 566
fb13a49f 567=item Return Value: L<$resultset|DBIx::Class::ResultSet>
27f01d1f 568
569=back
13765dad 570
829517d4 571 my $rs = $schema->resultset('DVD');
82b01c38 572
829517d4 573Returns the L<DBIx::Class::ResultSet> object for the registered source
574name.
77254782 575
576=cut
577
829517d4 578sub resultset {
fb13a49f 579 my ($self, $source_name) = @_;
73d47f9f 580 $self->throw_exception('resultset() expects a source name')
fb13a49f 581 unless defined $source_name;
582 return $self->source($source_name)->resultset;
b7951443 583}
584
829517d4 585=head2 sources
6b43ba5f 586
587=over 4
588
fb13a49f 589=item Return Value: L<@source_names|DBIx::Class::ResultSource/source_name>
6b43ba5f 590
591=back
592
829517d4 593 my @source_names = $schema->sources;
6b43ba5f 594
829517d4 595Lists names of all the sources registered on this Schema object.
6b43ba5f 596
829517d4 597=cut
161fb223 598
93d7452f 599sub sources { keys %{shift->source_registrations} }
106d5f3b 600
829517d4 601=head2 source
87c4e602 602
27f01d1f 603=over 4
604
fb13a49f 605=item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
66d9ef6b 606
fb13a49f 607=item Return Value: L<$result_source|DBIx::Class::ResultSource>
27f01d1f 608
609=back
82b01c38 610
829517d4 611 my $source = $schema->source('Book');
85f78622 612
829517d4 613Returns the L<DBIx::Class::ResultSource> object for the registered
614source name.
66d9ef6b 615
616=cut
617
829517d4 618sub source {
f5f2af8f 619 my $self = shift;
620
621 $self->throw_exception("source() expects a source name")
622 unless @_;
623
fb13a49f 624 my $source_name = shift;
f5f2af8f 625
829517d4 626 my $sreg = $self->source_registrations;
fb13a49f 627 return $sreg->{$source_name} if exists $sreg->{$source_name};
829517d4 628
629 # if we got here, they probably passed a full class name
fb13a49f 630 my $mapped = $self->class_mappings->{$source_name};
631 $self->throw_exception("Can't find source for ${source_name}")
829517d4 632 unless $mapped && exists $sreg->{$mapped};
633 return $sreg->{$mapped};
161fb223 634}
635
829517d4 636=head2 class
87c4e602 637
27f01d1f 638=over 4
639
fb13a49f 640=item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>
66d9ef6b 641
829517d4 642=item Return Value: $classname
27f01d1f 643
644=back
82b01c38 645
829517d4 646 my $class = $schema->class('CD');
647
648Retrieves the Result class name for the given source name.
66d9ef6b 649
650=cut
651
829517d4 652sub class {
4b8a53ea 653 return shift->source(shift)->result_class;
829517d4 654}
08b515f1 655
4012acd8 656=head2 txn_do
08b515f1 657
4012acd8 658=over 4
08b515f1 659
4012acd8 660=item Arguments: C<$coderef>, @coderef_args?
08b515f1 661
4012acd8 662=item Return Value: The return value of $coderef
08b515f1 663
4012acd8 664=back
08b515f1 665
4012acd8 666Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
667returning its result (if any). Equivalent to calling $schema->storage->txn_do.
668See L<DBIx::Class::Storage/"txn_do"> for more information.
08b515f1 669
4012acd8 670This interface is preferred over using the individual methods L</txn_begin>,
671L</txn_commit>, and L</txn_rollback> below.
08b515f1 672
f9f06ae0 673WARNING: If you are connected with C<< AutoCommit => 0 >> the transaction is
281719d2 674considered nested, and you will still need to call L</txn_commit> to write your
f9f06ae0 675changes when appropriate. You will also want to connect with C<< auto_savepoint =>
6761 >> to get partial rollback to work, if the storage driver for your database
281719d2 677supports it.
678
f9f06ae0 679Connecting with C<< AutoCommit => 1 >> is recommended.
281719d2 680
4012acd8 681=cut
08b515f1 682
4012acd8 683sub txn_do {
684 my $self = shift;
08b515f1 685
4012acd8 686 $self->storage or $self->throw_exception
687 ('txn_do called on $schema without storage');
08b515f1 688
4012acd8 689 $self->storage->txn_do(@_);
690}
66d9ef6b 691
6936e902 692=head2 txn_scope_guard
75c8a7ab 693
fd323bf1 694Runs C<txn_scope_guard> on the schema's storage. See
89028f42 695L<DBIx::Class::Storage/txn_scope_guard>.
75c8a7ab 696
b85be4c1 697=cut
698
1bc193ac 699sub txn_scope_guard {
700 my $self = shift;
701
702 $self->storage or $self->throw_exception
703 ('txn_scope_guard called on $schema without storage');
704
705 $self->storage->txn_scope_guard(@_);
706}
707
4012acd8 708=head2 txn_begin
a62cf8d4 709
4012acd8 710Begins a transaction (does nothing if AutoCommit is off). Equivalent to
711calling $schema->storage->txn_begin. See
8bfce9d5 712L<DBIx::Class::Storage/"txn_begin"> for more information.
27f01d1f 713
4012acd8 714=cut
82b01c38 715
4012acd8 716sub txn_begin {
717 my $self = shift;
27f01d1f 718
4012acd8 719 $self->storage or $self->throw_exception
720 ('txn_begin called on $schema without storage');
a62cf8d4 721
4012acd8 722 $self->storage->txn_begin;
723}
a62cf8d4 724
4012acd8 725=head2 txn_commit
a62cf8d4 726
4012acd8 727Commits the current transaction. Equivalent to calling
8bfce9d5 728$schema->storage->txn_commit. See L<DBIx::Class::Storage/"txn_commit">
4012acd8 729for more information.
a62cf8d4 730
4012acd8 731=cut
a62cf8d4 732
4012acd8 733sub txn_commit {
734 my $self = shift;
a62cf8d4 735
4012acd8 736 $self->storage or $self->throw_exception
737 ('txn_commit called on $schema without storage');
a62cf8d4 738
4012acd8 739 $self->storage->txn_commit;
740}
70634260 741
4012acd8 742=head2 txn_rollback
a62cf8d4 743
4012acd8 744Rolls back the current transaction. Equivalent to calling
745$schema->storage->txn_rollback. See
8bfce9d5 746L<DBIx::Class::Storage/"txn_rollback"> for more information.
a62cf8d4 747
748=cut
749
4012acd8 750sub txn_rollback {
751 my $self = shift;
a62cf8d4 752
19630353 753 $self->storage or $self->throw_exception
4012acd8 754 ('txn_rollback called on $schema without storage');
a62cf8d4 755
4012acd8 756 $self->storage->txn_rollback;
a62cf8d4 757}
758
829517d4 759=head2 storage
66d9ef6b 760
829517d4 761 my $storage = $schema->storage;
04786a4c 762
829517d4 763Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
764if you want to turn on SQL statement debugging at runtime, or set the
765quote character. For the default storage, the documentation can be
766found in L<DBIx::Class::Storage::DBI>.
66d9ef6b 767
87c4e602 768=head2 populate
769
27f01d1f 770=over 4
771
44e95db4 772=item Arguments: L<$source_name|DBIx::Class::ResultSource/source_name>, [ \@column_list, \@row_values+ ] | [ \%col_data+ ]
27f01d1f 773
44e95db4 774=item Return Value: L<\@result_objects|DBIx::Class::Manual::ResultClass> (scalar context) | L<@result_objects|DBIx::Class::Manual::ResultClass> (list context)
829517d4 775
27f01d1f 776=back
a37a4697 777
44e95db4 778A convenience shortcut to L<DBIx::Class::ResultSet/populate>. Equivalent to:
779
780 $schema->resultset($source_name)->populate([...]);
781
782=over 4
783
784=item NOTE
785
786The context of this method call has an important effect on what is
787submitted to storage. In void context data is fed directly to fastpath
788insertion routines provided by the underlying storage (most often
789L<DBI/execute_for_fetch>), bypassing the L<new|DBIx::Class::Row/new> and
790L<insert|DBIx::Class::Row/insert> calls on the
791L<Result|DBIx::Class::Manual::ResultClass> class, including any
792augmentation of these methods provided by components. For example if you
793are using something like L<DBIx::Class::UUIDColumns> to create primary
794keys for you, you will find that your PKs are empty. In this case you
795will have to explicitly force scalar or list context in order to create
796those values.
797
798=back
a37a4697 799
800=cut
801
802sub populate {
e5053694 803 DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
804
a37a4697 805 my ($self, $name, $data) = @_;
4b8a53ea 806 my $rs = $self->resultset($name)
807 or $self->throw_exception("'$name' is not a resultset");
808
809 return $rs->populate($data);
a37a4697 810}
811
829517d4 812=head2 connection
813
814=over 4
815
816=item Arguments: @args
817
759a7f44 818=item Return Value: $self
829517d4 819
820=back
821
822Similar to L</connect> except sets the storage object and connection
759a7f44 823data B<in-place> on C<$self>. You should probably be calling
824L</connect> to get a properly L<cloned|/clone> Schema object instead.
829517d4 825
4c7d99ca 826=head3 Overloading
827
828Overload C<connection> to change the behaviour of C<connect>.
829517d4 829
830=cut
831
832sub connection {
833 my ($self, @info) = @_;
834 return $self if !@info && $self->storage;
d4daee7b 835
93d7452f 836 my ($storage_class, $args) = ref $self->storage_type
837 ? $self->_normalize_storage_type($self->storage_type)
838 : $self->storage_type
839 ;
840
841 $storage_class =~ s/^::/DBIx::Class::Storage::/;
d4daee7b 842
ddcc02d1 843 dbic_internal_try {
9780718f 844 $self->ensure_class_loaded ($storage_class);
845 }
846 catch {
847 $self->throw_exception(
dee99c24 848 "Unable to load storage class ${storage_class}: $_"
9780718f 849 );
850 };
93d7452f 851
852 my $storage = $storage_class->new( $self => $args||{} );
829517d4 853 $storage->connect_info(\@info);
854 $self->storage($storage);
855 return $self;
856}
857
858sub _normalize_storage_type {
859 my ($self, $storage_type) = @_;
860 if(ref $storage_type eq 'ARRAY') {
861 return @$storage_type;
862 } elsif(ref $storage_type eq 'HASH') {
863 return %$storage_type;
864 } else {
865 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
866 }
867}
868
869=head2 compose_namespace
82cc0386 870
871=over 4
872
829517d4 873=item Arguments: $target_namespace, $additional_base_class?
874
8600b1c1 875=item Return Value: $new_schema
829517d4 876
877=back
878
879For each L<DBIx::Class::ResultSource> in the schema, this method creates a
880class in the target namespace (e.g. $target_namespace::CD,
881$target_namespace::Artist) that inherits from the corresponding classes
882attached to the current schema.
883
884It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
885new $schema object. If C<$additional_base_class> is given, the new composed
48580715 886classes will inherit from first the corresponding class from the current
829517d4 887schema then the base class.
888
889For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
890
891 $schema->compose_namespace('My::DB', 'Base::Class');
892 print join (', ', @My::DB::CD::ISA) . "\n";
893 print join (', ', @My::DB::Artist::ISA) ."\n";
894
895will produce the output
896
897 My::Schema::CD, Base::Class
898 My::Schema::Artist, Base::Class
899
900=cut
901
829517d4 902sub compose_namespace {
903 my ($self, $target, $base) = @_;
dee99c24 904
829517d4 905 my $schema = $self->clone;
dee99c24 906
907 $schema->source_registrations({});
908
909 # the original class-mappings must remain - otherwise
910 # reverse_relationship_info will not work
911 #$schema->class_mappings({});
912
829517d4 913 {
914 no warnings qw/redefine/;
87bf71d5 915 local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
916 use warnings qw/redefine/;
917
fb13a49f 918 foreach my $source_name ($self->sources) {
919 my $orig_source = $self->source($source_name);
dee99c24 920
fb13a49f 921 my $target_class = "${target}::${source_name}";
dee99c24 922 $self->inject_base($target_class, $orig_source->result_class, ($base || ()) );
923
924 # register_source examines result_class, and then returns us a clone
fb13a49f 925 my $new_source = $schema->register_source($source_name, bless
dee99c24 926 { %$orig_source, result_class => $target_class },
927 ref $orig_source,
829517d4 928 );
a8c2c746 929
dee99c24 930 if ($target_class->can('result_source_instance')) {
931 # give the class a schema-less source copy
932 $target_class->result_source_instance( bless
933 { %$new_source, schema => ref $new_source->{schema} || $new_source->{schema} },
934 ref $new_source,
935 );
a8c2c746 936 }
829517d4 937 }
dee99c24 938
d99f2db7 939 # Legacy stuff, not inserting INDIRECT assertions
8d73fcd4 940 quote_sub "${target}::${_}" => "shift->schema->$_(\@_)"
941 for qw(class source resultset);
829517d4 942 }
dee99c24 943
944 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
945
829517d4 946 return $schema;
947}
948
759a7f44 949# LEGACY: The intra-call to this was removed in 66d9ef6b and then
950# the sub was de-documented way later in 249963d4. No way to be sure
951# nothing on darkpan is calling it directly, so keeping as-is
829517d4 952sub setup_connection_class {
953 my ($class, $target, @info) = @_;
954 $class->inject_base($target => 'DBIx::Class::DB');
955 #$target->load_components('DB');
956 $target->connection(@info);
957}
958
959=head2 svp_begin
960
fd323bf1 961Creates a new savepoint (does nothing outside a transaction).
829517d4 962Equivalent to calling $schema->storage->svp_begin. See
8bfce9d5 963L<DBIx::Class::Storage/"svp_begin"> for more information.
829517d4 964
965=cut
966
967sub svp_begin {
968 my ($self, $name) = @_;
969
970 $self->storage or $self->throw_exception
971 ('svp_begin called on $schema without storage');
972
973 $self->storage->svp_begin($name);
974}
975
976=head2 svp_release
977
fd323bf1 978Releases a savepoint (does nothing outside a transaction).
829517d4 979Equivalent to calling $schema->storage->svp_release. See
8bfce9d5 980L<DBIx::Class::Storage/"svp_release"> for more information.
829517d4 981
982=cut
983
984sub svp_release {
985 my ($self, $name) = @_;
986
987 $self->storage or $self->throw_exception
988 ('svp_release called on $schema without storage');
82cc0386 989
829517d4 990 $self->storage->svp_release($name);
991}
82cc0386 992
829517d4 993=head2 svp_rollback
db5dc233 994
fd323bf1 995Rollback to a savepoint (does nothing outside a transaction).
829517d4 996Equivalent to calling $schema->storage->svp_rollback. See
8bfce9d5 997L<DBIx::Class::Storage/"svp_rollback"> for more information.
82cc0386 998
829517d4 999=cut
82cc0386 1000
829517d4 1001sub svp_rollback {
1002 my ($self, $name) = @_;
82cc0386 1003
829517d4 1004 $self->storage or $self->throw_exception
1005 ('svp_rollback called on $schema without storage');
82cc0386 1006
829517d4 1007 $self->storage->svp_rollback($name);
1008}
db5dc233 1009
829517d4 1010=head2 clone
613397e7 1011
84c5863b 1012=over 4
613397e7 1013
71829446 1014=item Arguments: %attrs?
1015
829517d4 1016=item Return Value: $new_schema
613397e7 1017
1018=back
1019
829517d4 1020Clones the schema and its associated result_source objects and returns the
71829446 1021copy. The resulting copy will have the same attributes as the source schema,
4a0eed52 1022except for those attributes explicitly overridden by the provided C<%attrs>.
829517d4 1023
1024=cut
1025
1026sub clone {
71829446 1027 my $self = shift;
1028
1029 my $clone = {
1030 (ref $self ? %$self : ()),
1031 (@_ == 1 && ref $_[0] eq 'HASH' ? %{ $_[0] } : @_),
1032 };
829517d4 1033 bless $clone, (ref $self || $self);
1034
93963f59 1035 $clone->$_(undef) for qw/class_mappings source_registrations storage/;
1036
1037 $clone->_copy_state_from($self);
1038
1039 return $clone;
1040}
1041
1042# Needed in Schema::Loader - if you refactor, please make a compatibility shim
1043# -- Caelum
1044sub _copy_state_from {
1045 my ($self, $from) = @_;
1046
1047 $self->class_mappings({ %{$from->class_mappings} });
1048 $self->source_registrations({ %{$from->source_registrations} });
1049
fb13a49f 1050 foreach my $source_name ($from->sources) {
1051 my $source = $from->source($source_name);
829517d4 1052 my $new = $source->new($source);
1053 # we use extra here as we want to leave the class_mappings as they are
1054 # but overwrite the source_registrations entry with the new source
fb13a49f 1055 $self->register_extra_source($source_name => $new);
829517d4 1056 }
dee99c24 1057
93963f59 1058 if ($from->storage) {
1059 $self->storage($from->storage);
1060 $self->storage->set_schema($self);
1061 }
829517d4 1062}
613397e7 1063
5160b401 1064=head2 throw_exception
701da8c4 1065
75d07914 1066=over 4
82b01c38 1067
ebc77b53 1068=item Arguments: $message
82b01c38 1069
1070=back
1071
70c28808 1072Throws an exception. Obeys the exemption rules of L<DBIx::Class::Carp> to report
1073errors from outer-user's perspective. See L</exception_action> for details on overriding
4b946902 1074this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1075default behavior will provide a detailed stack trace.
701da8c4 1076
1077=cut
1078
1079sub throw_exception {
e240b8ba 1080 my ($self, @args) = @_;
4981dc70 1081
ddcc02d1 1082 if (
1083 ! DBIx::Class::_Util::in_internal_try()
1084 and
1085 my $act = $self->exception_action
1086 ) {
7cb35852 1087
1088 my $guard_disarmed;
1089
1090 my $guard = scope_guard {
1091 return if $guard_disarmed;
7db939de 1092 local $SIG{__WARN__} if $SIG{__WARN__};
7cb35852 1093 Carp::cluck("
1094 !!! DBIx::Class INTERNAL PANIC !!!
1095
1096The exception_action() handler installed on '$self'
1097aborted the stacktrace below via a longjmp (either via Return::Multilevel or
1098plain goto, or Scope::Upper or something equally nefarious). There currently
1099is nothing safe DBIx::Class can do, aside from displaying this error. A future
1100version ( 0.082900, when available ) will reduce the cases in which the
1101handler is invoked, but this is neither a complete solution, nor can it do
1102anything for other software that might be affected by a similar problem.
1103
1104 !!! FIX YOUR ERROR HANDLING !!!
1105
1106This guard was activated beginning"
1107 );
1108 };
1109
7704dbc9 1110 dbic_internal_try {
118b2c36 1111 # if it throws - good, we'll assign to @args in the end
e240b8ba 1112 # if it doesn't - do different things depending on RV truthiness
1113 if( $act->(@args) ) {
1114 $args[0] = (
c3e9f718 1115 "Invocation of the exception_action handler installed on $self did *not*"
1116 .' result in an exception. DBIx::Class is unable to function without a reliable'
118b2c36 1117 .' exception mechanism, ensure your exception_action does not hide exceptions'
e240b8ba 1118 ." (original error: $args[0])"
1119 );
1120 }
1121 else {
1122 carp_unique (
1123 "The exception_action handler installed on $self returned false instead"
1124 .' of throwing an exception. This behavior has been deprecated, adjust your'
7cb35852 1125 .' handler to always rethrow the supplied error'
e240b8ba 1126 );
1127 }
7cb35852 1128
118b2c36 1129 1;
7cb35852 1130 }
7704dbc9 1131 catch {
1132 # We call this to get the necessary warnings emitted and disregard the RV
1133 # as it's definitely an exception if we got as far as this catch{} block
1134 is_exception(
1135 $args[0] = $_
1136 );
1137 };
f9080e45 1138
118b2c36 1139 # Done guarding against https://github.com/PerlDancer/Dancer2/issues/1125
1140 $guard_disarmed = 1;
c3e9f718 1141 }
1142
e240b8ba 1143 DBIx::Class::Exception->throw( $args[0], $self->stacktrace );
701da8c4 1144}
1145
dfccde48 1146=head2 deploy
1c339d71 1147
82b01c38 1148=over 4
1149
10976519 1150=item Arguments: \%sqlt_args, $dir
82b01c38 1151
1152=back
1153
1154Attempts to deploy the schema to the current storage using L<SQL::Translator>.
ec6704d4 1155
10976519 1156See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1157The most common value for this would be C<< { add_drop_table => 1 } >>
1158to have the SQL produced include a C<DROP TABLE> statement for each table
b5d783cd 1159created. For quoting purposes supply C<quote_identifiers>.
51bace1c 1160
fd323bf1 1161Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1162ref or an array ref, containing a list of source to deploy. If present, then
0e2c6809 1163only the sources listed will get deployed. Furthermore, you can use the
1164C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1165FK.
499adf63 1166
1c339d71 1167=cut
1168
1169sub deploy {
6e73ac25 1170 my ($self, $sqltargs, $dir) = @_;
1c339d71 1171 $self->throw_exception("Can't deploy without storage") unless $self->storage;
6e73ac25 1172 $self->storage->deploy($self, undef, $sqltargs, $dir);
1c339d71 1173}
1174
0e0ce6c1 1175=head2 deployment_statements
1176
1177=over 4
1178
10976519 1179=item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
0e0ce6c1 1180
fb13a49f 1181=item Return Value: $listofstatements
829517d4 1182
0e0ce6c1 1183=back
1184
10976519 1185A convenient shortcut to
1186C<< $self->storage->deployment_statements($self, @args) >>.
5529838f 1187Returns the statements used by L</deploy> and
1188L<DBIx::Class::Storage/deploy>.
0e0ce6c1 1189
1190=cut
1191
1192sub deployment_statements {
7ad93f5a 1193 my $self = shift;
0e0ce6c1 1194
1195 $self->throw_exception("Can't generate deployment statements without a storage")
1196 if not $self->storage;
1197
7ad93f5a 1198 $self->storage->deployment_statements($self, @_);
0e0ce6c1 1199}
1200
6dfbe2f8 1201=head2 create_ddl_dir
c0f61310 1202
1203=over 4
1204
10976519 1205=item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
c0f61310 1206
1207=back
1208
fd323bf1 1209A convenient shortcut to
10976519 1210C<< $self->storage->create_ddl_dir($self, @args) >>.
c9d2e0a2 1211
10976519 1212Creates an SQL file based on the Schema, for each of the specified
1213database types, in the given directory.
c9d2e0a2 1214
c0f61310 1215=cut
1216
6e73ac25 1217sub create_ddl_dir {
e673f011 1218 my $self = shift;
1219
1220 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1221 $self->storage->create_ddl_dir($self, @_);
1222}
1223
e63a82f7 1224=head2 ddl_filename
9b83fccd 1225
c9d2e0a2 1226=over 4
1227
99a74c4a 1228=item Arguments: $database-type, $version, $directory, $preversion
c9d2e0a2 1229
fb13a49f 1230=item Return Value: $normalised_filename
829517d4 1231
c9d2e0a2 1232=back
1233
99a74c4a 1234 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
c9d2e0a2 1235
1236This method is called by C<create_ddl_dir> to compose a file name out of
1237the supplied directory, database type and version number. The default file
1238name format is: C<$dir$schema-$version-$type.sql>.
9b83fccd 1239
c9d2e0a2 1240You may override this method in your schema if you wish to use a different
1241format.
9b83fccd 1242
1acfef8e 1243 WARNING
1244
1245 Prior to DBIx::Class version 0.08100 this method had a different signature:
1246
1247 my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1248
1249 In recent versions variables $dir and $version were reversed in order to
fd323bf1 1250 bring the signature in line with other Schema/Storage methods. If you
1acfef8e 1251 really need to maintain backward compatibility, you can do the following
1252 in any overriding methods:
1253
1254 ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1255
9b83fccd 1256=cut
1257
6e73ac25 1258sub ddl_filename {
99a74c4a 1259 my ($self, $type, $version, $dir, $preversion) = @_;
e673f011 1260
aea59b74 1261 $version = "$preversion-$version" if $preversion;
d4daee7b 1262
aea59b74 1263 my $class = blessed($self) || $self;
1264 $class =~ s/::/-/g;
1265
aff5e9c1 1266 return "$dir/$class-$version-$type.sql";
e673f011 1267}
1268
4146e3da 1269=head2 thaw
1270
fd323bf1 1271Provided as the recommended way of thawing schema objects. You can call
4146e3da 1272C<Storable::thaw> directly if you wish, but the thawed objects will not have a
48580715 1273reference to any schema, so are rather useless.
4146e3da 1274
1275=cut
1276
1277sub thaw {
1278 my ($self, $obj) = @_;
1279 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1280 return Storable::thaw($obj);
1281}
1282
1283=head2 freeze
1284
5529838f 1285This doesn't actually do anything beyond calling L<nfreeze|Storable/SYNOPSIS>,
1286it is just provided here for symmetry.
4146e3da 1287
d2f3e87b 1288=cut
1289
4146e3da 1290sub freeze {
26148d36 1291 return Storable::nfreeze($_[1]);
4146e3da 1292}
1293
1294=head2 dclone
1295
1477a478 1296=over 4
1297
1298=item Arguments: $object
1299
1300=item Return Value: dcloned $object
1301
1302=back
1303
9e9ecfda 1304Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1305objects so their references to the schema object
1306(which itself is B<not> cloned) are properly maintained.
4146e3da 1307
1308=cut
1309
1310sub dclone {
1311 my ($self, $obj) = @_;
1312 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1313 return Storable::dclone($obj);
1314}
1315
93e4d41a 1316=head2 schema_version
1317
829517d4 1318Returns the current schema class' $VERSION in a normalised way.
93e4d41a 1319
1320=cut
1321
1322sub schema_version {
1323 my ($self) = @_;
1324 my $class = ref($self)||$self;
1325
1326 # does -not- use $schema->VERSION
1327 # since that varies in results depending on if version.pm is installed, and if
1328 # so the perl or XS versions. If you want this to change, bug the version.pm
1329 # author to make vpp and vxs behave the same.
1330
1331 my $version;
1332 {
1333 no strict 'refs';
1334 $version = ${"${class}::VERSION"};
1335 }
1336 return $version;
1337}
1338
829517d4 1339
1340=head2 register_class
1341
1342=over 4
1343
fb13a49f 1344=item Arguments: $source_name, $component_class
829517d4 1345
1346=back
1347
fd323bf1 1348This 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.
829517d4 1349
1350You will only need this method if you have your Result classes in
1351files which are not named after the packages (or all in the same
1352file). You may also need it to register classes at runtime.
1353
1354Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1355calling:
1356
fb13a49f 1357 $schema->register_source($source_name, $component_class->result_source_instance);
829517d4 1358
1359=cut
1360
1361sub register_class {
fb13a49f 1362 my ($self, $source_name, $to_register) = @_;
1363 $self->register_source($source_name => $to_register->result_source_instance);
829517d4 1364}
1365
1366=head2 register_source
1367
1368=over 4
1369
fb13a49f 1370=item Arguments: $source_name, L<$result_source|DBIx::Class::ResultSource>
829517d4 1371
1372=back
1373
1374This method is called by L</register_class>.
1375
1376Registers the L<DBIx::Class::ResultSource> in the schema with the given
fb13a49f 1377source name.
829517d4 1378
1379=cut
1380
dee99c24 1381sub register_source { shift->_register_source(@_) }
829517d4 1382
98cabed3 1383=head2 unregister_source
1384
1385=over 4
1386
fb13a49f 1387=item Arguments: $source_name
98cabed3 1388
1389=back
1390
fb13a49f 1391Removes the L<DBIx::Class::ResultSource> from the schema for the given source name.
98cabed3 1392
1393=cut
1394
dee99c24 1395sub unregister_source { shift->_unregister_source(@_) }
98cabed3 1396
829517d4 1397=head2 register_extra_source
1398
1399=over 4
1400
fb13a49f 1401=item Arguments: $source_name, L<$result_source|DBIx::Class::ResultSource>
829517d4 1402
1403=back
1404
fd323bf1 1405As L</register_source> but should be used if the result class already
829517d4 1406has a source and you want to register an extra one.
1407
1408=cut
1409
dee99c24 1410sub register_extra_source { shift->_register_source(@_, { extra => 1 }) }
829517d4 1411
1412sub _register_source {
fb13a49f 1413 my ($self, $source_name, $source, $params) = @_;
829517d4 1414
fb13a49f 1415 $source = $source->new({ %$source, source_name => $source_name });
dee99c24 1416
2461ae19 1417 $source->schema($self);
6298a324 1418 weaken $source->{schema} if ref($self);
2461ae19 1419
829517d4 1420 my %reg = %{$self->source_registrations};
fb13a49f 1421 $reg{$source_name} = $source;
829517d4 1422 $self->source_registrations(\%reg);
1423
dee99c24 1424 return $source if $params->{extra};
1425
1426 my $rs_class = $source->result_class;
ddcc02d1 1427 if ($rs_class and my $rsrc = dbic_internal_try { $rs_class->result_source_instance } ) {
dee99c24 1428 my %map = %{$self->class_mappings};
1429 if (
1430 exists $map{$rs_class}
1431 and
fb13a49f 1432 $map{$rs_class} ne $source_name
dee99c24 1433 and
1434 $rsrc ne $_[2] # orig_source
1435 ) {
1436 carp
1437 "$rs_class already had a registered source which was replaced by this call. "
1438 . 'Perhaps you wanted register_extra_source(), though it is more likely you did '
1439 . 'something wrong.'
1440 ;
1441 }
1442
fb13a49f 1443 $map{$rs_class} = $source_name;
dee99c24 1444 $self->class_mappings(\%map);
829517d4 1445 }
dee99c24 1446
1447 return $source;
829517d4 1448}
1449
a4367b26 1450my $global_phase_destroy;
1451sub DESTROY {
e1d9e578 1452 ### NO detected_reinvoked_destructor check
3d56e026 1453 ### This code very much relies on being called multuple times
1454
a4367b26 1455 return if $global_phase_destroy ||= in_global_destruction;
66917da3 1456
a4367b26 1457 my $self = shift;
1458 my $srcs = $self->source_registrations;
1459
fb13a49f 1460 for my $source_name (keys %$srcs) {
a4367b26 1461 # find first source that is not about to be GCed (someone other than $self
1462 # holds a reference to it) and reattach to it, weakening our own link
1463 #
1464 # during global destruction (if we have not yet bailed out) this should throw
1465 # which will serve as a signal to not try doing anything else
1466 # however beware - on older perls the exception seems randomly untrappable
1467 # due to some weird race condition during thread joining :(((
dac7972a 1468 if (length ref $srcs->{$source_name} and refcount($srcs->{$source_name}) > 1) {
5c33c8be 1469 local $SIG{__DIE__} if $SIG{__DIE__};
7db939de 1470 local $@ if DBIx::Class::_ENV_::UNSTABLE_DOLLARAT;
a4367b26 1471 eval {
fb13a49f 1472 $srcs->{$source_name}->schema($self);
1473 weaken $srcs->{$source_name};
a4367b26 1474 1;
1475 } or do {
1476 $global_phase_destroy = 1;
1477 };
1478
1479 last;
50261284 1480 }
1481 }
d52fc26d 1482
1483 # Dummy NEXTSTATE ensuring the all temporaries on the stack are garbage
1484 # collected before leaving this scope. Depending on the code above, this
1485 # may very well be just a preventive measure guarding future modifications
1486 undef;
50261284 1487}
1488
829517d4 1489sub _unregister_source {
fb13a49f 1490 my ($self, $source_name) = @_;
fd323bf1 1491 my %reg = %{$self->source_registrations};
829517d4 1492
fb13a49f 1493 my $source = delete $reg{$source_name};
829517d4 1494 $self->source_registrations(\%reg);
1495 if ($source->result_class) {
1496 my %map = %{$self->class_mappings};
1497 delete $map{$source->result_class};
1498 $self->class_mappings(\%map);
1499 }
1500}
1501
1502
1503=head2 compose_connection (DEPRECATED)
1504
1505=over 4
1506
1507=item Arguments: $target_namespace, @db_info
1508
1509=item Return Value: $new_schema
1510
1511=back
1512
1513DEPRECATED. You probably wanted compose_namespace.
1514
1515Actually, you probably just wanted to call connect.
1516
1517=begin hidden
1518
1519(hidden due to deprecation)
1520
1521Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1522calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1523then injects the L<DBix::Class::ResultSetProxy> component and a
1524resultset_instance classdata entry on all the new classes, in order to support
1525$target_namespaces::$class->search(...) method calls.
1526
1527This is primarily useful when you have a specific need for class method access
1528to a connection. In normal usage it is preferred to call
1529L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1530on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1531more information.
1532
1533=end hidden
1534
1535=cut
1536
e42bbd7f 1537sub compose_connection {
1538 my ($self, $target, @info) = @_;
829517d4 1539
e42bbd7f 1540 carp_once "compose_connection deprecated as of 0.08000"
1541 unless $INC{"DBIx/Class/CDBICompat.pm"};
d4daee7b 1542
ddcc02d1 1543 dbic_internal_try {
63a18cfe 1544 require DBIx::Class::ResultSetProxy;
e42bbd7f 1545 }
1546 catch {
1547 $self->throw_exception
63a18cfe 1548 ("No arguments to load_classes and couldn't load DBIx::Class::ResultSetProxy ($_)")
e42bbd7f 1549 };
d4daee7b 1550
e42bbd7f 1551 if ($self eq $target) {
1552 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
fb13a49f 1553 foreach my $source_name ($self->sources) {
1554 my $source = $self->source($source_name);
829517d4 1555 my $class = $source->result_class;
63a18cfe 1556 $self->inject_base($class, 'DBIx::Class::ResultSetProxy');
e5053694 1557 $class->mk_classaccessor(resultset_instance => $source->resultset);
1558 $class->mk_classaccessor(class_resolver => $self);
829517d4 1559 }
e42bbd7f 1560 $self->connection(@info);
1561 return $self;
1562 }
1563
63a18cfe 1564 my $schema = $self->compose_namespace($target, 'DBIx::Class::ResultSetProxy');
8d73fcd4 1565 quote_sub "${target}::schema", '$s', { '$s' => \$schema };
e42bbd7f 1566
1567 $schema->connection(@info);
fb13a49f 1568 foreach my $source_name ($schema->sources) {
1569 my $source = $schema->source($source_name);
e42bbd7f 1570 my $class = $source->result_class;
fb13a49f 1571 #warn "$source_name $class $source ".$source->storage;
e5053694 1572 $class->mk_classaccessor(result_source_instance => $source);
1573 $class->mk_classaccessor(resultset_instance => $source->resultset);
1574 $class->mk_classaccessor(class_resolver => $schema);
e42bbd7f 1575 }
1576 return $schema;
829517d4 1577}
1578
a2bd3796 1579=head1 FURTHER QUESTIONS?
c2da098a 1580
a2bd3796 1581Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
c2da098a 1582
a2bd3796 1583=head1 COPYRIGHT AND LICENSE
c2da098a 1584
a2bd3796 1585This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1586by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1587redistribute it and/or modify it under the same terms as the
1588L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
c2da098a 1589
1590=cut
a2bd3796 1591
15921;