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