use namespace::clean w/ Try::Tiny
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Schema.pm
CommitLineData
a02675cd 1package DBIx::Class::Schema;
2
3use strict;
4use warnings;
aa562407 5
4981dc70 6use DBIx::Class::Exception;
701da8c4 7use Carp::Clan qw/^DBIx::Class/;
9780718f 8use Try::Tiny;
551e711a 9use Scalar::Util ();
c9d2e0a2 10use File::Spec;
ddc0a6c8 11use Sub::Name ();
329d7385 12use Module::Find();
fd323bf1 13use namespace::clean;
a02675cd 14
41a6f8c0 15use base qw/DBIx::Class/;
a02675cd 16
0dc79249 17__PACKAGE__->mk_classdata('class_mappings' => {});
18__PACKAGE__->mk_classdata('source_registrations' => {});
1e10a11d 19__PACKAGE__->mk_classdata('storage_type' => '::DBI');
d7156e50 20__PACKAGE__->mk_classdata('storage');
82cc0386 21__PACKAGE__->mk_classdata('exception_action');
4b946902 22__PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
e6c747fd 23__PACKAGE__->mk_classdata('default_resultset_attributes' => {});
a02675cd 24
c2da098a 25=head1 NAME
26
27DBIx::Class::Schema - composable schemas
28
29=head1 SYNOPSIS
30
24d67825 31 package Library::Schema;
c2da098a 32 use base qw/DBIx::Class::Schema/;
bab77431 33
829517d4 34 # load all Result classes in Library/Schema/Result/
35 __PACKAGE__->load_namespaces();
c2da098a 36
829517d4 37 package Library::Schema::Result::CD;
d88ecca6 38 use base qw/DBIx::Class::Core/;
39
40 __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
24d67825 41 __PACKAGE__->table('cd');
c2da098a 42
5d9076f2 43 # Elsewhere in your code:
24d67825 44 my $schema1 = Library::Schema->connect(
a3d93194 45 $dsn,
46 $user,
47 $password,
ef131d82 48 { AutoCommit => 1 },
a3d93194 49 );
bab77431 50
24d67825 51 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
c2da098a 52
829517d4 53 # fetch objects using Library::Schema::Result::DVD
24d67825 54 my $resultset = $schema1->resultset('DVD')->search( ... );
55 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
c2da098a 56
57=head1 DESCRIPTION
58
a3d93194 59Creates database classes based on a schema. This is the recommended way to
60use L<DBIx::Class> and allows you to use more than one concurrent connection
61with your classes.
429bd4f1 62
03312470 63NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
2053ab2a 64carefully, as DBIx::Class does things a little differently. Note in
03312470 65particular which module inherits off which.
66
829517d4 67=head1 SETUP METHODS
c2da098a 68
829517d4 69=head2 load_namespaces
87c4e602 70
27f01d1f 71=over 4
72
829517d4 73=item Arguments: %options?
27f01d1f 74
75=back
076652e8 76
829517d4 77 __PACKAGE__->load_namespaces();
66d9ef6b 78
829517d4 79 __PACKAGE__->load_namespaces(
80 result_namespace => 'Res',
81 resultset_namespace => 'RSet',
82 default_resultset_class => '+MyDB::Othernamespace::RSet',
83 );
076652e8 84
829517d4 85With no arguments, this method uses L<Module::Find> to load all your
86Result classes from a sub-namespace F<Result> under your Schema class'
48580715 87namespace, i.e. with a Schema of I<MyDB::Schema> all files in
829517d4 88I<MyDB::Schema::Result> are assumed to be Result classes.
c2da098a 89
829517d4 90It also finds all ResultSet classes in the namespace F<ResultSet> and
91loads them into the appropriate Result classes using for you. The
92matching is done by assuming the package name of the ResultSet class
93is the same as that of the Result class.
74b92d9a 94
672687db 95You will be warned if ResultSet classes are discovered for which there
829517d4 96are no matching Result classes like this:
87c4e602 97
829517d4 98 load_namespaces found ResultSet class $classname with no corresponding Result class
27f01d1f 99
829517d4 100If a Result class is found to already have a ResultSet class set using
101L</resultset_class> to some other class, you will be warned like this:
27f01d1f 102
fd323bf1 103 We found ResultSet class '$rs_class' for '$result', but it seems
829517d4 104 that you had already set '$result' to use '$rs_set' instead
076652e8 105
829517d4 106Both of the sub-namespaces are configurable if you don't like the defaults,
107via the options C<result_namespace> and C<resultset_namespace>.
076652e8 108
829517d4 109If (and only if) you specify the option C<default_resultset_class>, any found
110Result classes for which we do not find a corresponding
111ResultSet class will have their C<resultset_class> set to
112C<default_resultset_class>.
076652e8 113
829517d4 114All of the namespace and classname options to this method are relative to
115the schema classname by default. To specify a fully-qualified name, prefix
116it with a literal C<+>.
2a4d9487 117
829517d4 118Examples:
2a4d9487 119
829517d4 120 # load My::Schema::Result::CD, My::Schema::Result::Artist,
121 # My::Schema::ResultSet::CD, etc...
122 My::Schema->load_namespaces;
2a4d9487 123
829517d4 124 # Override everything to use ugly names.
125 # In this example, if there is a My::Schema::Res::Foo, but no matching
126 # My::Schema::RSets::Foo, then Foo will have its
127 # resultset_class set to My::Schema::RSetBase
128 My::Schema->load_namespaces(
129 result_namespace => 'Res',
130 resultset_namespace => 'RSets',
131 default_resultset_class => 'RSetBase',
132 );
2a4d9487 133
829517d4 134 # Put things in other namespaces
135 My::Schema->load_namespaces(
136 result_namespace => '+Some::Place::Results',
137 resultset_namespace => '+Another::Place::RSets',
138 );
2a4d9487 139
829517d4 140If you'd like to use multiple namespaces of each type, simply use an arrayref
141of namespaces for that option. In the case that the same result
142(or resultset) class exists in multiple namespaces, the latter entries in
143your list of namespaces will override earlier ones.
2a4d9487 144
829517d4 145 My::Schema->load_namespaces(
146 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
147 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
148 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
149 );
2a4d9487 150
151=cut
152
829517d4 153# Pre-pends our classname to the given relative classname or
154# class namespace, unless there is a '+' prefix, which will
155# be stripped.
156sub _expand_relative_name {
157 my ($class, $name) = @_;
158 return if !$name;
159 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
160 return $name;
2a4d9487 161}
162
f3405058 163# Finds all modules in the supplied namespace, or if omitted in the
164# namespace of $class. Untaints all findings as they can be assumed
165# to be safe
166sub _findallmod {
167 my $proto = shift;
168 my $ns = shift || ref $proto || $proto;
169
170 my @mods = Module::Find::findallmod($ns);
171
172 # try to untaint module names. mods where this fails
173 # are left alone so we don't have to change the old behavior
174 no locale; # localized \w doesn't untaint expression
175 return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
176}
177
829517d4 178# returns a hash of $shortname => $fullname for every package
b488020e 179# found in the given namespaces ($shortname is with the $fullname's
180# namespace stripped off)
829517d4 181sub _map_namespaces {
182 my ($class, @namespaces) = @_;
6eec9003 183
829517d4 184 my @results_hash;
185 foreach my $namespace (@namespaces) {
186 push(
187 @results_hash,
188 map { (substr($_, length "${namespace}::"), $_) }
f3405058 189 $class->_findallmod($namespace)
829517d4 190 );
0dc79249 191 }
27f01d1f 192
829517d4 193 @results_hash;
ea20d0fd 194}
195
b488020e 196# returns the result_source_instance for the passed class/object,
197# or dies with an informative message (used by load_namespaces)
198sub _ns_get_rsrc_instance {
199 my $class = shift;
200 my $rs = ref ($_[0]) || $_[0];
201
202 if ($rs->can ('result_source_instance') ) {
0647e0cc 203 return $rs->result_source_instance;
b488020e 204 }
205 else {
206 $class->throw_exception (
207 "Attempt to load_namespaces() class $rs failed - are you sure this is a real Result Class?"
208 );
209 }
210}
211
829517d4 212sub load_namespaces {
213 my ($class, %args) = @_;
0dc79249 214
829517d4 215 my $result_namespace = delete $args{result_namespace} || 'Result';
216 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
217 my $default_resultset_class = delete $args{default_resultset_class};
0dc79249 218
829517d4 219 $class->throw_exception('load_namespaces: unknown option(s): '
220 . join(q{,}, map { qq{'$_'} } keys %args))
221 if scalar keys %args;
0dc79249 222
829517d4 223 $default_resultset_class
224 = $class->_expand_relative_name($default_resultset_class);
9b1ba0f2 225
829517d4 226 for my $arg ($result_namespace, $resultset_namespace) {
227 $arg = [ $arg ] if !ref($arg) && $arg;
9b1ba0f2 228
829517d4 229 $class->throw_exception('load_namespaces: namespace arguments must be '
230 . 'a simple string or an arrayref')
231 if ref($arg) ne 'ARRAY';
9b1ba0f2 232
829517d4 233 $_ = $class->_expand_relative_name($_) for (@$arg);
234 }
ea20d0fd 235
829517d4 236 my %results = $class->_map_namespaces(@$result_namespace);
237 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
27f01d1f 238
829517d4 239 my @to_register;
240 {
241 no warnings 'redefine';
242 local *Class::C3::reinitialize = sub { };
243 use warnings 'redefine';
27f01d1f 244
3988ce40 245 # ensure classes are loaded and attached in inheritance order
3d27f771 246 $class->ensure_class_loaded($_) foreach(values %results);
3988ce40 247 my %inh_idx;
248 my @subclass_last = sort {
249
250 ($inh_idx{$a} ||=
251 scalar @{mro::get_linear_isa( $results{$a} )}
252 )
253
254 <=>
255
256 ($inh_idx{$b} ||=
257 scalar @{mro::get_linear_isa( $results{$b} )}
258 )
259
260 } keys(%results);
261
3d27f771 262 foreach my $result (@subclass_last) {
829517d4 263 my $result_class = $results{$result};
82b01c38 264
829517d4 265 my $rs_class = delete $resultsets{$result};
b488020e 266 my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
3988ce40 267
829517d4 268 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
3d27f771 269 if($rs_class && $rs_class ne $rs_set) {
341d5ede 270 carp "We found ResultSet class '$rs_class' for '$result', but it seems "
829517d4 271 . "that you had already set '$result' to use '$rs_set' instead";
272 }
273 }
274 elsif($rs_class ||= $default_resultset_class) {
275 $class->ensure_class_loaded($rs_class);
1d3108a4 276 if(!$rs_class->isa("DBIx::Class::ResultSet")) {
277 carp "load_namespaces found ResultSet class $rs_class that does not subclass DBIx::Class::ResultSet";
278 }
279
b488020e 280 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($rs_class);
829517d4 281 }
82b01c38 282
b488020e 283 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $result;
0e6c5d58 284
285 push(@to_register, [ $source_name, $result_class ]);
829517d4 286 }
287 }
ea20d0fd 288
829517d4 289 foreach (sort keys %resultsets) {
341d5ede 290 carp "load_namespaces found ResultSet class $_ with no "
829517d4 291 . 'corresponding Result class';
292 }
ea20d0fd 293
829517d4 294 Class::C3->reinitialize;
295 $class->register_class(@$_) for (@to_register);
ea20d0fd 296
829517d4 297 return;
ea20d0fd 298}
299
87c4e602 300=head2 load_classes
301
27f01d1f 302=over 4
303
304=item Arguments: @classes?, { $namespace => [ @classes ] }+
305
306=back
076652e8 307
1ab61457 308L</load_classes> is an alternative method to L</load_namespaces>, both of
309which serve similar purposes, each with different advantages and disadvantages.
310In the general case you should use L</load_namespaces>, unless you need to
311be able to specify that only specific classes are loaded at runtime.
829517d4 312
82b01c38 313With no arguments, this method uses L<Module::Find> to find all classes under
314the schema's namespace. Otherwise, this method loads the classes you specify
315(using L<use>), and registers them (using L</"register_class">).
076652e8 316
2053ab2a 317It is possible to comment out classes with a leading C<#>, but note that perl
318will think it's a mistake (trying to use a comment in a qw list), so you'll
319need to add C<no warnings 'qw';> before your load_classes call.
5ce32fc1 320
829517d4 321If any classes found do not appear to be Result class files, you will
322get the following warning:
323
fd323bf1 324 Failed to load $comp_class. Can't find source_name method. Is
829517d4 325 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
326 or make your load_classes call more specific.
327
2053ab2a 328Example:
82b01c38 329
330 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
75d07914 331 # etc. (anything under the My::Schema namespace)
82b01c38 332
333 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
334 # not Other::Namespace::LinerNotes nor My::Schema::Track
335 My::Schema->load_classes(qw/ CD Artist #Track /, {
336 Other::Namespace => [qw/ Producer #LinerNotes /],
337 });
338
076652e8 339=cut
340
a02675cd 341sub load_classes {
5ce32fc1 342 my ($class, @params) = @_;
bab77431 343
5ce32fc1 344 my %comps_for;
bab77431 345
5ce32fc1 346 if (@params) {
347 foreach my $param (@params) {
348 if (ref $param eq 'ARRAY') {
349 # filter out commented entries
350 my @modules = grep { $_ !~ /^#/ } @$param;
bab77431 351
5ce32fc1 352 push (@{$comps_for{$class}}, @modules);
353 }
354 elsif (ref $param eq 'HASH') {
355 # more than one namespace possible
356 for my $comp ( keys %$param ) {
357 # filter out commented entries
358 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
359
360 push (@{$comps_for{$comp}}, @modules);
361 }
362 }
363 else {
364 # filter out commented entries
365 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
366 }
367 }
368 } else {
bc0c9800 369 my @comp = map { substr $_, length "${class}::" }
f3405058 370 $class->_findallmod;
5ce32fc1 371 $comps_for{$class} = \@comp;
41a6f8c0 372 }
5ce32fc1 373
e6efde04 374 my @to_register;
375 {
376 no warnings qw/redefine/;
377 local *Class::C3::reinitialize = sub { };
378 foreach my $prefix (keys %comps_for) {
379 foreach my $comp (@{$comps_for{$prefix}||[]}) {
380 my $comp_class = "${prefix}::${comp}";
c037c03a 381 $class->ensure_class_loaded($comp_class);
bab77431 382
89271e56 383 my $snsub = $comp_class->can('source_name');
384 if(! $snsub ) {
341d5ede 385 carp "Failed to load $comp_class. Can't find source_name method. Is $comp_class really a full DBIC result class? Fix it, move it elsewhere, or make your load_classes call more specific.";
89271e56 386 next;
387 }
388 $comp = $snsub->($comp_class) || $comp;
389
93405cf0 390 push(@to_register, [ $comp, $comp_class ]);
bfb2bd4f 391 }
5ce32fc1 392 }
a02675cd 393 }
e6efde04 394 Class::C3->reinitialize;
395
396 foreach my $to (@to_register) {
397 $class->register_class(@$to);
398 # if $class->can('result_source_instance');
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
408=item Return value: $storage_type|{$storage_type, \%args}
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
829517d4 428=head2 exception_action
f017c022 429
829517d4 430=over 4
0f4ec1d2 431
829517d4 432=item Arguments: $code_reference
f017c022 433
829517d4 434=item Return value: $code_reference
85bd0538 435
829517d4 436=item Default value: None
2374c5ff 437
829517d4 438=back
f017c022 439
829517d4 440If C<exception_action> is set for this class/object, L</throw_exception>
441will prefer to call this code reference with the exception as an argument,
442rather than L<DBIx::Class::Exception/throw>.
f017c022 443
829517d4 444Your subroutine should probably just wrap the error in the exception
445object/class of your choosing and rethrow. If, against all sage advice,
446you'd like your C<exception_action> to suppress a particular exception
447completely, simply have it return true.
f017c022 448
829517d4 449Example:
f017c022 450
829517d4 451 package My::Schema;
452 use base qw/DBIx::Class::Schema/;
453 use My::ExceptionClass;
454 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
455 __PACKAGE__->load_classes;
2374c5ff 456
829517d4 457 # or:
458 my $schema_obj = My::Schema->connect( .... );
459 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
0f4ec1d2 460
829517d4 461 # suppress all exceptions, like a moron:
462 $schema_obj->exception_action(sub { 1 });
25fb14bd 463
829517d4 464=head2 stacktrace
f017c022 465
829517d4 466=over 4
2374c5ff 467
829517d4 468=item Arguments: boolean
2374c5ff 469
829517d4 470=back
2374c5ff 471
829517d4 472Whether L</throw_exception> should include stack trace information.
473Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
474is true.
0f4ec1d2 475
829517d4 476=head2 sqlt_deploy_hook
0f4ec1d2 477
829517d4 478=over
0f4ec1d2 479
829517d4 480=item Arguments: $sqlt_schema
2374c5ff 481
829517d4 482=back
2374c5ff 483
fd323bf1 484An optional sub which you can declare in your own Schema class that will get
829517d4 485passed the L<SQL::Translator::Schema> object when you deploy the schema via
486L</create_ddl_dir> or L</deploy>.
0f4ec1d2 487
fd323bf1 488For an example of what you can do with this, see
829517d4 489L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
fdcd8145 490
2d7d8459 491Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
492is called before L</deploy>. Therefore the hook can be used only to manipulate
493the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
494database. If you want to execute post-deploy statements which can not be generated
495by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
496and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
497
829517d4 498=head1 METHODS
2374c5ff 499
829517d4 500=head2 connect
87c4e602 501
27f01d1f 502=over 4
503
829517d4 504=item Arguments: @connectinfo
429bd4f1 505
d601dc88 506=item Return Value: $new_schema
27f01d1f 507
508=back
076652e8 509
829517d4 510Creates and returns a new Schema object. The connection info set on it
511is used to create a new instance of the storage backend and set it on
512the Schema object.
1c133e22 513
829517d4 514See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
5d52945a 515syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
829517d4 516general.
1c133e22 517
5d52945a 518Note that C<connect_info> expects an arrayref of arguments, but
faaba25f 519C<connect> does not. C<connect> wraps its arguments in an arrayref
5d52945a 520before passing them to C<connect_info>.
521
4c7d99ca 522=head3 Overloading
523
524C<connect> is a convenience method. It is equivalent to calling
525$schema->clone->connection(@connectinfo). To write your own overloaded
526version, overload L</connection> instead.
527
076652e8 528=cut
529
829517d4 530sub connect { shift->clone->connection(@_) }
e678398e 531
829517d4 532=head2 resultset
77254782 533
27f01d1f 534=over 4
535
829517d4 536=item Arguments: $source_name
82b01c38 537
829517d4 538=item Return Value: $resultset
27f01d1f 539
540=back
13765dad 541
829517d4 542 my $rs = $schema->resultset('DVD');
82b01c38 543
829517d4 544Returns the L<DBIx::Class::ResultSet> object for the registered source
545name.
77254782 546
547=cut
548
829517d4 549sub resultset {
550 my ($self, $moniker) = @_;
73d47f9f 551 $self->throw_exception('resultset() expects a source name')
552 unless defined $moniker;
829517d4 553 return $self->source($moniker)->resultset;
b7951443 554}
555
829517d4 556=head2 sources
6b43ba5f 557
558=over 4
559
829517d4 560=item Return Value: @source_names
6b43ba5f 561
562=back
563
829517d4 564 my @source_names = $schema->sources;
6b43ba5f 565
829517d4 566Lists names of all the sources registered on this Schema object.
6b43ba5f 567
829517d4 568=cut
161fb223 569
829517d4 570sub sources { return keys %{shift->source_registrations}; }
106d5f3b 571
829517d4 572=head2 source
87c4e602 573
27f01d1f 574=over 4
575
829517d4 576=item Arguments: $source_name
66d9ef6b 577
829517d4 578=item Return Value: $result_source
27f01d1f 579
580=back
82b01c38 581
829517d4 582 my $source = $schema->source('Book');
85f78622 583
829517d4 584Returns the L<DBIx::Class::ResultSource> object for the registered
585source name.
66d9ef6b 586
587=cut
588
829517d4 589sub source {
590 my ($self, $moniker) = @_;
591 my $sreg = $self->source_registrations;
592 return $sreg->{$moniker} if exists $sreg->{$moniker};
593
594 # if we got here, they probably passed a full class name
595 my $mapped = $self->class_mappings->{$moniker};
596 $self->throw_exception("Can't find source for ${moniker}")
597 unless $mapped && exists $sreg->{$mapped};
598 return $sreg->{$mapped};
161fb223 599}
600
829517d4 601=head2 class
87c4e602 602
27f01d1f 603=over 4
604
829517d4 605=item Arguments: $source_name
66d9ef6b 606
829517d4 607=item Return Value: $classname
27f01d1f 608
609=back
82b01c38 610
829517d4 611 my $class = $schema->class('CD');
612
613Retrieves the Result class name for the given source name.
66d9ef6b 614
615=cut
616
829517d4 617sub class {
618 my ($self, $moniker) = @_;
619 return $self->source($moniker)->result_class;
620}
08b515f1 621
4012acd8 622=head2 txn_do
08b515f1 623
4012acd8 624=over 4
08b515f1 625
4012acd8 626=item Arguments: C<$coderef>, @coderef_args?
08b515f1 627
4012acd8 628=item Return Value: The return value of $coderef
08b515f1 629
4012acd8 630=back
08b515f1 631
4012acd8 632Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
633returning its result (if any). Equivalent to calling $schema->storage->txn_do.
634See L<DBIx::Class::Storage/"txn_do"> for more information.
08b515f1 635
4012acd8 636This interface is preferred over using the individual methods L</txn_begin>,
637L</txn_commit>, and L</txn_rollback> below.
08b515f1 638
f9f06ae0 639WARNING: If you are connected with C<< AutoCommit => 0 >> the transaction is
281719d2 640considered nested, and you will still need to call L</txn_commit> to write your
f9f06ae0 641changes when appropriate. You will also want to connect with C<< auto_savepoint =>
6421 >> to get partial rollback to work, if the storage driver for your database
281719d2 643supports it.
644
f9f06ae0 645Connecting with C<< AutoCommit => 1 >> is recommended.
281719d2 646
4012acd8 647=cut
08b515f1 648
4012acd8 649sub txn_do {
650 my $self = shift;
08b515f1 651
4012acd8 652 $self->storage or $self->throw_exception
653 ('txn_do called on $schema without storage');
08b515f1 654
4012acd8 655 $self->storage->txn_do(@_);
656}
66d9ef6b 657
6936e902 658=head2 txn_scope_guard
75c8a7ab 659
fd323bf1 660Runs C<txn_scope_guard> on the schema's storage. See
89028f42 661L<DBIx::Class::Storage/txn_scope_guard>.
75c8a7ab 662
b85be4c1 663=cut
664
1bc193ac 665sub txn_scope_guard {
666 my $self = shift;
667
668 $self->storage or $self->throw_exception
669 ('txn_scope_guard called on $schema without storage');
670
671 $self->storage->txn_scope_guard(@_);
672}
673
4012acd8 674=head2 txn_begin
a62cf8d4 675
4012acd8 676Begins a transaction (does nothing if AutoCommit is off). Equivalent to
677calling $schema->storage->txn_begin. See
8bfce9d5 678L<DBIx::Class::Storage/"txn_begin"> for more information.
27f01d1f 679
4012acd8 680=cut
82b01c38 681
4012acd8 682sub txn_begin {
683 my $self = shift;
27f01d1f 684
4012acd8 685 $self->storage or $self->throw_exception
686 ('txn_begin called on $schema without storage');
a62cf8d4 687
4012acd8 688 $self->storage->txn_begin;
689}
a62cf8d4 690
4012acd8 691=head2 txn_commit
a62cf8d4 692
4012acd8 693Commits the current transaction. Equivalent to calling
8bfce9d5 694$schema->storage->txn_commit. See L<DBIx::Class::Storage/"txn_commit">
4012acd8 695for more information.
a62cf8d4 696
4012acd8 697=cut
a62cf8d4 698
4012acd8 699sub txn_commit {
700 my $self = shift;
a62cf8d4 701
4012acd8 702 $self->storage or $self->throw_exception
703 ('txn_commit called on $schema without storage');
a62cf8d4 704
4012acd8 705 $self->storage->txn_commit;
706}
70634260 707
4012acd8 708=head2 txn_rollback
a62cf8d4 709
4012acd8 710Rolls back the current transaction. Equivalent to calling
711$schema->storage->txn_rollback. See
8bfce9d5 712L<DBIx::Class::Storage/"txn_rollback"> for more information.
a62cf8d4 713
714=cut
715
4012acd8 716sub txn_rollback {
717 my $self = shift;
a62cf8d4 718
19630353 719 $self->storage or $self->throw_exception
4012acd8 720 ('txn_rollback called on $schema without storage');
a62cf8d4 721
4012acd8 722 $self->storage->txn_rollback;
a62cf8d4 723}
724
829517d4 725=head2 storage
66d9ef6b 726
829517d4 727 my $storage = $schema->storage;
04786a4c 728
829517d4 729Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
730if you want to turn on SQL statement debugging at runtime, or set the
731quote character. For the default storage, the documentation can be
732found in L<DBIx::Class::Storage::DBI>.
66d9ef6b 733
87c4e602 734=head2 populate
735
27f01d1f 736=over 4
737
16c5f7d3 738=item Arguments: $source_name, \@data;
27f01d1f 739
829517d4 740=item Return value: \@$objects | nothing
741
27f01d1f 742=back
a37a4697 743
16c5f7d3 744Pass this method a resultsource name, and an arrayref of
745arrayrefs. The arrayrefs should contain a list of column names,
fd323bf1 746followed by one or many sets of matching data for the given columns.
16c5f7d3 747
744076d8 748In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
749to insert the data, as this is a fast method. However, insert_bulk currently
750assumes that your datasets all contain the same type of values, using scalar
751references in a column in one row, and not in another will probably not work.
752
753Otherwise, each set of data is inserted into the database using
16c5f7d3 754L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
755objects is returned.
82b01c38 756
48580715 757e.g.
a37a4697 758
24d67825 759 $schema->populate('Artist', [
760 [ qw/artistid name/ ],
761 [ 1, 'Popular Band' ],
762 [ 2, 'Indie Band' ],
a62cf8d4 763 ...
764 ]);
d4daee7b 765
fd323bf1 766Since wantarray context is basically the same as looping over $rs->create(...)
5a93e138 767you won't see any performance benefits and in this case the method is more for
768convenience. Void context sends the column information directly to storage
fd323bf1 769using <DBI>s bulk insert method. So the performance will be much better for
5a93e138 770storages that support this method.
771
fd323bf1 772Because of this difference in the way void context inserts rows into your
5a93e138 773database you need to note how this will effect any loaded components that
fd323bf1 774override or augment insert. For example if you are using a component such
775as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
5a93e138 776wantarray context if you want the PKs automatically created.
a37a4697 777
778=cut
779
780sub populate {
781 my ($self, $name, $data) = @_;
c4e67d31 782 if(my $rs = $self->resultset($name)) {
783 if(defined wantarray) {
784 return $rs->populate($data);
785 } else {
786 $rs->populate($data);
54e0bd06 787 }
c4e67d31 788 } else {
fd323bf1 789 $self->throw_exception("$name is not a resultset");
8b93a938 790 }
a37a4697 791}
792
829517d4 793=head2 connection
794
795=over 4
796
797=item Arguments: @args
798
799=item Return Value: $new_schema
800
801=back
802
803Similar to L</connect> except sets the storage object and connection
804data in-place on the Schema class. You should probably be calling
805L</connect> to get a proper Schema object instead.
806
4c7d99ca 807=head3 Overloading
808
809Overload C<connection> to change the behaviour of C<connect>.
829517d4 810
811=cut
812
813sub connection {
814 my ($self, @info) = @_;
815 return $self if !@info && $self->storage;
d4daee7b 816
fd323bf1 817 my ($storage_class, $args) = ref $self->storage_type ?
829517d4 818 ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
d4daee7b 819
829517d4 820 $storage_class = 'DBIx::Class::Storage'.$storage_class
821 if $storage_class =~ m/^::/;
9780718f 822 try {
823 $self->ensure_class_loaded ($storage_class);
824 }
825 catch {
826 $self->throw_exception(
827 "No arguments to load_classes and couldn't load ${storage_class} ($_)"
828 );
829 };
829517d4 830 my $storage = $storage_class->new($self=>$args);
831 $storage->connect_info(\@info);
832 $self->storage($storage);
833 return $self;
834}
835
836sub _normalize_storage_type {
837 my ($self, $storage_type) = @_;
838 if(ref $storage_type eq 'ARRAY') {
839 return @$storage_type;
840 } elsif(ref $storage_type eq 'HASH') {
841 return %$storage_type;
842 } else {
843 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
844 }
845}
846
847=head2 compose_namespace
82cc0386 848
849=over 4
850
829517d4 851=item Arguments: $target_namespace, $additional_base_class?
852
853=item Retur Value: $new_schema
854
855=back
856
857For each L<DBIx::Class::ResultSource> in the schema, this method creates a
858class in the target namespace (e.g. $target_namespace::CD,
859$target_namespace::Artist) that inherits from the corresponding classes
860attached to the current schema.
861
862It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
863new $schema object. If C<$additional_base_class> is given, the new composed
48580715 864classes will inherit from first the corresponding class from the current
829517d4 865schema then the base class.
866
867For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
868
869 $schema->compose_namespace('My::DB', 'Base::Class');
870 print join (', ', @My::DB::CD::ISA) . "\n";
871 print join (', ', @My::DB::Artist::ISA) ."\n";
872
873will produce the output
874
875 My::Schema::CD, Base::Class
876 My::Schema::Artist, Base::Class
877
878=cut
879
880# this might be oversimplified
881# sub compose_namespace {
882# my ($self, $target, $base) = @_;
883
884# my $schema = $self->clone;
885# foreach my $moniker ($schema->sources) {
886# my $source = $schema->source($moniker);
887# my $target_class = "${target}::${moniker}";
888# $self->inject_base(
889# $target_class => $source->result_class, ($base ? $base : ())
890# );
891# $source->result_class($target_class);
892# $target_class->result_source_instance($source)
893# if $target_class->can('result_source_instance');
894# $schema->register_source($moniker, $source);
895# }
896# return $schema;
897# }
898
899sub compose_namespace {
900 my ($self, $target, $base) = @_;
901 my $schema = $self->clone;
902 {
903 no warnings qw/redefine/;
904# local *Class::C3::reinitialize = sub { };
905 foreach my $moniker ($schema->sources) {
906 my $source = $schema->source($moniker);
907 my $target_class = "${target}::${moniker}";
908 $self->inject_base(
909 $target_class => $source->result_class, ($base ? $base : ())
910 );
911 $source->result_class($target_class);
912 $target_class->result_source_instance($source)
913 if $target_class->can('result_source_instance');
914 $schema->register_source($moniker, $source);
915 }
916 }
917# Class::C3->reinitialize();
918 {
919 no strict 'refs';
920 no warnings 'redefine';
921 foreach my $meth (qw/class source resultset/) {
8637bb24 922 *{"${target}::${meth}"} = Sub::Name::subname "${target}::${meth}" =>
829517d4 923 sub { shift->schema->$meth(@_) };
924 }
925 }
926 return $schema;
927}
928
929sub setup_connection_class {
930 my ($class, $target, @info) = @_;
931 $class->inject_base($target => 'DBIx::Class::DB');
932 #$target->load_components('DB');
933 $target->connection(@info);
934}
935
936=head2 svp_begin
937
fd323bf1 938Creates a new savepoint (does nothing outside a transaction).
829517d4 939Equivalent to calling $schema->storage->svp_begin. See
8bfce9d5 940L<DBIx::Class::Storage/"svp_begin"> for more information.
829517d4 941
942=cut
943
944sub svp_begin {
945 my ($self, $name) = @_;
946
947 $self->storage or $self->throw_exception
948 ('svp_begin called on $schema without storage');
949
950 $self->storage->svp_begin($name);
951}
952
953=head2 svp_release
954
fd323bf1 955Releases a savepoint (does nothing outside a transaction).
829517d4 956Equivalent to calling $schema->storage->svp_release. See
8bfce9d5 957L<DBIx::Class::Storage/"svp_release"> for more information.
829517d4 958
959=cut
960
961sub svp_release {
962 my ($self, $name) = @_;
963
964 $self->storage or $self->throw_exception
965 ('svp_release called on $schema without storage');
82cc0386 966
829517d4 967 $self->storage->svp_release($name);
968}
82cc0386 969
829517d4 970=head2 svp_rollback
db5dc233 971
fd323bf1 972Rollback to a savepoint (does nothing outside a transaction).
829517d4 973Equivalent to calling $schema->storage->svp_rollback. See
8bfce9d5 974L<DBIx::Class::Storage/"svp_rollback"> for more information.
82cc0386 975
829517d4 976=cut
82cc0386 977
829517d4 978sub svp_rollback {
979 my ($self, $name) = @_;
82cc0386 980
829517d4 981 $self->storage or $self->throw_exception
982 ('svp_rollback called on $schema without storage');
82cc0386 983
829517d4 984 $self->storage->svp_rollback($name);
985}
db5dc233 986
829517d4 987=head2 clone
613397e7 988
84c5863b 989=over 4
613397e7 990
829517d4 991=item Return Value: $new_schema
613397e7 992
993=back
994
829517d4 995Clones the schema and its associated result_source objects and returns the
996copy.
997
998=cut
999
1000sub clone {
1001 my ($self) = @_;
1002 my $clone = { (ref $self ? %$self : ()) };
1003 bless $clone, (ref $self || $self);
1004
1005 $clone->class_mappings({ %{$clone->class_mappings} });
1006 $clone->source_registrations({ %{$clone->source_registrations} });
1007 foreach my $moniker ($self->sources) {
1008 my $source = $self->source($moniker);
1009 my $new = $source->new($source);
1010 # we use extra here as we want to leave the class_mappings as they are
1011 # but overwrite the source_registrations entry with the new source
1012 $clone->register_extra_source($moniker => $new);
1013 }
1014 $clone->storage->set_schema($clone) if $clone->storage;
1015 return $clone;
1016}
613397e7 1017
5160b401 1018=head2 throw_exception
701da8c4 1019
75d07914 1020=over 4
82b01c38 1021
ebc77b53 1022=item Arguments: $message
82b01c38 1023
1024=back
1025
1026Throws an exception. Defaults to using L<Carp::Clan> to report errors from
db5dc233 1027user's perspective. See L</exception_action> for details on overriding
4b946902 1028this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1029default behavior will provide a detailed stack trace.
701da8c4 1030
1031=cut
1032
1033sub throw_exception {
82cc0386 1034 my $self = shift;
4981dc70 1035
1036 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
1037 if !$self->exception_action || !$self->exception_action->(@_);
701da8c4 1038}
1039
dfccde48 1040=head2 deploy
1c339d71 1041
82b01c38 1042=over 4
1043
10976519 1044=item Arguments: \%sqlt_args, $dir
82b01c38 1045
1046=back
1047
1048Attempts to deploy the schema to the current storage using L<SQL::Translator>.
ec6704d4 1049
10976519 1050See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1051The most common value for this would be C<< { add_drop_table => 1 } >>
1052to have the SQL produced include a C<DROP TABLE> statement for each table
1053created. For quoting purposes supply C<quote_table_names> and
3e82fc27 1054C<quote_field_names>.
51bace1c 1055
fd323bf1 1056Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1057ref or an array ref, containing a list of source to deploy. If present, then
0e2c6809 1058only the sources listed will get deployed. Furthermore, you can use the
1059C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1060FK.
499adf63 1061
1c339d71 1062=cut
1063
1064sub deploy {
6e73ac25 1065 my ($self, $sqltargs, $dir) = @_;
1c339d71 1066 $self->throw_exception("Can't deploy without storage") unless $self->storage;
6e73ac25 1067 $self->storage->deploy($self, undef, $sqltargs, $dir);
1c339d71 1068}
1069
0e0ce6c1 1070=head2 deployment_statements
1071
1072=over 4
1073
10976519 1074=item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
0e0ce6c1 1075
829517d4 1076=item Return value: $listofstatements
1077
0e0ce6c1 1078=back
1079
10976519 1080A convenient shortcut to
1081C<< $self->storage->deployment_statements($self, @args) >>.
1082Returns the SQL statements used by L</deploy> and
1083L<DBIx::Class::Schema::Storage/deploy>.
0e0ce6c1 1084
1085=cut
1086
1087sub deployment_statements {
7ad93f5a 1088 my $self = shift;
0e0ce6c1 1089
1090 $self->throw_exception("Can't generate deployment statements without a storage")
1091 if not $self->storage;
1092
7ad93f5a 1093 $self->storage->deployment_statements($self, @_);
0e0ce6c1 1094}
1095
6dfbe2f8 1096=head2 create_ddl_dir
c0f61310 1097
1098=over 4
1099
10976519 1100=item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
c0f61310 1101
1102=back
1103
fd323bf1 1104A convenient shortcut to
10976519 1105C<< $self->storage->create_ddl_dir($self, @args) >>.
c9d2e0a2 1106
10976519 1107Creates an SQL file based on the Schema, for each of the specified
1108database types, in the given directory.
c9d2e0a2 1109
c0f61310 1110=cut
1111
6e73ac25 1112sub create_ddl_dir {
e673f011 1113 my $self = shift;
1114
1115 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1116 $self->storage->create_ddl_dir($self, @_);
1117}
1118
e63a82f7 1119=head2 ddl_filename
9b83fccd 1120
c9d2e0a2 1121=over 4
1122
99a74c4a 1123=item Arguments: $database-type, $version, $directory, $preversion
c9d2e0a2 1124
829517d4 1125=item Return value: $normalised_filename
1126
c9d2e0a2 1127=back
1128
99a74c4a 1129 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
c9d2e0a2 1130
1131This method is called by C<create_ddl_dir> to compose a file name out of
1132the supplied directory, database type and version number. The default file
1133name format is: C<$dir$schema-$version-$type.sql>.
9b83fccd 1134
c9d2e0a2 1135You may override this method in your schema if you wish to use a different
1136format.
9b83fccd 1137
1acfef8e 1138 WARNING
1139
1140 Prior to DBIx::Class version 0.08100 this method had a different signature:
1141
1142 my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1143
1144 In recent versions variables $dir and $version were reversed in order to
fd323bf1 1145 bring the signature in line with other Schema/Storage methods. If you
1acfef8e 1146 really need to maintain backward compatibility, you can do the following
1147 in any overriding methods:
1148
1149 ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1150
9b83fccd 1151=cut
1152
6e73ac25 1153sub ddl_filename {
99a74c4a 1154 my ($self, $type, $version, $dir, $preversion) = @_;
e673f011 1155
99a74c4a 1156 my $filename = ref($self);
1157 $filename =~ s/::/-/g;
1158 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1159 $filename =~ s/$version/$preversion-$version/ if($preversion);
d4daee7b 1160
99a74c4a 1161 return $filename;
e673f011 1162}
1163
4146e3da 1164=head2 thaw
1165
fd323bf1 1166Provided as the recommended way of thawing schema objects. You can call
4146e3da 1167C<Storable::thaw> directly if you wish, but the thawed objects will not have a
48580715 1168reference to any schema, so are rather useless.
4146e3da 1169
1170=cut
1171
1172sub thaw {
1173 my ($self, $obj) = @_;
1174 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1175 return Storable::thaw($obj);
1176}
1177
1178=head2 freeze
1179
48580715 1180This doesn't actually do anything more than call L<Storable/freeze>, it is just
1181provided here for symmetry.
4146e3da 1182
d2f3e87b 1183=cut
1184
4146e3da 1185sub freeze {
1186 return Storable::freeze($_[1]);
1187}
1188
1189=head2 dclone
1190
1477a478 1191=over 4
1192
1193=item Arguments: $object
1194
1195=item Return Value: dcloned $object
1196
1197=back
1198
9e9ecfda 1199Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1200objects so their references to the schema object
1201(which itself is B<not> cloned) are properly maintained.
4146e3da 1202
1203=cut
1204
1205sub dclone {
1206 my ($self, $obj) = @_;
1207 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1208 return Storable::dclone($obj);
1209}
1210
93e4d41a 1211=head2 schema_version
1212
829517d4 1213Returns the current schema class' $VERSION in a normalised way.
93e4d41a 1214
1215=cut
1216
1217sub schema_version {
1218 my ($self) = @_;
1219 my $class = ref($self)||$self;
1220
1221 # does -not- use $schema->VERSION
1222 # since that varies in results depending on if version.pm is installed, and if
1223 # so the perl or XS versions. If you want this to change, bug the version.pm
1224 # author to make vpp and vxs behave the same.
1225
1226 my $version;
1227 {
1228 no strict 'refs';
1229 $version = ${"${class}::VERSION"};
1230 }
1231 return $version;
1232}
1233
829517d4 1234
1235=head2 register_class
1236
1237=over 4
1238
1239=item Arguments: $moniker, $component_class
1240
1241=back
1242
fd323bf1 1243This 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 1244
1245You will only need this method if you have your Result classes in
1246files which are not named after the packages (or all in the same
1247file). You may also need it to register classes at runtime.
1248
1249Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1250calling:
1251
1252 $schema->register_source($moniker, $component_class->result_source_instance);
1253
1254=cut
1255
1256sub register_class {
1257 my ($self, $moniker, $to_register) = @_;
1e36ef62 1258 $self->register_source($moniker => $to_register->result_source_instance);
829517d4 1259}
1260
1261=head2 register_source
1262
1263=over 4
1264
1265=item Arguments: $moniker, $result_source
1266
1267=back
1268
1269This method is called by L</register_class>.
1270
1271Registers the L<DBIx::Class::ResultSource> in the schema with the given
1272moniker.
1273
1274=cut
1275
1276sub register_source {
1277 my $self = shift;
1278
1279 $self->_register_source(@_);
1280}
1281
98cabed3 1282=head2 unregister_source
1283
1284=over 4
1285
1286=item Arguments: $moniker
1287
1288=back
1289
1290Removes the L<DBIx::Class::ResultSource> from the schema for the given moniker.
1291
1292=cut
1293
1294sub unregister_source {
1295 my $self = shift;
1296
1297 $self->_unregister_source(@_);
1298}
1299
829517d4 1300=head2 register_extra_source
1301
1302=over 4
1303
1304=item Arguments: $moniker, $result_source
1305
1306=back
1307
fd323bf1 1308As L</register_source> but should be used if the result class already
829517d4 1309has a source and you want to register an extra one.
1310
1311=cut
1312
1313sub register_extra_source {
1314 my $self = shift;
1315
1316 $self->_register_source(@_, { extra => 1 });
1317}
1318
1319sub _register_source {
1320 my ($self, $moniker, $source, $params) = @_;
1321
6d4f9d94 1322 my $orig_source = $source;
2461ae19 1323
0e6c5d58 1324 $source = $source->new({ %$source, source_name => $moniker });
2461ae19 1325 $source->schema($self);
551e711a 1326 Scalar::Util::weaken($source->{schema}) if ref($self);
2461ae19 1327
1328 my $rs_class = $source->result_class;
829517d4 1329
1330 my %reg = %{$self->source_registrations};
1331 $reg{$moniker} = $source;
1332 $self->source_registrations(\%reg);
1333
829517d4 1334 return if ($params->{extra});
5dfe40b8 1335 return unless defined($rs_class) && $rs_class->can('result_source_instance');
829517d4 1336
2461ae19 1337 my %map = %{$self->class_mappings};
f18d2d04 1338 if (
1339 exists $map{$rs_class}
1340 and
1341 $map{$rs_class} ne $moniker
1342 and
1343 $rs_class->result_source_instance ne $orig_source
1344 ) {
2461ae19 1345 carp "$rs_class already has a source, use register_extra_source for additional sources";
829517d4 1346 }
2461ae19 1347 $map{$rs_class} = $moniker;
1348 $self->class_mappings(\%map);
829517d4 1349}
1350
1351sub _unregister_source {
1352 my ($self, $moniker) = @_;
fd323bf1 1353 my %reg = %{$self->source_registrations};
829517d4 1354
1355 my $source = delete $reg{$moniker};
1356 $self->source_registrations(\%reg);
1357 if ($source->result_class) {
1358 my %map = %{$self->class_mappings};
1359 delete $map{$source->result_class};
1360 $self->class_mappings(\%map);
1361 }
1362}
1363
1364
1365=head2 compose_connection (DEPRECATED)
1366
1367=over 4
1368
1369=item Arguments: $target_namespace, @db_info
1370
1371=item Return Value: $new_schema
1372
1373=back
1374
1375DEPRECATED. You probably wanted compose_namespace.
1376
1377Actually, you probably just wanted to call connect.
1378
1379=begin hidden
1380
1381(hidden due to deprecation)
1382
1383Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1384calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1385then injects the L<DBix::Class::ResultSetProxy> component and a
1386resultset_instance classdata entry on all the new classes, in order to support
1387$target_namespaces::$class->search(...) method calls.
1388
1389This is primarily useful when you have a specific need for class method access
1390to a connection. In normal usage it is preferred to call
1391L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1392on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1393more information.
1394
1395=end hidden
1396
1397=cut
1398
1399{
1400 my $warn;
1401
1402 sub compose_connection {
1403 my ($self, $target, @info) = @_;
1404
341d5ede 1405 carp "compose_connection deprecated as of 0.08000"
829517d4 1406 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1407
1408 my $base = 'DBIx::Class::ResultSetProxy';
9780718f 1409 try {
1410 eval "require ${base};"
1411 }
1412 catch {
1413 $self->throw_exception
1414 ("No arguments to load_classes and couldn't load ${base} ($_)")
1415 };
d4daee7b 1416
829517d4 1417 if ($self eq $target) {
1418 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1419 foreach my $moniker ($self->sources) {
1420 my $source = $self->source($moniker);
1421 my $class = $source->result_class;
1422 $self->inject_base($class, $base);
1423 $class->mk_classdata(resultset_instance => $source->resultset);
1424 $class->mk_classdata(class_resolver => $self);
1425 }
1426 $self->connection(@info);
1427 return $self;
1428 }
d4daee7b 1429
829517d4 1430 my $schema = $self->compose_namespace($target, $base);
1431 {
1432 no strict 'refs';
1433 my $name = join '::', $target, 'schema';
1434 *$name = Sub::Name::subname $name, sub { $schema };
1435 }
d4daee7b 1436
829517d4 1437 $schema->connection(@info);
1438 foreach my $moniker ($schema->sources) {
1439 my $source = $schema->source($moniker);
1440 my $class = $source->result_class;
1441 #warn "$moniker $class $source ".$source->storage;
1442 $class->mk_classdata(result_source_instance => $source);
1443 $class->mk_classdata(resultset_instance => $source->resultset);
1444 $class->mk_classdata(class_resolver => $schema);
1445 }
1446 return $schema;
1447 }
1448}
1449
a02675cd 14501;
c2da098a 1451
c2da098a 1452=head1 AUTHORS
1453
daec44b8 1454Matt S. Trout <mst@shadowcatsystems.co.uk>
c2da098a 1455
1456=head1 LICENSE
1457
1458You may distribute this code under the same terms as Perl itself.
1459
1460=cut