moved schema_version from Versioning to core
[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/;
a917fb06 8use Scalar::Util qw/weaken/;
c9d2e0a2 9use File::Spec;
7cb86b38 10require Module::Find;
a02675cd 11
41a6f8c0 12use base qw/DBIx::Class/;
a02675cd 13
0dc79249 14__PACKAGE__->mk_classdata('class_mappings' => {});
15__PACKAGE__->mk_classdata('source_registrations' => {});
1e10a11d 16__PACKAGE__->mk_classdata('storage_type' => '::DBI');
d7156e50 17__PACKAGE__->mk_classdata('storage');
82cc0386 18__PACKAGE__->mk_classdata('exception_action');
4b946902 19__PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
e6c747fd 20__PACKAGE__->mk_classdata('default_resultset_attributes' => {});
a02675cd 21
c2da098a 22=head1 NAME
23
24DBIx::Class::Schema - composable schemas
25
26=head1 SYNOPSIS
27
24d67825 28 package Library::Schema;
c2da098a 29 use base qw/DBIx::Class::Schema/;
bab77431 30
24d67825 31 # load Library::Schema::CD, Library::Schema::Book, Library::Schema::DVD
32 __PACKAGE__->load_classes(qw/CD Book DVD/);
c2da098a 33
24d67825 34 package Library::Schema::CD;
03312470 35 use base qw/DBIx::Class/;
77254782 36 __PACKAGE__->load_components(qw/PK::Auto Core/); # for example
24d67825 37 __PACKAGE__->table('cd');
c2da098a 38
5d9076f2 39 # Elsewhere in your code:
24d67825 40 my $schema1 = Library::Schema->connect(
a3d93194 41 $dsn,
42 $user,
43 $password,
24d67825 44 { AutoCommit => 0 },
a3d93194 45 );
bab77431 46
24d67825 47 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
c2da098a 48
24d67825 49 # fetch objects using Library::Schema::DVD
50 my $resultset = $schema1->resultset('DVD')->search( ... );
51 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
c2da098a 52
53=head1 DESCRIPTION
54
a3d93194 55Creates database classes based on a schema. This is the recommended way to
56use L<DBIx::Class> and allows you to use more than one concurrent connection
57with your classes.
429bd4f1 58
03312470 59NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
2053ab2a 60carefully, as DBIx::Class does things a little differently. Note in
03312470 61particular which module inherits off which.
62
c2da098a 63=head1 METHODS
64
5b60f0c1 65=head2 schema_version
66
67Returns the current schema class' $VERSION
68
69=cut
70
71sub schema_version {
72 my ($self) = @_;
73 my $class = ref($self)||$self;
74
75 # does -not- use $schema->VERSION
76 # since that varies in results depending on if version.pm is installed, and if
77 # so the perl or XS versions. If you want this to change, bug the version.pm
78 # author to make vpp and vxs behave the same.
79
80 my $version;
81 {
82 no strict 'refs';
83 $version = ${"${class}::VERSION"};
84 }
85 return $version;
86}
87
87c4e602 88=head2 register_class
89
27f01d1f 90=over 4
91
ebc77b53 92=item Arguments: $moniker, $component_class
27f01d1f 93
94=back
076652e8 95
71f9df37 96Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
2053ab2a 97calling:
66d9ef6b 98
181a28f4 99 $schema->register_source($moniker, $component_class->result_source_instance);
076652e8 100
c2da098a 101=cut
102
a02675cd 103sub register_class {
0dc79249 104 my ($self, $moniker, $to_register) = @_;
105 $self->register_source($moniker => $to_register->result_source_instance);
74b92d9a 106}
107
87c4e602 108=head2 register_source
109
27f01d1f 110=over 4
111
ebc77b53 112=item Arguments: $moniker, $result_source
27f01d1f 113
114=back
076652e8 115
82b01c38 116Registers the L<DBIx::Class::ResultSource> in the schema with the given
117moniker.
076652e8 118
119=cut
120
0dc79249 121sub register_source {
122 my ($self, $moniker, $source) = @_;
93405cf0 123
124 %$source = %{ $source->new( { %$source, source_name => $moniker }) };
125
96c95414 126 my %reg = %{$self->source_registrations};
127 $reg{$moniker} = $source;
128 $self->source_registrations(\%reg);
93405cf0 129
0dc79249 130 $source->schema($self);
93405cf0 131
a917fb06 132 weaken($source->{schema}) if ref($self);
0dc79249 133 if ($source->result_class) {
96c95414 134 my %map = %{$self->class_mappings};
135 $map{$source->result_class} = $moniker;
136 $self->class_mappings(\%map);
0dc79249 137 }
75d07914 138}
a02675cd 139
93405cf0 140sub _unregister_source {
141 my ($self, $moniker) = @_;
142 my %reg = %{$self->source_registrations};
143
144 my $source = delete $reg{$moniker};
145 $self->source_registrations(\%reg);
146 if ($source->result_class) {
147 my %map = %{$self->class_mappings};
148 delete $map{$source->result_class};
149 $self->class_mappings(\%map);
150 }
151}
152
bfb2bd4f 153=head2 class
154
27f01d1f 155=over 4
82b01c38 156
ebc77b53 157=item Arguments: $moniker
27f01d1f 158
d601dc88 159=item Return Value: $classname
27f01d1f 160
161=back
82b01c38 162
2053ab2a 163Retrieves the result class name for the given moniker. For example:
82b01c38 164
165 my $class = $schema->class('CD');
bfb2bd4f 166
167=cut
168
169sub class {
0dc79249 170 my ($self, $moniker) = @_;
171 return $self->source($moniker)->result_class;
bfb2bd4f 172}
173
ea20d0fd 174=head2 source
175
27f01d1f 176=over 4
177
ebc77b53 178=item Arguments: $moniker
27f01d1f 179
d601dc88 180=item Return Value: $result_source
82b01c38 181
27f01d1f 182=back
82b01c38 183
24d67825 184 my $source = $schema->source('Book');
ea20d0fd 185
82b01c38 186Returns the L<DBIx::Class::ResultSource> object for the registered moniker.
ea20d0fd 187
188=cut
189
190sub source {
0dc79249 191 my ($self, $moniker) = @_;
192 my $sreg = $self->source_registrations;
193 return $sreg->{$moniker} if exists $sreg->{$moniker};
194
195 # if we got here, they probably passed a full class name
196 my $mapped = $self->class_mappings->{$moniker};
701da8c4 197 $self->throw_exception("Can't find source for ${moniker}")
0dc79249 198 unless $mapped && exists $sreg->{$mapped};
199 return $sreg->{$mapped};
ea20d0fd 200}
201
0dc79249 202=head2 sources
203
27f01d1f 204=over 4
205
d601dc88 206=item Return Value: @source_monikers
27f01d1f 207
208=back
82b01c38 209
210Returns the source monikers of all source registrations on this schema.
2053ab2a 211For example:
82b01c38 212
213 my @source_monikers = $schema->sources;
0dc79249 214
215=cut
216
217sub sources { return keys %{shift->source_registrations}; }
218
9b1ba0f2 219=head2 storage
220
221 my $storage = $schema->storage;
222
223Returns the L<DBIx::Class::Storage> object for this Schema.
224
ea20d0fd 225=head2 resultset
226
27f01d1f 227=over 4
228
ebc77b53 229=item Arguments: $moniker
27f01d1f 230
d601dc88 231=item Return Value: $result_set
82b01c38 232
27f01d1f 233=back
82b01c38 234
24d67825 235 my $rs = $schema->resultset('DVD');
ea20d0fd 236
82b01c38 237Returns the L<DBIx::Class::ResultSet> object for the registered moniker.
ea20d0fd 238
239=cut
240
241sub resultset {
0dc79249 242 my ($self, $moniker) = @_;
243 return $self->source($moniker)->resultset;
ea20d0fd 244}
245
87c4e602 246=head2 load_classes
247
27f01d1f 248=over 4
249
250=item Arguments: @classes?, { $namespace => [ @classes ] }+
251
252=back
076652e8 253
82b01c38 254With no arguments, this method uses L<Module::Find> to find all classes under
255the schema's namespace. Otherwise, this method loads the classes you specify
256(using L<use>), and registers them (using L</"register_class">).
076652e8 257
2053ab2a 258It is possible to comment out classes with a leading C<#>, but note that perl
259will think it's a mistake (trying to use a comment in a qw list), so you'll
260need to add C<no warnings 'qw';> before your load_classes call.
5ce32fc1 261
2053ab2a 262Example:
82b01c38 263
264 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
75d07914 265 # etc. (anything under the My::Schema namespace)
82b01c38 266
267 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
268 # not Other::Namespace::LinerNotes nor My::Schema::Track
269 My::Schema->load_classes(qw/ CD Artist #Track /, {
270 Other::Namespace => [qw/ Producer #LinerNotes /],
271 });
272
076652e8 273=cut
274
a02675cd 275sub load_classes {
5ce32fc1 276 my ($class, @params) = @_;
bab77431 277
5ce32fc1 278 my %comps_for;
bab77431 279
5ce32fc1 280 if (@params) {
281 foreach my $param (@params) {
282 if (ref $param eq 'ARRAY') {
283 # filter out commented entries
284 my @modules = grep { $_ !~ /^#/ } @$param;
bab77431 285
5ce32fc1 286 push (@{$comps_for{$class}}, @modules);
287 }
288 elsif (ref $param eq 'HASH') {
289 # more than one namespace possible
290 for my $comp ( keys %$param ) {
291 # filter out commented entries
292 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
293
294 push (@{$comps_for{$comp}}, @modules);
295 }
296 }
297 else {
298 # filter out commented entries
299 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
300 }
301 }
302 } else {
bc0c9800 303 my @comp = map { substr $_, length "${class}::" }
304 Module::Find::findallmod($class);
5ce32fc1 305 $comps_for{$class} = \@comp;
41a6f8c0 306 }
5ce32fc1 307
e6efde04 308 my @to_register;
309 {
310 no warnings qw/redefine/;
311 local *Class::C3::reinitialize = sub { };
312 foreach my $prefix (keys %comps_for) {
313 foreach my $comp (@{$comps_for{$prefix}||[]}) {
314 my $comp_class = "${prefix}::${comp}";
83542a7d 315 { # try to untaint module name. mods where this fails
316 # are left alone so we don't have to change the old behavior
317 no locale; # localized \w doesn't untaint expression
318 if ( $comp_class =~ m/^( (?:\w+::)* \w+ )$/x ) {
319 $comp_class = $1;
320 }
321 }
c037c03a 322 $class->ensure_class_loaded($comp_class);
bab77431 323
93405cf0 324 $comp = $comp_class->source_name || $comp;
325# $DB::single = 1;
326 push(@to_register, [ $comp, $comp_class ]);
bfb2bd4f 327 }
5ce32fc1 328 }
a02675cd 329 }
e6efde04 330 Class::C3->reinitialize;
331
332 foreach my $to (@to_register) {
333 $class->register_class(@$to);
334 # if $class->can('result_source_instance');
335 }
a02675cd 336}
337
2374c5ff 338=head2 load_namespaces
339
340=over 4
341
85bd0538 342=item Arguments: %options?
2374c5ff 343
344=back
345
346This is an alternative to L</load_classes> above which assumes an alternative
c87014e8 347layout for automatic class loading. It assumes that all result
348classes are underneath a sub-namespace of the schema called C<Result>, any
7a58f051 349corresponding ResultSet classes are underneath a sub-namespace of the schema
46a05fd4 350called C<ResultSet>.
2374c5ff 351
46a05fd4 352Both of the sub-namespaces are configurable if you don't like the defaults,
c87014e8 353via the options C<result_namespace> and C<resultset_namespace>.
85bd0538 354
25fb14bd 355If (and only if) you specify the option C<default_resultset_class>, any found
c87014e8 356Result classes for which we do not find a corresponding
25fb14bd 357ResultSet class will have their C<resultset_class> set to
358C<default_resultset_class>.
0f4ec1d2 359
46a05fd4 360C<load_namespaces> takes care of calling C<resultset_class> for you where
361neccessary if you didn't do it for yourself.
f017c022 362
0f4ec1d2 363All of the namespace and classname options to this method are relative to
364the schema classname by default. To specify a fully-qualified name, prefix
365it with a literal C<+>.
2374c5ff 366
f017c022 367Examples:
2374c5ff 368
c87014e8 369 # load My::Schema::Result::CD, My::Schema::Result::Artist,
2374c5ff 370 # My::Schema::ResultSet::CD, etc...
0f4ec1d2 371 My::Schema->load_namespaces;
372
c87014e8 373 # Override everything to use ugly names.
374 # In this example, if there is a My::Schema::Res::Foo, but no matching
375 # My::Schema::RSets::Foo, then Foo will have its
376 # resultset_class set to My::Schema::RSetBase
0f4ec1d2 377 My::Schema->load_namespaces(
c87014e8 378 result_namespace => 'Res',
0f4ec1d2 379 resultset_namespace => 'RSets',
25fb14bd 380 default_resultset_class => 'RSetBase',
0f4ec1d2 381 );
2374c5ff 382
0f4ec1d2 383 # Put things in other namespaces
85bd0538 384 My::Schema->load_namespaces(
c87014e8 385 result_namespace => '+Some::Place::Results',
0f4ec1d2 386 resultset_namespace => '+Another::Place::RSets',
85bd0538 387 );
0f4ec1d2 388
f017c022 389If you'd like to use multiple namespaces of each type, simply use an arrayref
c87014e8 390of namespaces for that option. In the case that the same result
46a05fd4 391(or resultset) class exists in multiple namespaces, the latter entries in
392your list of namespaces will override earlier ones.
f017c022 393
394 My::Schema->load_namespaces(
c87014e8 395 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
396 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
f017c022 397 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
398 );
85bd0538 399
2374c5ff 400=cut
401
f017c022 402# Pre-pends our classname to the given relative classname or
403# class namespace, unless there is a '+' prefix, which will
7a58f051 404# be stripped.
f017c022 405sub _expand_relative_name {
7a58f051 406 my ($class, $name) = @_;
407 return if !$name;
408 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
409 return $name;
f017c022 410}
411
412# returns a hash of $shortname => $fullname for every package
413# found in the given namespaces ($shortname is with the $fullname's
414# namespace stripped off)
415sub _map_namespaces {
416 my ($class, @namespaces) = @_;
417
418 my @results_hash;
419 foreach my $namespace (@namespaces) {
420 push(
421 @results_hash,
422 map { (substr($_, length "${namespace}::"), $_) }
423 Module::Find::findallmod($namespace)
424 );
425 }
426
427 @results_hash;
428}
429
2374c5ff 430sub load_namespaces {
85bd0538 431 my ($class, %args) = @_;
2374c5ff 432
c87014e8 433 my $result_namespace = delete $args{result_namespace} || 'Result';
25fb14bd 434 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
25fb14bd 435 my $default_resultset_class = delete $args{default_resultset_class};
0f4ec1d2 436
25fb14bd 437 $class->throw_exception('load_namespaces: unknown option(s): '
438 . join(q{,}, map { qq{'$_'} } keys %args))
439 if scalar keys %args;
440
7a58f051 441 $default_resultset_class
442 = $class->_expand_relative_name($default_resultset_class);
f017c022 443
c87014e8 444 for my $arg ($result_namespace, $resultset_namespace) {
f017c022 445 $arg = [ $arg ] if !ref($arg) && $arg;
2374c5ff 446
f017c022 447 $class->throw_exception('load_namespaces: namespace arguments must be '
448 . 'a simple string or an arrayref')
449 if ref($arg) ne 'ARRAY';
2374c5ff 450
7a58f051 451 $_ = $class->_expand_relative_name($_) for (@$arg);
f017c022 452 }
2374c5ff 453
c87014e8 454 my %results = $class->_map_namespaces(@$result_namespace);
f017c022 455 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
0f4ec1d2 456
2374c5ff 457 my @to_register;
458 {
25fb14bd 459 no warnings 'redefine';
2374c5ff 460 local *Class::C3::reinitialize = sub { };
25fb14bd 461 use warnings 'redefine';
0f4ec1d2 462
c87014e8 463 foreach my $result (keys %results) {
464 my $result_class = $results{$result};
465 $class->ensure_class_loaded($result_class);
466 $result_class->source_name($result) unless $result_class->source_name;
0f4ec1d2 467
c87014e8 468 my $rs_class = delete $resultsets{$result};
469 my $rs_set = $result_class->resultset_class;
25fb14bd 470 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
f017c022 471 if($rs_class && $rs_class ne $rs_set) {
c87014e8 472 warn "We found ResultSet class '$rs_class' for '$result', but it seems "
473 . "that you had already set '$result' to use '$rs_set' instead";
2374c5ff 474 }
475 }
25fb14bd 476 elsif($rs_class ||= $default_resultset_class) {
477 $class->ensure_class_loaded($rs_class);
c87014e8 478 $result_class->resultset_class($rs_class);
0f4ec1d2 479 }
2374c5ff 480
c87014e8 481 push(@to_register, [ $result_class->source_name, $result_class ]);
2374c5ff 482 }
483 }
484
0f4ec1d2 485 foreach (sort keys %resultsets) {
486 warn "load_namespaces found ResultSet class $_ with no "
c87014e8 487 . 'corresponding Result class';
2374c5ff 488 }
0f4ec1d2 489
fdcd8145 490 Class::C3->reinitialize;
491 $class->register_class(@$_) for (@to_register);
492
0f4ec1d2 493 return;
2374c5ff 494}
495
c216324a 496=head2 compose_connection (DEPRECATED)
87c4e602 497
27f01d1f 498=over 4
499
ebc77b53 500=item Arguments: $target_namespace, @db_info
429bd4f1 501
d601dc88 502=item Return Value: $new_schema
27f01d1f 503
504=back
076652e8 505
c216324a 506DEPRECATED. You probably wanted compose_namespace.
507
508Actually, you probably just wanted to call connect.
509
1c133e22 510=begin hidden
511
512(hidden due to deprecation)
c216324a 513
2053ab2a 514Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
515calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
516then injects the L<DBix::Class::ResultSetProxy> component and a
517resultset_instance classdata entry on all the new classes, in order to support
82b01c38 518$target_namespaces::$class->search(...) method calls.
519
520This is primarily useful when you have a specific need for class method access
521to a connection. In normal usage it is preferred to call
522L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
523on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
524more information.
54540863 525
1c133e22 526=end hidden
527
076652e8 528=cut
529
c216324a 530{
531 my $warn;
532
533 sub compose_connection {
534 my ($self, $target, @info) = @_;
535
3943fd63 536 warn "compose_connection deprecated as of 0.08000"
537 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
c216324a 538
539 my $base = 'DBIx::Class::ResultSetProxy';
540 eval "require ${base};";
541 $self->throw_exception
542 ("No arguments to load_classes and couldn't load ${base} ($@)")
543 if $@;
544
545 if ($self eq $target) {
546 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
547 foreach my $moniker ($self->sources) {
548 my $source = $self->source($moniker);
549 my $class = $source->result_class;
550 $self->inject_base($class, $base);
551 $class->mk_classdata(resultset_instance => $source->resultset);
552 $class->mk_classdata(class_resolver => $self);
553 }
554 $self->connection(@info);
555 return $self;
556 }
557
558 my $schema = $self->compose_namespace($target, $base);
559 {
560 no strict 'refs';
561 *{"${target}::schema"} = sub { $schema };
562 }
563
564 $schema->connection(@info);
565 foreach my $moniker ($schema->sources) {
566 my $source = $schema->source($moniker);
be381829 567 my $class = $source->result_class;
c216324a 568 #warn "$moniker $class $source ".$source->storage;
569 $class->mk_classdata(result_source_instance => $source);
be381829 570 $class->mk_classdata(resultset_instance => $source->resultset);
c216324a 571 $class->mk_classdata(class_resolver => $schema);
be381829 572 }
c216324a 573 return $schema;
bfb2bd4f 574 }
e678398e 575}
576
77254782 577=head2 compose_namespace
578
27f01d1f 579=over 4
580
581=item Arguments: $target_namespace, $additional_base_class?
82b01c38 582
d601dc88 583=item Return Value: $new_schema
27f01d1f 584
585=back
13765dad 586
82b01c38 587For each L<DBIx::Class::ResultSource> in the schema, this method creates a
588class in the target namespace (e.g. $target_namespace::CD,
589$target_namespace::Artist) that inherits from the corresponding classes
590attached to the current schema.
77254782 591
82b01c38 592It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
593new $schema object. If C<$additional_base_class> is given, the new composed
594classes will inherit from first the corresponding classe from the current
595schema then the base class.
596
2053ab2a 597For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
82b01c38 598
599 $schema->compose_namespace('My::DB', 'Base::Class');
600 print join (', ', @My::DB::CD::ISA) . "\n";
601 print join (', ', @My::DB::Artist::ISA) ."\n";
602
2053ab2a 603will produce the output
82b01c38 604
605 My::Schema::CD, Base::Class
606 My::Schema::Artist, Base::Class
77254782 607
608=cut
609
e678398e 610sub compose_namespace {
66d9ef6b 611 my ($self, $target, $base) = @_;
66d9ef6b 612 my $schema = $self->clone;
e9100ff7 613 {
614 no warnings qw/redefine/;
615 local *Class::C3::reinitialize = sub { };
616 foreach my $moniker ($schema->sources) {
617 my $source = $schema->source($moniker);
618 my $target_class = "${target}::${moniker}";
619 $self->inject_base(
620 $target_class => $source->result_class, ($base ? $base : ())
621 );
622 $source->result_class($target_class);
9d3d5af3 623 $target_class->result_source_instance($source)
624 if $target_class->can('result_source_instance');
e9100ff7 625 }
b7951443 626 }
e9100ff7 627 Class::C3->reinitialize();
11b78bd6 628 {
629 no strict 'refs';
978b42af 630 no warnings 'redefine';
1edaf6fe 631 foreach my $meth (qw/class source resultset/) {
632 *{"${target}::${meth}"} =
633 sub { shift->schema->$meth(@_) };
634 }
11b78bd6 635 }
bfb2bd4f 636 return $schema;
b7951443 637}
638
639sub setup_connection_class {
640 my ($class, $target, @info) = @_;
63e9583a 641 $class->inject_base($target => 'DBIx::Class::DB');
642 #$target->load_components('DB');
b7951443 643 $target->connection(@info);
644}
645
6b43ba5f 646=head2 storage_type
647
648=over 4
649
650=item Arguments: $storage_type
651
652=item Return Value: $storage_type
653
654=back
655
656Set the storage class that will be instantiated when L</connect> is called.
657If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
658assumed by L</connect>. Defaults to C<::DBI>,
659which is L<DBIx::Class::Storage::DBI>.
660
661You want to use this to hardcoded subclasses of L<DBIx::Class::Storage::DBI>
662in cases where the appropriate subclass is not autodetected, such as when
663dealing with MSSQL via L<DBD::Sybase>, in which case you'd set it to
664C<::DBI::Sybase::MSSQL>.
665
87c4e602 666=head2 connection
667
27f01d1f 668=over 4
669
ebc77b53 670=item Arguments: @args
66d9ef6b 671
d601dc88 672=item Return Value: $new_schema
27f01d1f 673
674=back
82b01c38 675
676Instantiates a new Storage object of type
677L<DBIx::Class::Schema/"storage_type"> and passes the arguments to
85f78622 678$storage->connect_info. Sets the connection in-place on the schema.
679
680See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific syntax,
681or L<DBIx::Class::Storage> in general.
66d9ef6b 682
683=cut
684
685sub connection {
686 my ($self, @info) = @_;
e59d3e5b 687 return $self if !@info && $self->storage;
1e10a11d 688 my $storage_class = $self->storage_type;
689 $storage_class = 'DBIx::Class::Storage'.$storage_class
690 if $storage_class =~ m/^::/;
8ef144ff 691 eval "require ${storage_class};";
bc0c9800 692 $self->throw_exception(
693 "No arguments to load_classes and couldn't load ${storage_class} ($@)"
694 ) if $@;
82cc0386 695 my $storage = $storage_class->new($self);
66d9ef6b 696 $storage->connect_info(\@info);
697 $self->storage($storage);
698 return $self;
699}
700
87c4e602 701=head2 connect
702
27f01d1f 703=over 4
704
ebc77b53 705=item Arguments: @info
66d9ef6b 706
d601dc88 707=item Return Value: $new_schema
27f01d1f 708
709=back
82b01c38 710
711This is a convenience method. It is equivalent to calling
712$schema->clone->connection(@info). See L</connection> and L</clone> for more
713information.
66d9ef6b 714
715=cut
716
08b515f1 717sub connect { shift->clone->connection(@_) }
718
4012acd8 719=head2 txn_do
08b515f1 720
4012acd8 721=over 4
08b515f1 722
4012acd8 723=item Arguments: C<$coderef>, @coderef_args?
08b515f1 724
4012acd8 725=item Return Value: The return value of $coderef
08b515f1 726
4012acd8 727=back
08b515f1 728
4012acd8 729Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
730returning its result (if any). Equivalent to calling $schema->storage->txn_do.
731See L<DBIx::Class::Storage/"txn_do"> for more information.
08b515f1 732
4012acd8 733This interface is preferred over using the individual methods L</txn_begin>,
734L</txn_commit>, and L</txn_rollback> below.
08b515f1 735
4012acd8 736=cut
08b515f1 737
4012acd8 738sub txn_do {
739 my $self = shift;
08b515f1 740
4012acd8 741 $self->storage or $self->throw_exception
742 ('txn_do called on $schema without storage');
08b515f1 743
4012acd8 744 $self->storage->txn_do(@_);
745}
66d9ef6b 746
75c8a7ab 747=head2 txn_scope_guard
748
749Runs C<txn_scope_guard> on the schema's storage.
750
b85be4c1 751=cut
752
1bc193ac 753sub txn_scope_guard {
754 my $self = shift;
755
756 $self->storage or $self->throw_exception
757 ('txn_scope_guard called on $schema without storage');
758
759 $self->storage->txn_scope_guard(@_);
760}
761
4012acd8 762=head2 txn_begin
a62cf8d4 763
4012acd8 764Begins a transaction (does nothing if AutoCommit is off). Equivalent to
765calling $schema->storage->txn_begin. See
766L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
27f01d1f 767
4012acd8 768=cut
82b01c38 769
4012acd8 770sub txn_begin {
771 my $self = shift;
27f01d1f 772
4012acd8 773 $self->storage or $self->throw_exception
774 ('txn_begin called on $schema without storage');
a62cf8d4 775
4012acd8 776 $self->storage->txn_begin;
777}
a62cf8d4 778
4012acd8 779=head2 txn_commit
a62cf8d4 780
4012acd8 781Commits the current transaction. Equivalent to calling
782$schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
783for more information.
a62cf8d4 784
4012acd8 785=cut
a62cf8d4 786
4012acd8 787sub txn_commit {
788 my $self = shift;
a62cf8d4 789
4012acd8 790 $self->storage or $self->throw_exception
791 ('txn_commit called on $schema without storage');
a62cf8d4 792
4012acd8 793 $self->storage->txn_commit;
794}
70634260 795
4012acd8 796=head2 txn_rollback
a62cf8d4 797
4012acd8 798Rolls back the current transaction. Equivalent to calling
799$schema->storage->txn_rollback. See
800L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
a62cf8d4 801
802=cut
803
4012acd8 804sub txn_rollback {
805 my $self = shift;
a62cf8d4 806
19630353 807 $self->storage or $self->throw_exception
4012acd8 808 ('txn_rollback called on $schema without storage');
a62cf8d4 809
4012acd8 810 $self->storage->txn_rollback;
a62cf8d4 811}
812
adb3554a 813=head2 svp_begin
814
815Creates a new savepoint (does nothing outside a transaction).
816Equivalent to calling $schema->storage->svp_begin. See
817L<DBIx::Class::Storage::DBI/"svp_begin"> for more information.
818
819=cut
820
821sub svp_begin {
822 my ($self, $name) = @_;
823
824 $self->storage or $self->throw_exception
825 ('svp_begin called on $schema without storage');
826
827 $self->storage->svp_begin($name);
828}
829
830=head2 svp_release
831
832Releases a savepoint (does nothing outside a transaction).
833Equivalent to calling $schema->storage->svp_release. See
834L<DBIx::Class::Storage::DBI/"svp_release"> for more information.
835
836=cut
837
838sub svp_release {
839 my ($self, $name) = @_;
840
841 $self->storage or $self->throw_exception
842 ('svp_release called on $schema without storage');
843
844 $self->storage->svp_release($name);
845}
846
847=head2 svp_rollback
848
849Rollback to a savepoint (does nothing outside a transaction).
850Equivalent to calling $schema->storage->svp_rollback. See
851L<DBIx::Class::Storage::DBI/"svp_rollback"> for more information.
852
853=cut
854
855sub svp_rollback {
856 my ($self, $name) = @_;
857
858 $self->storage or $self->throw_exception
859 ('svp_rollback called on $schema without storage');
860
861 $self->storage->svp_rollback($name);
862}
863
66d9ef6b 864=head2 clone
865
27f01d1f 866=over 4
867
d601dc88 868=item Return Value: $new_schema
27f01d1f 869
870=back
82b01c38 871
66d9ef6b 872Clones the schema and its associated result_source objects and returns the
873copy.
874
875=cut
876
877sub clone {
878 my ($self) = @_;
04786a4c 879 my $clone = { (ref $self ? %$self : ()) };
880 bless $clone, (ref $self || $self);
881
66d9ef6b 882 foreach my $moniker ($self->sources) {
883 my $source = $self->source($moniker);
884 my $new = $source->new($source);
885 $clone->register_source($moniker => $new);
886 }
82cc0386 887 $clone->storage->set_schema($clone) if $clone->storage;
66d9ef6b 888 return $clone;
889}
890
87c4e602 891=head2 populate
892
27f01d1f 893=over 4
894
16c5f7d3 895=item Arguments: $source_name, \@data;
27f01d1f 896
897=back
a37a4697 898
16c5f7d3 899Pass this method a resultsource name, and an arrayref of
900arrayrefs. The arrayrefs should contain a list of column names,
901followed by one or many sets of matching data for the given columns.
902
744076d8 903In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
904to insert the data, as this is a fast method. However, insert_bulk currently
905assumes that your datasets all contain the same type of values, using scalar
906references in a column in one row, and not in another will probably not work.
907
908Otherwise, each set of data is inserted into the database using
16c5f7d3 909L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
910objects is returned.
82b01c38 911
912i.e.,
a37a4697 913
24d67825 914 $schema->populate('Artist', [
915 [ qw/artistid name/ ],
916 [ 1, 'Popular Band' ],
917 [ 2, 'Indie Band' ],
a62cf8d4 918 ...
919 ]);
5a93e138 920
921Since wantarray context is basically the same as looping over $rs->create(...)
922you won't see any performance benefits and in this case the method is more for
923convenience. Void context sends the column information directly to storage
924using <DBI>s bulk insert method. So the performance will be much better for
925storages that support this method.
926
927Because of this difference in the way void context inserts rows into your
928database you need to note how this will effect any loaded components that
929override or augment insert. For example if you are using a component such
930as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
931wantarray context if you want the PKs automatically created.
a37a4697 932
933=cut
934
935sub populate {
936 my ($self, $name, $data) = @_;
937 my $rs = $self->resultset($name);
938 my @names = @{shift(@$data)};
54e0bd06 939 if(defined wantarray) {
940 my @created;
941 foreach my $item (@$data) {
942 my %create;
943 @create{@names} = @$item;
944 push(@created, $rs->create(\%create));
945 }
946 return @created;
a37a4697 947 }
8b93a938 948 my @results_to_create;
949 foreach my $datum (@$data) {
950 my %result_to_create;
951 foreach my $index (0..$#names) {
952 $result_to_create{$names[$index]} = $$datum[$index];
953 }
954 push @results_to_create, \%result_to_create;
955 }
956 $rs->populate(\@results_to_create);
a37a4697 957}
958
82cc0386 959=head2 exception_action
960
961=over 4
962
963=item Arguments: $code_reference
964
965=back
966
db5dc233 967If C<exception_action> is set for this class/object, L</throw_exception>
968will prefer to call this code reference with the exception as an argument,
613397e7 969rather than its normal C<croak> or C<confess> action.
db5dc233 970
971Your subroutine should probably just wrap the error in the exception
972object/class of your choosing and rethrow. If, against all sage advice,
973you'd like your C<exception_action> to suppress a particular exception
974completely, simply have it return true.
82cc0386 975
976Example:
977
978 package My::Schema;
979 use base qw/DBIx::Class::Schema/;
980 use My::ExceptionClass;
981 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
982 __PACKAGE__->load_classes;
983
db5dc233 984 # or:
82cc0386 985 my $schema_obj = My::Schema->connect( .... );
986 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
987
db5dc233 988 # suppress all exceptions, like a moron:
989 $schema_obj->exception_action(sub { 1 });
990
613397e7 991=head2 stacktrace
992
84c5863b 993=over 4
613397e7 994
995=item Arguments: boolean
996
997=back
998
4981dc70 999Whether L</throw_exception> should include stack trace information.
4b946902 1000Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
1001is true.
613397e7 1002
5160b401 1003=head2 throw_exception
701da8c4 1004
75d07914 1005=over 4
82b01c38 1006
ebc77b53 1007=item Arguments: $message
82b01c38 1008
1009=back
1010
1011Throws an exception. Defaults to using L<Carp::Clan> to report errors from
db5dc233 1012user's perspective. See L</exception_action> for details on overriding
4b946902 1013this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1014default behavior will provide a detailed stack trace.
701da8c4 1015
1016=cut
1017
1018sub throw_exception {
82cc0386 1019 my $self = shift;
4981dc70 1020
1021 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
1022 if !$self->exception_action || !$self->exception_action->(@_);
701da8c4 1023}
1024
dfccde48 1025=head2 deploy
1c339d71 1026
82b01c38 1027=over 4
1028
6e73ac25 1029=item Arguments: $sqlt_args, $dir
82b01c38 1030
1031=back
1032
1033Attempts to deploy the schema to the current storage using L<SQL::Translator>.
ec6704d4 1034
51bace1c 1035See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
1036common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
1037produced include a DROP TABLE statement for each table created.
1038
499adf63 1039Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1040ref or an array ref, containing a list of source to deploy. If present, then
0e2c6809 1041only the sources listed will get deployed. Furthermore, you can use the
1042C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1043FK.
499adf63 1044
1c339d71 1045=cut
1046
1047sub deploy {
6e73ac25 1048 my ($self, $sqltargs, $dir) = @_;
1c339d71 1049 $self->throw_exception("Can't deploy without storage") unless $self->storage;
6e73ac25 1050 $self->storage->deploy($self, undef, $sqltargs, $dir);
1c339d71 1051}
1052
0e0ce6c1 1053=head2 deployment_statements
1054
1055=over 4
1056
1057=item Arguments: $rdbms_type
1058
1059=back
1060
1061Returns the SQL statements used by L</deploy> and L<DBIx::Class::Schema/deploy>.
1062C<$rdbms_type> provides the DBI database driver name for which the SQL
1063statements are produced. If not supplied, the type of the current schema storage
1064will be used.
1065
1066=cut
1067
1068sub deployment_statements {
1069 my ($self, $rdbms_type) = @_;
1070
1071 $self->throw_exception("Can't generate deployment statements without a storage")
1072 if not $self->storage;
1073
1074 $self->storage->deployment_statements($self, $rdbms_type);
1075}
1076
c0f61310 1077=head2 create_ddl_dir (EXPERIMENTAL)
1078
1079=over 4
1080
c9d2e0a2 1081=item Arguments: \@databases, $version, $directory, $preversion, $sqlt_args
c0f61310 1082
1083=back
1084
1085Creates an SQL file based on the Schema, for each of the specified
c9d2e0a2 1086database types, in the given directory. Given a previous version number,
1087this will also create a file containing the ALTER TABLE statements to
1088transform the previous schema into the current one. Note that these
1089statements may contain DROP TABLE or DROP COLUMN statements that can
1090potentially destroy data.
1091
1092The file names are created using the C<ddl_filename> method below, please
1093override this method in your schema if you would like a different file
1094name format. For the ALTER file, the same format is used, replacing
1095$version in the name with "$preversion-$version".
1096
0e2c6809 1097See L<DBIx::Class::Schema/deploy> for details of $sqlt_args.
1098
c9d2e0a2 1099If no arguments are passed, then the following default values are used:
1100
1101=over 4
1102
1103=item databases - ['MySQL', 'SQLite', 'PostgreSQL']
1104
1105=item version - $schema->VERSION
1106
1107=item directory - './'
1108
1109=item preversion - <none>
1110
1111=back
c0f61310 1112
1113Note that this feature is currently EXPERIMENTAL and may not work correctly
1114across all databases, or fully handle complex relationships.
1115
c9d2e0a2 1116WARNING: Please check all SQL files created, before applying them.
1117
c0f61310 1118=cut
1119
6e73ac25 1120sub create_ddl_dir {
e673f011 1121 my $self = shift;
1122
1123 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1124 $self->storage->create_ddl_dir($self, @_);
1125}
1126
9b83fccd 1127=head2 ddl_filename (EXPERIMENTAL)
1128
c9d2e0a2 1129=over 4
1130
99a74c4a 1131=item Arguments: $database-type, $version, $directory, $preversion
c9d2e0a2 1132
1133=back
1134
99a74c4a 1135 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
c9d2e0a2 1136
1137This method is called by C<create_ddl_dir> to compose a file name out of
1138the supplied directory, database type and version number. The default file
1139name format is: C<$dir$schema-$version-$type.sql>.
9b83fccd 1140
c9d2e0a2 1141You may override this method in your schema if you wish to use a different
1142format.
9b83fccd 1143
1144=cut
1145
6e73ac25 1146sub ddl_filename {
99a74c4a 1147 my ($self, $type, $version, $dir, $preversion) = @_;
e673f011 1148
99a74c4a 1149 my $filename = ref($self);
1150 $filename =~ s/::/-/g;
1151 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1152 $filename =~ s/$version/$preversion-$version/ if($preversion);
1153
1154 return $filename;
e673f011 1155}
1156
d2f3e87b 1157=head2 sqlt_deploy_hook($sqlt_schema)
1158
1159An optional sub which you can declare in your own Schema class that will get
1160passed the L<SQL::Translator::Schema> object when you deploy the schema via
1161L</create_ddl_dir> or L</deploy>.
1162
1163For an example of what you can do with this, see
1164L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
1165
4146e3da 1166=head2 thaw
1167
1168Provided as the recommened way of thawing schema objects. You can call
1169C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1170reference to any schema, so are rather useless
1171
1172=cut
1173
1174sub thaw {
1175 my ($self, $obj) = @_;
1176 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1177 return Storable::thaw($obj);
1178}
1179
1180=head2 freeze
1181
1182This doesn't actualy do anything more than call L<Storable/freeze>, it is just
1183provided here for symetry.
1184
d2f3e87b 1185=cut
1186
4146e3da 1187sub freeze {
1188 return Storable::freeze($_[1]);
1189}
1190
1191=head2 dclone
1192
1193Recommeneded way of dcloning objects. This is needed to properly maintain
1194references to the schema object (which itself is B<not> cloned.)
1195
1196=cut
1197
1198sub dclone {
1199 my ($self, $obj) = @_;
1200 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1201 return Storable::dclone($obj);
1202}
1203
a02675cd 12041;
c2da098a 1205
c2da098a 1206=head1 AUTHORS
1207
daec44b8 1208Matt S. Trout <mst@shadowcatsystems.co.uk>
c2da098a 1209
1210=head1 LICENSE
1211
1212You may distribute this code under the same terms as Perl itself.
1213
1214=cut