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