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