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