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