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