10% speed up on quoted statement generation
[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/;
551e711a 8use Scalar::Util ();
c9d2e0a2 9use File::Spec;
ddc0a6c8 10use Sub::Name ();
329d7385 11use Module::Find();
a02675cd 12
41a6f8c0 13use base qw/DBIx::Class/;
a02675cd 14
0dc79249 15__PACKAGE__->mk_classdata('class_mappings' => {});
16__PACKAGE__->mk_classdata('source_registrations' => {});
1e10a11d 17__PACKAGE__->mk_classdata('storage_type' => '::DBI');
d7156e50 18__PACKAGE__->mk_classdata('storage');
82cc0386 19__PACKAGE__->mk_classdata('exception_action');
4b946902 20__PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
e6c747fd 21__PACKAGE__->mk_classdata('default_resultset_attributes' => {});
a02675cd 22
c2da098a 23=head1 NAME
24
25DBIx::Class::Schema - composable schemas
26
27=head1 SYNOPSIS
28
24d67825 29 package Library::Schema;
c2da098a 30 use base qw/DBIx::Class::Schema/;
bab77431 31
829517d4 32 # load all Result classes in Library/Schema/Result/
33 __PACKAGE__->load_namespaces();
c2da098a 34
829517d4 35 package Library::Schema::Result::CD;
d88ecca6 36 use base qw/DBIx::Class::Core/;
37
38 __PACKAGE__->load_components(qw/InflateColumn::DateTime/); # for example
24d67825 39 __PACKAGE__->table('cd');
c2da098a 40
5d9076f2 41 # Elsewhere in your code:
24d67825 42 my $schema1 = Library::Schema->connect(
a3d93194 43 $dsn,
44 $user,
45 $password,
ef131d82 46 { AutoCommit => 1 },
a3d93194 47 );
bab77431 48
24d67825 49 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
c2da098a 50
829517d4 51 # fetch objects using Library::Schema::Result::DVD
24d67825 52 my $resultset = $schema1->resultset('DVD')->search( ... );
53 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
c2da098a 54
55=head1 DESCRIPTION
56
a3d93194 57Creates database classes based on a schema. This is the recommended way to
58use L<DBIx::Class> and allows you to use more than one concurrent connection
59with your classes.
429bd4f1 60
03312470 61NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
2053ab2a 62carefully, as DBIx::Class does things a little differently. Note in
03312470 63particular which module inherits off which.
64
829517d4 65=head1 SETUP METHODS
c2da098a 66
829517d4 67=head2 load_namespaces
87c4e602 68
27f01d1f 69=over 4
70
829517d4 71=item Arguments: %options?
27f01d1f 72
73=back
076652e8 74
829517d4 75 __PACKAGE__->load_namespaces();
66d9ef6b 76
829517d4 77 __PACKAGE__->load_namespaces(
78 result_namespace => 'Res',
79 resultset_namespace => 'RSet',
80 default_resultset_class => '+MyDB::Othernamespace::RSet',
81 );
076652e8 82
829517d4 83With no arguments, this method uses L<Module::Find> to load all your
84Result classes from a sub-namespace F<Result> under your Schema class'
48580715 85namespace, i.e. with a Schema of I<MyDB::Schema> all files in
829517d4 86I<MyDB::Schema::Result> are assumed to be Result classes.
c2da098a 87
829517d4 88It also finds all ResultSet classes in the namespace F<ResultSet> and
89loads them into the appropriate Result classes using for you. The
90matching is done by assuming the package name of the ResultSet class
91is the same as that of the Result class.
74b92d9a 92
672687db 93You will be warned if ResultSet classes are discovered for which there
829517d4 94are no matching Result classes like this:
87c4e602 95
829517d4 96 load_namespaces found ResultSet class $classname with no corresponding Result class
27f01d1f 97
829517d4 98If a Result class is found to already have a ResultSet class set using
99L</resultset_class> to some other class, you will be warned like this:
27f01d1f 100
829517d4 101 We found ResultSet class '$rs_class' for '$result', but it seems
102 that you had already set '$result' to use '$rs_set' instead
076652e8 103
829517d4 104Both of the sub-namespaces are configurable if you don't like the defaults,
105via the options C<result_namespace> and C<resultset_namespace>.
076652e8 106
829517d4 107If (and only if) you specify the option C<default_resultset_class>, any found
108Result classes for which we do not find a corresponding
109ResultSet class will have their C<resultset_class> set to
110C<default_resultset_class>.
076652e8 111
829517d4 112All of the namespace and classname options to this method are relative to
113the schema classname by default. To specify a fully-qualified name, prefix
114it with a literal C<+>.
2a4d9487 115
829517d4 116Examples:
2a4d9487 117
829517d4 118 # load My::Schema::Result::CD, My::Schema::Result::Artist,
119 # My::Schema::ResultSet::CD, etc...
120 My::Schema->load_namespaces;
2a4d9487 121
829517d4 122 # Override everything to use ugly names.
123 # In this example, if there is a My::Schema::Res::Foo, but no matching
124 # My::Schema::RSets::Foo, then Foo will have its
125 # resultset_class set to My::Schema::RSetBase
126 My::Schema->load_namespaces(
127 result_namespace => 'Res',
128 resultset_namespace => 'RSets',
129 default_resultset_class => 'RSetBase',
130 );
2a4d9487 131
829517d4 132 # Put things in other namespaces
133 My::Schema->load_namespaces(
134 result_namespace => '+Some::Place::Results',
135 resultset_namespace => '+Another::Place::RSets',
136 );
2a4d9487 137
829517d4 138If you'd like to use multiple namespaces of each type, simply use an arrayref
139of namespaces for that option. In the case that the same result
140(or resultset) class exists in multiple namespaces, the latter entries in
141your list of namespaces will override earlier ones.
2a4d9487 142
829517d4 143 My::Schema->load_namespaces(
144 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
145 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
146 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
147 );
2a4d9487 148
149=cut
150
829517d4 151# Pre-pends our classname to the given relative classname or
152# class namespace, unless there is a '+' prefix, which will
153# be stripped.
154sub _expand_relative_name {
155 my ($class, $name) = @_;
156 return if !$name;
157 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
158 return $name;
2a4d9487 159}
160
f3405058 161# Finds all modules in the supplied namespace, or if omitted in the
162# namespace of $class. Untaints all findings as they can be assumed
163# to be safe
164sub _findallmod {
165 my $proto = shift;
166 my $ns = shift || ref $proto || $proto;
167
168 my @mods = Module::Find::findallmod($ns);
169
170 # try to untaint module names. mods where this fails
171 # are left alone so we don't have to change the old behavior
172 no locale; # localized \w doesn't untaint expression
173 return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
174}
175
829517d4 176# returns a hash of $shortname => $fullname for every package
b488020e 177# found in the given namespaces ($shortname is with the $fullname's
178# namespace stripped off)
829517d4 179sub _map_namespaces {
180 my ($class, @namespaces) = @_;
6eec9003 181
829517d4 182 my @results_hash;
183 foreach my $namespace (@namespaces) {
184 push(
185 @results_hash,
186 map { (substr($_, length "${namespace}::"), $_) }
f3405058 187 $class->_findallmod($namespace)
829517d4 188 );
0dc79249 189 }
27f01d1f 190
829517d4 191 @results_hash;
ea20d0fd 192}
193
b488020e 194# returns the result_source_instance for the passed class/object,
195# or dies with an informative message (used by load_namespaces)
196sub _ns_get_rsrc_instance {
197 my $class = shift;
198 my $rs = ref ($_[0]) || $_[0];
199
200 if ($rs->can ('result_source_instance') ) {
762deea2 201 my $x = $rs->result_source_instance;
202 use Data::Dumper;
203 die Dumper $x;
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
324 Failed to load $comp_class. Can't find source_name method. Is
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
829517d4 484An optional sub which you can declare in your own Schema class that will get
485passed the L<SQL::Translator::Schema> object when you deploy the schema via
486L</create_ddl_dir> or L</deploy>.
0f4ec1d2 487
829517d4 488For an example of what you can do with this, see
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
89028f42 660Runs C<txn_scope_guard> on the schema's storage. See
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,
746followed by one or many sets of matching data for the given columns.
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
5a93e138 766Since wantarray context is basically the same as looping over $rs->create(...)
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
769using <DBI>s bulk insert method. So the performance will be much better for
770storages that support this method.
771
772Because of this difference in the way void context inserts rows into your
773database you need to note how this will effect any loaded components that
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
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 {
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
829517d4 817 my ($storage_class, $args) = ref $self->storage_type ?
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/^::/;
82202206 822 eval { $self->ensure_class_loaded ($storage_class) };
829517d4 823 $self->throw_exception(
824 "No arguments to load_classes and couldn't load ${storage_class} ($@)"
825 ) if $@;
826 my $storage = $storage_class->new($self=>$args);
827 $storage->connect_info(\@info);
828 $self->storage($storage);
829 return $self;
830}
831
832sub _normalize_storage_type {
833 my ($self, $storage_type) = @_;
834 if(ref $storage_type eq 'ARRAY') {
835 return @$storage_type;
836 } elsif(ref $storage_type eq 'HASH') {
837 return %$storage_type;
838 } else {
839 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
840 }
841}
842
843=head2 compose_namespace
82cc0386 844
845=over 4
846
829517d4 847=item Arguments: $target_namespace, $additional_base_class?
848
849=item Retur Value: $new_schema
850
851=back
852
853For each L<DBIx::Class::ResultSource> in the schema, this method creates a
854class in the target namespace (e.g. $target_namespace::CD,
855$target_namespace::Artist) that inherits from the corresponding classes
856attached to the current schema.
857
858It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
859new $schema object. If C<$additional_base_class> is given, the new composed
48580715 860classes will inherit from first the corresponding class from the current
829517d4 861schema then the base class.
862
863For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
864
865 $schema->compose_namespace('My::DB', 'Base::Class');
866 print join (', ', @My::DB::CD::ISA) . "\n";
867 print join (', ', @My::DB::Artist::ISA) ."\n";
868
869will produce the output
870
871 My::Schema::CD, Base::Class
872 My::Schema::Artist, Base::Class
873
874=cut
875
876# this might be oversimplified
877# sub compose_namespace {
878# my ($self, $target, $base) = @_;
879
880# my $schema = $self->clone;
881# foreach my $moniker ($schema->sources) {
882# my $source = $schema->source($moniker);
883# my $target_class = "${target}::${moniker}";
884# $self->inject_base(
885# $target_class => $source->result_class, ($base ? $base : ())
886# );
887# $source->result_class($target_class);
888# $target_class->result_source_instance($source)
889# if $target_class->can('result_source_instance');
890# $schema->register_source($moniker, $source);
891# }
892# return $schema;
893# }
894
895sub compose_namespace {
896 my ($self, $target, $base) = @_;
897 my $schema = $self->clone;
898 {
899 no warnings qw/redefine/;
900# local *Class::C3::reinitialize = sub { };
901 foreach my $moniker ($schema->sources) {
902 my $source = $schema->source($moniker);
903 my $target_class = "${target}::${moniker}";
904 $self->inject_base(
905 $target_class => $source->result_class, ($base ? $base : ())
906 );
907 $source->result_class($target_class);
908 $target_class->result_source_instance($source)
909 if $target_class->can('result_source_instance');
910 $schema->register_source($moniker, $source);
911 }
912 }
913# Class::C3->reinitialize();
914 {
915 no strict 'refs';
916 no warnings 'redefine';
917 foreach my $meth (qw/class source resultset/) {
8637bb24 918 *{"${target}::${meth}"} = Sub::Name::subname "${target}::${meth}" =>
829517d4 919 sub { shift->schema->$meth(@_) };
920 }
921 }
922 return $schema;
923}
924
925sub setup_connection_class {
926 my ($class, $target, @info) = @_;
927 $class->inject_base($target => 'DBIx::Class::DB');
928 #$target->load_components('DB');
929 $target->connection(@info);
930}
931
932=head2 svp_begin
933
934Creates a new savepoint (does nothing outside a transaction).
935Equivalent to calling $schema->storage->svp_begin. See
8bfce9d5 936L<DBIx::Class::Storage/"svp_begin"> for more information.
829517d4 937
938=cut
939
940sub svp_begin {
941 my ($self, $name) = @_;
942
943 $self->storage or $self->throw_exception
944 ('svp_begin called on $schema without storage');
945
946 $self->storage->svp_begin($name);
947}
948
949=head2 svp_release
950
951Releases a savepoint (does nothing outside a transaction).
952Equivalent to calling $schema->storage->svp_release. See
8bfce9d5 953L<DBIx::Class::Storage/"svp_release"> for more information.
829517d4 954
955=cut
956
957sub svp_release {
958 my ($self, $name) = @_;
959
960 $self->storage or $self->throw_exception
961 ('svp_release called on $schema without storage');
82cc0386 962
829517d4 963 $self->storage->svp_release($name);
964}
82cc0386 965
829517d4 966=head2 svp_rollback
db5dc233 967
829517d4 968Rollback to a savepoint (does nothing outside a transaction).
969Equivalent to calling $schema->storage->svp_rollback. See
8bfce9d5 970L<DBIx::Class::Storage/"svp_rollback"> for more information.
82cc0386 971
829517d4 972=cut
82cc0386 973
829517d4 974sub svp_rollback {
975 my ($self, $name) = @_;
82cc0386 976
829517d4 977 $self->storage or $self->throw_exception
978 ('svp_rollback called on $schema without storage');
82cc0386 979
829517d4 980 $self->storage->svp_rollback($name);
981}
db5dc233 982
829517d4 983=head2 clone
613397e7 984
84c5863b 985=over 4
613397e7 986
829517d4 987=item Return Value: $new_schema
613397e7 988
989=back
990
829517d4 991Clones the schema and its associated result_source objects and returns the
992copy.
993
994=cut
995
996sub clone {
997 my ($self) = @_;
998 my $clone = { (ref $self ? %$self : ()) };
999 bless $clone, (ref $self || $self);
1000
1001 $clone->class_mappings({ %{$clone->class_mappings} });
1002 $clone->source_registrations({ %{$clone->source_registrations} });
1003 foreach my $moniker ($self->sources) {
1004 my $source = $self->source($moniker);
1005 my $new = $source->new($source);
1006 # we use extra here as we want to leave the class_mappings as they are
1007 # but overwrite the source_registrations entry with the new source
1008 $clone->register_extra_source($moniker => $new);
1009 }
1010 $clone->storage->set_schema($clone) if $clone->storage;
1011 return $clone;
1012}
613397e7 1013
5160b401 1014=head2 throw_exception
701da8c4 1015
75d07914 1016=over 4
82b01c38 1017
ebc77b53 1018=item Arguments: $message
82b01c38 1019
1020=back
1021
1022Throws an exception. Defaults to using L<Carp::Clan> to report errors from
db5dc233 1023user's perspective. See L</exception_action> for details on overriding
4b946902 1024this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1025default behavior will provide a detailed stack trace.
701da8c4 1026
1027=cut
1028
1029sub throw_exception {
82cc0386 1030 my $self = shift;
4981dc70 1031
1032 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
1033 if !$self->exception_action || !$self->exception_action->(@_);
701da8c4 1034}
1035
dfccde48 1036=head2 deploy
1c339d71 1037
82b01c38 1038=over 4
1039
10976519 1040=item Arguments: \%sqlt_args, $dir
82b01c38 1041
1042=back
1043
1044Attempts to deploy the schema to the current storage using L<SQL::Translator>.
ec6704d4 1045
10976519 1046See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1047The most common value for this would be C<< { add_drop_table => 1 } >>
1048to have the SQL produced include a C<DROP TABLE> statement for each table
1049created. For quoting purposes supply C<quote_table_names> and
3e82fc27 1050C<quote_field_names>.
51bace1c 1051
499adf63 1052Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1053ref or an array ref, containing a list of source to deploy. If present, then
0e2c6809 1054only the sources listed will get deployed. Furthermore, you can use the
1055C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1056FK.
499adf63 1057
1c339d71 1058=cut
1059
1060sub deploy {
6e73ac25 1061 my ($self, $sqltargs, $dir) = @_;
1c339d71 1062 $self->throw_exception("Can't deploy without storage") unless $self->storage;
6e73ac25 1063 $self->storage->deploy($self, undef, $sqltargs, $dir);
1c339d71 1064}
1065
0e0ce6c1 1066=head2 deployment_statements
1067
1068=over 4
1069
10976519 1070=item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
0e0ce6c1 1071
829517d4 1072=item Return value: $listofstatements
1073
0e0ce6c1 1074=back
1075
10976519 1076A convenient shortcut to
1077C<< $self->storage->deployment_statements($self, @args) >>.
1078Returns the SQL statements used by L</deploy> and
1079L<DBIx::Class::Schema::Storage/deploy>.
0e0ce6c1 1080
1081=cut
1082
1083sub deployment_statements {
7ad93f5a 1084 my $self = shift;
0e0ce6c1 1085
1086 $self->throw_exception("Can't generate deployment statements without a storage")
1087 if not $self->storage;
1088
7ad93f5a 1089 $self->storage->deployment_statements($self, @_);
0e0ce6c1 1090}
1091
6dfbe2f8 1092=head2 create_ddl_dir
c0f61310 1093
1094=over 4
1095
10976519 1096=item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
c0f61310 1097
1098=back
1099
10976519 1100A convenient shortcut to
1101C<< $self->storage->create_ddl_dir($self, @args) >>.
c9d2e0a2 1102
10976519 1103Creates an SQL file based on the Schema, for each of the specified
1104database types, in the given directory.
c9d2e0a2 1105
c0f61310 1106=cut
1107
6e73ac25 1108sub create_ddl_dir {
e673f011 1109 my $self = shift;
1110
1111 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1112 $self->storage->create_ddl_dir($self, @_);
1113}
1114
e63a82f7 1115=head2 ddl_filename
9b83fccd 1116
c9d2e0a2 1117=over 4
1118
99a74c4a 1119=item Arguments: $database-type, $version, $directory, $preversion
c9d2e0a2 1120
829517d4 1121=item Return value: $normalised_filename
1122
c9d2e0a2 1123=back
1124
99a74c4a 1125 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
c9d2e0a2 1126
1127This method is called by C<create_ddl_dir> to compose a file name out of
1128the supplied directory, database type and version number. The default file
1129name format is: C<$dir$schema-$version-$type.sql>.
9b83fccd 1130
c9d2e0a2 1131You may override this method in your schema if you wish to use a different
1132format.
9b83fccd 1133
1acfef8e 1134 WARNING
1135
1136 Prior to DBIx::Class version 0.08100 this method had a different signature:
1137
1138 my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
1139
1140 In recent versions variables $dir and $version were reversed in order to
1141 bring the signature in line with other Schema/Storage methods. If you
1142 really need to maintain backward compatibility, you can do the following
1143 in any overriding methods:
1144
1145 ($dir, $version) = ($version, $dir) if ($DBIx::Class::VERSION < 0.08100);
1146
9b83fccd 1147=cut
1148
6e73ac25 1149sub ddl_filename {
99a74c4a 1150 my ($self, $type, $version, $dir, $preversion) = @_;
e673f011 1151
99a74c4a 1152 my $filename = ref($self);
1153 $filename =~ s/::/-/g;
1154 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1155 $filename =~ s/$version/$preversion-$version/ if($preversion);
d4daee7b 1156
99a74c4a 1157 return $filename;
e673f011 1158}
1159
4146e3da 1160=head2 thaw
1161
829517d4 1162Provided as the recommended way of thawing schema objects. You can call
4146e3da 1163C<Storable::thaw> directly if you wish, but the thawed objects will not have a
48580715 1164reference to any schema, so are rather useless.
4146e3da 1165
1166=cut
1167
1168sub thaw {
1169 my ($self, $obj) = @_;
1170 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1171 return Storable::thaw($obj);
1172}
1173
1174=head2 freeze
1175
48580715 1176This doesn't actually do anything more than call L<Storable/freeze>, it is just
1177provided here for symmetry.
4146e3da 1178
d2f3e87b 1179=cut
1180
4146e3da 1181sub freeze {
1182 return Storable::freeze($_[1]);
1183}
1184
1185=head2 dclone
1186
1477a478 1187=over 4
1188
1189=item Arguments: $object
1190
1191=item Return Value: dcloned $object
1192
1193=back
1194
9e9ecfda 1195Recommended way of dcloning L<DBIx::Class::Row> and L<DBIx::Class::ResultSet>
1196objects so their references to the schema object
1197(which itself is B<not> cloned) are properly maintained.
4146e3da 1198
1199=cut
1200
1201sub dclone {
1202 my ($self, $obj) = @_;
1203 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1204 return Storable::dclone($obj);
1205}
1206
93e4d41a 1207=head2 schema_version
1208
829517d4 1209Returns the current schema class' $VERSION in a normalised way.
93e4d41a 1210
1211=cut
1212
1213sub schema_version {
1214 my ($self) = @_;
1215 my $class = ref($self)||$self;
1216
1217 # does -not- use $schema->VERSION
1218 # since that varies in results depending on if version.pm is installed, and if
1219 # so the perl or XS versions. If you want this to change, bug the version.pm
1220 # author to make vpp and vxs behave the same.
1221
1222 my $version;
1223 {
1224 no strict 'refs';
1225 $version = ${"${class}::VERSION"};
1226 }
1227 return $version;
1228}
1229
829517d4 1230
1231=head2 register_class
1232
1233=over 4
1234
1235=item Arguments: $moniker, $component_class
1236
1237=back
1238
1239This 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.
1240
1241You will only need this method if you have your Result classes in
1242files which are not named after the packages (or all in the same
1243file). You may also need it to register classes at runtime.
1244
1245Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1246calling:
1247
1248 $schema->register_source($moniker, $component_class->result_source_instance);
1249
1250=cut
1251
1252sub register_class {
1253 my ($self, $moniker, $to_register) = @_;
1e36ef62 1254 $self->register_source($moniker => $to_register->result_source_instance);
829517d4 1255}
1256
1257=head2 register_source
1258
1259=over 4
1260
1261=item Arguments: $moniker, $result_source
1262
1263=back
1264
1265This method is called by L</register_class>.
1266
1267Registers the L<DBIx::Class::ResultSource> in the schema with the given
1268moniker.
1269
1270=cut
1271
1272sub register_source {
1273 my $self = shift;
1274
1275 $self->_register_source(@_);
1276}
1277
98cabed3 1278=head2 unregister_source
1279
1280=over 4
1281
1282=item Arguments: $moniker
1283
1284=back
1285
1286Removes the L<DBIx::Class::ResultSource> from the schema for the given moniker.
1287
1288=cut
1289
1290sub unregister_source {
1291 my $self = shift;
1292
1293 $self->_unregister_source(@_);
1294}
1295
829517d4 1296=head2 register_extra_source
1297
1298=over 4
1299
1300=item Arguments: $moniker, $result_source
1301
1302=back
1303
1304As L</register_source> but should be used if the result class already
1305has a source and you want to register an extra one.
1306
1307=cut
1308
1309sub register_extra_source {
1310 my $self = shift;
1311
1312 $self->_register_source(@_, { extra => 1 });
1313}
1314
1315sub _register_source {
1316 my ($self, $moniker, $source, $params) = @_;
1317
6d4f9d94 1318 my $orig_source = $source;
2461ae19 1319
0e6c5d58 1320 $source = $source->new({ %$source, source_name => $moniker });
762deea2 1321 use Data::Dumper;
1322 die Dumper $source;
2461ae19 1323 $source->schema($self);
551e711a 1324 Scalar::Util::weaken($source->{schema}) if ref($self);
2461ae19 1325
1326 my $rs_class = $source->result_class;
829517d4 1327
1328 my %reg = %{$self->source_registrations};
1329 $reg{$moniker} = $source;
1330 $self->source_registrations(\%reg);
1331
829517d4 1332 return if ($params->{extra});
5dfe40b8 1333 return unless defined($rs_class) && $rs_class->can('result_source_instance');
829517d4 1334
2461ae19 1335 my %map = %{$self->class_mappings};
f18d2d04 1336 if (
1337 exists $map{$rs_class}
1338 and
1339 $map{$rs_class} ne $moniker
1340 and
1341 $rs_class->result_source_instance ne $orig_source
1342 ) {
2461ae19 1343 carp "$rs_class already has a source, use register_extra_source for additional sources";
829517d4 1344 }
2461ae19 1345 $map{$rs_class} = $moniker;
1346 $self->class_mappings(\%map);
829517d4 1347}
1348
1349sub _unregister_source {
1350 my ($self, $moniker) = @_;
1351 my %reg = %{$self->source_registrations};
1352
1353 my $source = delete $reg{$moniker};
1354 $self->source_registrations(\%reg);
1355 if ($source->result_class) {
1356 my %map = %{$self->class_mappings};
1357 delete $map{$source->result_class};
1358 $self->class_mappings(\%map);
1359 }
1360}
1361
1362
1363=head2 compose_connection (DEPRECATED)
1364
1365=over 4
1366
1367=item Arguments: $target_namespace, @db_info
1368
1369=item Return Value: $new_schema
1370
1371=back
1372
1373DEPRECATED. You probably wanted compose_namespace.
1374
1375Actually, you probably just wanted to call connect.
1376
1377=begin hidden
1378
1379(hidden due to deprecation)
1380
1381Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1382calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1383then injects the L<DBix::Class::ResultSetProxy> component and a
1384resultset_instance classdata entry on all the new classes, in order to support
1385$target_namespaces::$class->search(...) method calls.
1386
1387This is primarily useful when you have a specific need for class method access
1388to a connection. In normal usage it is preferred to call
1389L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1390on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1391more information.
1392
1393=end hidden
1394
1395=cut
1396
1397{
1398 my $warn;
1399
1400 sub compose_connection {
1401 my ($self, $target, @info) = @_;
1402
341d5ede 1403 carp "compose_connection deprecated as of 0.08000"
829517d4 1404 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1405
1406 my $base = 'DBIx::Class::ResultSetProxy';
1407 eval "require ${base};";
1408 $self->throw_exception
1409 ("No arguments to load_classes and couldn't load ${base} ($@)")
1410 if $@;
d4daee7b 1411
829517d4 1412 if ($self eq $target) {
1413 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1414 foreach my $moniker ($self->sources) {
1415 my $source = $self->source($moniker);
1416 my $class = $source->result_class;
1417 $self->inject_base($class, $base);
1418 $class->mk_classdata(resultset_instance => $source->resultset);
1419 $class->mk_classdata(class_resolver => $self);
1420 }
1421 $self->connection(@info);
1422 return $self;
1423 }
d4daee7b 1424
829517d4 1425 my $schema = $self->compose_namespace($target, $base);
1426 {
1427 no strict 'refs';
1428 my $name = join '::', $target, 'schema';
1429 *$name = Sub::Name::subname $name, sub { $schema };
1430 }
d4daee7b 1431
829517d4 1432 $schema->connection(@info);
1433 foreach my $moniker ($schema->sources) {
1434 my $source = $schema->source($moniker);
1435 my $class = $source->result_class;
1436 #warn "$moniker $class $source ".$source->storage;
1437 $class->mk_classdata(result_source_instance => $source);
1438 $class->mk_classdata(resultset_instance => $source->resultset);
1439 $class->mk_classdata(class_resolver => $schema);
1440 }
1441 return $schema;
1442 }
1443}
1444
a02675cd 14451;
c2da098a 1446
c2da098a 1447=head1 AUTHORS
1448
daec44b8 1449Matt S. Trout <mst@shadowcatsystems.co.uk>
c2da098a 1450
1451=head1 LICENSE
1452
1453You may distribute this code under the same terms as Perl itself.
1454
1455=cut