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