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