Lazy-load as many of the non-essential modules as possible
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
CommitLineData
9c992ba1 1package DBIx::Class::ResultSource;
2
3use strict;
4use warnings;
5
6use DBIx::Class::ResultSet;
aec3eff1 7use DBIx::Class::ResultSourceHandle;
1a58752c 8
9use DBIx::Class::Exception;
701da8c4 10use Carp::Clan qw/^DBIx::Class/;
ed7ab0f4 11use Try::Tiny;
6298a324 12use List::Util 'first';
50261284 13use Scalar::Util qw/weaken isweak/;
fd323bf1 14use namespace::clean;
6da5894c 15
9c992ba1 16use base qw/DBIx::Class/;
9c992ba1 17
aa1088bf 18__PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
19 _columns _primaries _unique_constraints name resultset_attributes
4376a157 20 from _relationships column_info_from_storage source_info
f89bb832 21 source_name sqlt_deploy_callback/);
aa1088bf 22
fac560c2 23__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
b0dd0e03 24 result_class/);
9c992ba1 25
75d07914 26=head1 NAME
9c992ba1 27
28DBIx::Class::ResultSource - Result source object
29
30=head1 SYNOPSIS
31
16ccb4fe 32 # Create a table based result source, in a result class.
33
34 package MyDB::Schema::Result::Artist;
d88ecca6 35 use base qw/DBIx::Class::Core/;
16ccb4fe 36
16ccb4fe 37 __PACKAGE__->table('artist');
38 __PACKAGE__->add_columns(qw/ artistid name /);
39 __PACKAGE__->set_primary_key('artistid');
40 __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
41
42 1;
43
44 # Create a query (view) based result source, in a result class
45 package MyDB::Schema::Result::Year2000CDs;
d88ecca6 46 use base qw/DBIx::Class::Core/;
16ccb4fe 47
d88ecca6 48 __PACKAGE__->load_components('InflateColumn::DateTime');
16ccb4fe 49 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
50
51 __PACKAGE__->table('year2000cds');
52 __PACKAGE__->result_source_instance->is_virtual(1);
53 __PACKAGE__->result_source_instance->view_definition(
54 "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
55 );
56
57
9c992ba1 58=head1 DESCRIPTION
59
16ccb4fe 60A ResultSource is an object that represents a source of data for querying.
61
62This class is a base class for various specialised types of result
63sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
64default result source type, so one is created for you when defining a
65result class as described in the synopsis above.
66
d88ecca6 67More specifically, the L<DBIx::Class::Core> base class pulls in the
68L<DBIx::Class::ResultSourceProxy::Table> component, which defines
69the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
70When called, C<table> creates and stores an instance of
16ccb4fe 71L<DBIx::Class::ResultSoure::Table>. Luckily, to use tables as result
72sources, you don't need to remember any of this.
73
74Result sources representing select queries, or views, can also be
75created, see L<DBIx::Class::ResultSource::View> for full details.
76
77=head2 Finding result source objects
78
79As mentioned above, a result source instance is created and stored for
80you when you define a L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
81
82You can retrieve the result source at runtime in the following ways:
83
84=over
85
86=item From a Schema object:
87
88 $schema->source($source_name);
89
90=item From a Row object:
9c992ba1 91
16ccb4fe 92 $row->result_source;
93
94=item From a ResultSet object:
95
96 $rs->result_source;
97
98=back
00be2e0b 99
9c992ba1 100=head1 METHODS
101
7eb4ecc8 102=pod
103
9c992ba1 104=cut
105
106sub new {
107 my ($class, $attrs) = @_;
108 $class = ref $class if ref $class;
04786a4c 109
6b051e14 110 my $new = bless { %{$attrs || {}} }, $class;
9c992ba1 111 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
5ac6a044 112 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
6da5894c 113 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
114 $new->{_columns} = { %{$new->{_columns}||{}} };
115 $new->{_relationships} = { %{$new->{_relationships}||{}} };
9c992ba1 116 $new->{name} ||= "!!NAME NOT SET!!";
5afa2a15 117 $new->{_columns_info_loaded} ||= 0;
f89bb832 118 $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
9c992ba1 119 return $new;
120}
121
988bf309 122=pod
123
5ac6a044 124=head2 add_columns
125
391ccf38 126=over
127
128=item Arguments: @columns
129
130=item Return value: The ResultSource object
131
132=back
133
843f6bc1 134 $source->add_columns(qw/col1 col2 col3/);
5ac6a044 135
843f6bc1 136 $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
5ac6a044 137
16ccb4fe 138Adds columns to the result source. If supplied colname => hashref
139pairs, uses the hashref as the L</column_info> for that column. Repeated
140calls of this method will add more columns, not replace them.
5ac6a044 141
5d9d9e87 142The column names given will be created as accessor methods on your
7e51afbf 143L<DBIx::Class::Row> objects. You can change the name of the accessor
5d9d9e87 144by supplying an L</accessor> in the column_info hash.
145
157ce0cf 146If a column name beginning with a plus sign ('+col1') is provided, the
147attributes provided will be merged with any existing attributes for the
148column, with the new attributes taking precedence in the case that an
fd323bf1 149attribute already exists. Using this without a hashref
157ce0cf 150(C<< $source->add_columns(qw/+col1 +col2/) >>) is legal, but useless --
151it does the same thing it would do without the plus.
152
2053ab2a 153The contents of the column_info are not set in stone. The following
154keys are currently recognised/used by DBIx::Class:
988bf309 155
156=over 4
157
75d07914 158=item accessor
988bf309 159
16ccb4fe 160 { accessor => '_name' }
161
162 # example use, replace standard accessor with one of your own:
163 sub name {
164 my ($self, $value) = @_;
165
166 die "Name cannot contain digits!" if($value =~ /\d/);
167 $self->_name($value);
168
169 return $self->_name();
170 }
171
5d9d9e87 172Use this to set the name of the accessor method for this column. If unset,
988bf309 173the name of the column will be used.
174
175=item data_type
176
16ccb4fe 177 { data_type => 'integer' }
178
179This contains the column type. It is automatically filled if you use the
180L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
fd323bf1 181L<DBIx::Class::Schema::Loader> module.
988bf309 182
2053ab2a 183Currently there is no standard set of values for the data_type. Use
184whatever your database supports.
988bf309 185
186=item size
187
16ccb4fe 188 { size => 20 }
189
988bf309 190The length of your column, if it is a column type that can have a size
16ccb4fe 191restriction. This is currently only used to create tables from your
192schema, see L<DBIx::Class::Schema/deploy>.
988bf309 193
194=item is_nullable
195
16ccb4fe 196 { is_nullable => 1 }
197
198Set this to a true value for a columns that is allowed to contain NULL
199values, default is false. This is currently only used to create tables
200from your schema, see L<DBIx::Class::Schema/deploy>.
988bf309 201
202=item is_auto_increment
203
16ccb4fe 204 { is_auto_increment => 1 }
205
2053ab2a 206Set this to a true value for a column whose value is somehow
16ccb4fe 207automatically set, defaults to false. This is used to determine which
208columns to empty when cloning objects using
209L<DBIx::Class::Row/copy>. It is also used by
d7be2784 210L<DBIx::Class::Schema/deploy>.
988bf309 211
26a29815 212=item is_numeric
213
16ccb4fe 214 { is_numeric => 1 }
215
26a29815 216Set this to a true or false value (not C<undef>) to explicitly specify
217if this column contains numeric data. This controls how set_column
218decides whether to consider a column dirty after an update: if
0bad1823 219C<is_numeric> is true a numeric comparison C<< != >> will take place
26a29815 220instead of the usual C<eq>
221
222If not specified the storage class will attempt to figure this out on
223first access to the column, based on the column C<data_type>. The
224result will be cached in this attribute.
225
988bf309 226=item is_foreign_key
227
16ccb4fe 228 { is_foreign_key => 1 }
229
2053ab2a 230Set this to a true value for a column that contains a key from a
16ccb4fe 231foreign table, defaults to false. This is currently only used to
232create tables from your schema, see L<DBIx::Class::Schema/deploy>.
988bf309 233
234=item default_value
235
16ccb4fe 236 { default_value => \'now()' }
237
238Set this to the default value which will be inserted into a column by
239the database. Can contain either a value or a function (use a
4858fea7 240reference to a scalar e.g. C<\'now()'> if you want a function). This
16ccb4fe 241is currently only used to create tables from your schema, see
242L<DBIx::Class::Schema/deploy>.
988bf309 243
a4fcda00 244See the note on L<DBIx::Class::Row/new> for more information about possible
245issues related to db-side default values.
246
988bf309 247=item sequence
248
16ccb4fe 249 { sequence => 'my_table_seq' }
250
2053ab2a 251Set this on a primary key column to the name of the sequence used to
252generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
253will attempt to retrieve the name of the sequence from the database
254automatically.
988bf309 255
838ef78d 256=item auto_nextval
257
ca791b95 258Set this to a true value for a column whose value is retrieved automatically
259from a sequence or function (if supported by your Storage driver.) For a
260sequence, if you do not use a trigger to get the nextval, you have to set the
261L</sequence> value as well.
262
263Also set this for MSSQL columns with the 'uniqueidentifier'
e1958268 264L<data_type|DBIx::Class::ResultSource/data_type> whose values you want to
265automatically generate using C<NEWID()>, unless they are a primary key in which
266case this will be done anyway.
838ef78d 267
190615a7 268=item extra
d7be2784 269
270This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
190615a7 271to add extra non-generic data to the column. For example: C<< extra
d7be2784 272=> { unsigned => 1} >> is used by the MySQL producer to set an integer
273column to unsigned. For more details, see
274L<SQL::Translator::Producer::MySQL>.
275
988bf309 276=back
277
5ac6a044 278=head2 add_column
279
391ccf38 280=over
281
16ccb4fe 282=item Arguments: $colname, \%columninfo?
391ccf38 283
284=item Return value: 1/0 (true/false)
285
286=back
287
16ccb4fe 288 $source->add_column('col' => \%info);
5ac6a044 289
391ccf38 290Add a single column and optional column info. Uses the same column
291info keys as L</add_columns>.
5ac6a044 292
293=cut
294
9c992ba1 295sub add_columns {
296 my ($self, @cols) = @_;
8e04bf91 297 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
002a359a 298
20518cb4 299 my @added;
300 my $columns = $self->_columns;
9c992ba1 301 while (my $col = shift @cols) {
157ce0cf 302 my $column_info = {};
303 if ($col =~ s/^\+//) {
304 $column_info = $self->column_info($col);
305 }
306
8e04bf91 307 # If next entry is { ... } use that for the column info, if not
308 # use an empty hashref
157ce0cf 309 if (ref $cols[0]) {
310 my $new_info = shift(@cols);
311 %$column_info = (%$column_info, %$new_info);
312 }
20518cb4 313 push(@added, $col) unless exists $columns->{$col};
20518cb4 314 $columns->{$col} = $column_info;
9c992ba1 315 }
20518cb4 316 push @{ $self->_ordered_columns }, @added;
30126ac7 317 return $self;
9c992ba1 318}
319
b25e9fa0 320sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
9c992ba1 321
3842b955 322=head2 has_column
323
391ccf38 324=over
325
326=item Arguments: $colname
327
328=item Return value: 1/0 (true/false)
329
330=back
331
843f6bc1 332 if ($source->has_column($colname)) { ... }
988bf309 333
2053ab2a 334Returns true if the source has a column of this name, false otherwise.
988bf309 335
336=cut
9c992ba1 337
338sub has_column {
339 my ($self, $column) = @_;
340 return exists $self->_columns->{$column};
341}
342
87c4e602 343=head2 column_info
9c992ba1 344
391ccf38 345=over
346
347=item Arguments: $colname
348
349=item Return value: Hashref of info
350
351=back
352
843f6bc1 353 my $info = $source->column_info($col);
9c992ba1 354
391ccf38 355Returns the column metadata hashref for a column, as originally passed
16ccb4fe 356to L</add_columns>. See L</add_columns> above for information on the
357contents of the hashref.
9c992ba1 358
988bf309 359=cut
9c992ba1 360
361sub column_info {
362 my ($self, $column) = @_;
75d07914 363 $self->throw_exception("No such column $column")
701da8c4 364 unless exists $self->_columns->{$column};
52416317 365
75d07914 366 if ( ! $self->_columns->{$column}{data_type}
367 and ! $self->{_columns_info_loaded}
52416317 368 and $self->column_info_from_storage
4376a157 369 and my $stor = try { $self->storage } )
8e04bf91 370 {
371 $self->{_columns_info_loaded}++;
52b420dd 372
ed7ab0f4 373 # try for the case of storage without table
52b420dd 374 try {
52416317 375 my $info = $stor->columns_info_for( $self->from );
376 my $lc_info = { map
377 { (lc $_) => $info->{$_} }
378 ( keys %$info )
379 };
380
8e04bf91 381 foreach my $col ( keys %{$self->_columns} ) {
d51f93c8 382 $self->_columns->{$col} = {
383 %{ $self->_columns->{$col} },
384 %{ $info->{$col} || $lc_info->{lc $col} || {} }
385 };
a953d8d9 386 }
52b420dd 387 };
a953d8d9 388 }
52416317 389
9c992ba1 390 return $self->_columns->{$column};
391}
392
393=head2 columns
394
391ccf38 395=over
396
397=item Arguments: None
398
399=item Return value: Ordered list of column names
400
401=back
402
403 my @column_names = $source->columns;
20518cb4 404
391ccf38 405Returns all column names in the order they were declared to L</add_columns>.
87f0da6a 406
407=cut
9c992ba1 408
409sub columns {
8e04bf91 410 my $self = shift;
aa1088bf 411 $self->throw_exception(
412 "columns() is a read-only accessor, did you mean add_columns()?"
9851dada 413 ) if @_;
701da8c4 414 return @{$self->{_ordered_columns}||[]};
571dced3 415}
416
52416317 417=head2 columns_info
418
419=over
420
421=item Arguments: \@colnames ?
422
423=item Return value: Hashref of column name/info pairs
424
425=back
426
427 my $columns_info = $source->columns_info;
428
429Like L</column_info> but returns information for the requested columns. If
430the optional column-list arrayref is ommitted it returns info on all columns
431currently defined on the ResultSource via L</add_columns>.
432
433=cut
434
435sub columns_info {
436 my ($self, $columns) = @_;
437
438 my $colinfo = $self->_columns;
439
440 if (
441 first { ! $_->{data_type} } values %$colinfo
442 and
443 ! $self->{_columns_info_loaded}
444 and
445 $self->column_info_from_storage
446 and
4376a157 447 my $stor = try { $self->storage }
52416317 448 ) {
449 $self->{_columns_info_loaded}++;
450
451 # try for the case of storage without table
452 try {
453 my $info = $stor->columns_info_for( $self->from );
454 my $lc_info = { map
455 { (lc $_) => $info->{$_} }
456 ( keys %$info )
457 };
458
459 foreach my $col ( keys %$colinfo ) {
460 $colinfo->{$col} = {
461 %{ $colinfo->{$col} },
462 %{ $info->{$col} || $lc_info->{lc $col} || {} }
463 };
464 }
465 };
466 }
467
468 my %ret;
469
470 if ($columns) {
471 for (@$columns) {
472 if (my $inf = $colinfo->{$_}) {
473 $ret{$_} = $inf;
474 }
475 else {
476 $self->throw_exception( sprintf (
477 "No such column '%s' on source %s",
478 $_,
479 $self->source_name,
480 ));
481 }
482 }
483 }
484 else {
485 %ret = %$colinfo;
486 }
487
488 return \%ret;
489}
490
002a359a 491=head2 remove_columns
492
391ccf38 493=over
002a359a 494
391ccf38 495=item Arguments: @colnames
496
497=item Return value: undefined
498
499=back
500
501 $source->remove_columns(qw/col1 col2 col3/);
502
503Removes the given list of columns by name, from the result source.
504
505B<Warning>: Removing a column that is also used in the sources primary
506key, or in one of the sources unique constraints, B<will> result in a
507broken result source.
002a359a 508
509=head2 remove_column
510
391ccf38 511=over
512
513=item Arguments: $colname
514
515=item Return value: undefined
516
517=back
002a359a 518
391ccf38 519 $source->remove_column('col');
520
521Remove a single column by name from the result source, similar to
522L</remove_columns>.
523
524B<Warning>: Removing a column that is also used in the sources primary
525key, or in one of the sources unique constraints, B<will> result in a
526broken result source.
002a359a 527
528=cut
529
530sub remove_columns {
4738027b 531 my ($self, @to_remove) = @_;
002a359a 532
4738027b 533 my $columns = $self->_columns
534 or return;
002a359a 535
4738027b 536 my %to_remove;
537 for (@to_remove) {
a918d901 538 delete $columns->{$_};
4738027b 539 ++$to_remove{$_};
540 }
002a359a 541
4738027b 542 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
002a359a 543}
544
b25e9fa0 545sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
002a359a 546
87c4e602 547=head2 set_primary_key
548
27f01d1f 549=over 4
550
ebc77b53 551=item Arguments: @cols
27f01d1f 552
391ccf38 553=item Return value: undefined
554
27f01d1f 555=back
87f0da6a 556
16ccb4fe 557Defines one or more columns as primary key for this source. Must be
391ccf38 558called after L</add_columns>.
87f0da6a 559
391ccf38 560Additionally, defines a L<unique constraint|add_unique_constraint>
561named C<primary>.
87f0da6a 562
90f250bc 563Note: you normally do want to define a primary key on your sources
564B<even if the underlying database table does not have a primary key>.
565See
0c1a4a15 566L<DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
90f250bc 567for more info.
988bf309 568
87f0da6a 569=cut
9c992ba1 570
571sub set_primary_key {
572 my ($self, @cols) = @_;
573 # check if primary key columns are valid columns
8e04bf91 574 foreach my $col (@cols) {
575 $self->throw_exception("No such column $col on table " . $self->name)
576 unless $self->has_column($col);
9c992ba1 577 }
578 $self->_primaries(\@cols);
87f0da6a 579
580 $self->add_unique_constraint(primary => \@cols);
9c992ba1 581}
582
87f0da6a 583=head2 primary_columns
584
391ccf38 585=over 4
586
587=item Arguments: None
588
589=item Return value: Ordered list of primary column names
590
591=back
592
593Read-only accessor which returns the list of primary keys, supplied by
594L</set_primary_key>.
30126ac7 595
87f0da6a 596=cut
9c992ba1 597
598sub primary_columns {
599 return @{shift->_primaries||[]};
600}
601
b1d8e3fd 602# a helper method that will automatically die with a descriptive message if
603# no pk is defined on the source in question. For internal use to save
604# on if @pks... boilerplate
e8fb771b 605sub _pri_cols {
606 my $self = shift;
607 my @pcols = $self->primary_columns
608 or $self->throw_exception (sprintf(
455a33cb 609 "Operation requires a primary key to be declared on '%s' via set_primary_key",
7f505c17 610 # source_name is set only after schema-registration
611 $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
e8fb771b 612 ));
613 return @pcols;
614}
615
89170201 616=head2 sequence
617
618Manually define the correct sequence for your table, to avoid the overhead
619associated with looking up the sequence automatically. The supplied sequence
620will be applied to the L</column_info> of each L<primary_key|/set_primary_key>
621
622=over 4
623
624=item Arguments: $sequence_name
625
626=item Return value: undefined
627
628=back
629
630=cut
631
632sub sequence {
52416317 633 my ($self,$seq) = @_;
634
f70b86f9 635 my @pks = $self->primary_columns
52416317 636 or next;
637
638 $_->{sequence} = $seq
f70b86f9 639 for values %{ $self->columns_info (\@pks) };
89170201 640}
641
642
87f0da6a 643=head2 add_unique_constraint
644
391ccf38 645=over 4
646
16ccb4fe 647=item Arguments: $name?, \@colnames
391ccf38 648
649=item Return value: undefined
650
651=back
652
87f0da6a 653Declare a unique constraint on this source. Call once for each unique
58b5bb8c 654constraint.
27f01d1f 655
656 # For UNIQUE (column1, column2)
657 __PACKAGE__->add_unique_constraint(
658 constraint_name => [ qw/column1 column2/ ],
659 );
87f0da6a 660
368a5228 661Alternatively, you can specify only the columns:
662
663 __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
664
16ccb4fe 665This will result in a unique constraint named
666C<table_column1_column2>, where C<table> is replaced with the table
667name.
368a5228 668
16ccb4fe 669Unique constraints are used, for example, when you pass the constraint
670name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
671only columns in the constraint are searched.
58b5bb8c 672
391ccf38 673Throws an error if any of the given column names do not yet exist on
674the result source.
675
87f0da6a 676=cut
677
678sub add_unique_constraint {
368a5228 679 my $self = shift;
034d0be4 680
681 if (@_ > 2) {
682 $self->throw_exception(
683 'add_unique_constraint() does not accept multiple constraints, use '
684 . 'add_unique_constraints() instead'
685 );
686 }
687
368a5228 688 my $cols = pop @_;
034d0be4 689 if (ref $cols ne 'ARRAY') {
690 $self->throw_exception (
691 'Expecting an arrayref of constraint columns, got ' . ($cols||'NOTHING')
692 );
693 }
694
695 my $name = shift @_;
368a5228 696
697 $name ||= $self->name_unique_constraint($cols);
87f0da6a 698
8e04bf91 699 foreach my $col (@$cols) {
700 $self->throw_exception("No such column $col on table " . $self->name)
701 unless $self->has_column($col);
87f0da6a 702 }
703
704 my %unique_constraints = $self->unique_constraints;
705 $unique_constraints{$name} = $cols;
706 $self->_unique_constraints(\%unique_constraints);
707}
708
034d0be4 709=head2 add_unique_constraints
710
711=over 4
712
713=item Arguments: @constraints
714
715=item Return value: undefined
716
717=back
718
719Declare multiple unique constraints on this source.
720
721 __PACKAGE__->add_unique_constraints(
722 constraint_name1 => [ qw/column1 column2/ ],
723 constraint_name2 => [ qw/column2 column3/ ],
724 );
725
726Alternatively, you can specify only the columns:
727
728 __PACKAGE__->add_unique_constraints(
729 [ qw/column1 column2/ ],
730 [ qw/column3 column4/ ]
731 );
732
733This will result in unique constraints named C<table_column1_column2> and
734C<table_column3_column4>, where C<table> is replaced with the table name.
735
736Throws an error if any of the given column names do not yet exist on
737the result source.
738
739See also L</add_unique_constraint>.
740
741=cut
742
743sub add_unique_constraints {
744 my $self = shift;
745 my @constraints = @_;
746
747 if ( !(@constraints % 2) && first { ref $_ ne 'ARRAY' } @constraints ) {
748 # with constraint name
749 while (my ($name, $constraint) = splice @constraints, 0, 2) {
750 $self->add_unique_constraint($name => $constraint);
751 }
752 }
753 else {
754 # no constraint name
755 foreach my $constraint (@constraints) {
756 $self->add_unique_constraint($constraint);
757 }
758 }
759}
760
d9c74322 761=head2 name_unique_constraint
368a5228 762
391ccf38 763=over 4
764
6515609b 765=item Arguments: \@colnames
391ccf38 766
767=item Return value: Constraint name
768
769=back
770
771 $source->table('mytable');
6515609b 772 $source->name_unique_constraint(['col1', 'col2']);
391ccf38 773 # returns
774 'mytable_col1_col2'
775
776Return a name for a unique constraint containing the specified
777columns. The name is created by joining the table name and each column
778name, using an underscore character.
368a5228 779
780For example, a constraint on a table named C<cd> containing the columns
781C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
782
391ccf38 783This is used by L</add_unique_constraint> if you do not specify the
784optional constraint name.
785
368a5228 786=cut
787
788sub name_unique_constraint {
789 my ($self, $cols) = @_;
790
3e6c1131 791 my $name = $self->name;
4678e9da 792 $name = $$name if (ref $name eq 'SCALAR');
3e6c1131 793
794 return join '_', $name, @$cols;
368a5228 795}
796
87f0da6a 797=head2 unique_constraints
798
391ccf38 799=over 4
800
801=item Arguments: None
802
803=item Return value: Hash of unique constraint data
804
805=back
806
807 $source->unique_constraints();
808
16ccb4fe 809Read-only accessor which returns a hash of unique constraints on this
810source.
391ccf38 811
812The hash is keyed by constraint name, and contains an arrayref of
813column names as values.
87f0da6a 814
815=cut
816
817sub unique_constraints {
818 return %{shift->_unique_constraints||{}};
819}
820
e6a0e17c 821=head2 unique_constraint_names
822
391ccf38 823=over 4
824
825=item Arguments: None
826
827=item Return value: Unique constraint names
828
829=back
830
831 $source->unique_constraint_names();
832
e6a0e17c 833Returns the list of unique constraint names defined on this source.
834
835=cut
836
837sub unique_constraint_names {
838 my ($self) = @_;
839
840 my %unique_constraints = $self->unique_constraints;
841
842 return keys %unique_constraints;
843}
844
845=head2 unique_constraint_columns
846
391ccf38 847=over 4
848
849=item Arguments: $constraintname
850
851=item Return value: List of constraint columns
852
853=back
854
855 $source->unique_constraint_columns('myconstraint');
856
e6a0e17c 857Returns the list of columns that make up the specified unique constraint.
858
859=cut
860
861sub unique_constraint_columns {
862 my ($self, $constraint_name) = @_;
863
864 my %unique_constraints = $self->unique_constraints;
865
866 $self->throw_exception(
867 "Unknown unique constraint $constraint_name on '" . $self->name . "'"
868 ) unless exists $unique_constraints{$constraint_name};
869
870 return @{ $unique_constraints{$constraint_name} };
871}
872
880c075b 873=head2 sqlt_deploy_callback
874
875=over
876
877=item Arguments: $callback
878
879=back
880
881 __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
882
883An accessor to set a callback to be called during deployment of
884the schema via L<DBIx::Class::Schema/create_ddl_dir> or
885L<DBIx::Class::Schema/deploy>.
886
887The callback can be set as either a code reference or the name of a
888method in the current result class.
889
890If not set, the L</default_sqlt_deploy_hook> is called.
891
892Your callback will be passed the $source object representing the
893ResultSource instance being deployed, and the
894L<SQL::Translator::Schema::Table> object being created from it. The
895callback can be used to manipulate the table object or add your own
896customised indexes. If you need to manipulate a non-table object, use
897the L<DBIx::Class::Schema/sqlt_deploy_hook>.
898
899See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
900Your SQL> for examples.
901
902This sqlt deployment callback can only be used to manipulate
903SQL::Translator objects as they get turned into SQL. To execute
904post-deploy statements which SQL::Translator does not currently
905handle, override L<DBIx::Class::Schema/deploy> in your Schema class
906and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
907
908=head2 default_sqlt_deploy_hook
909
910=over
911
912=item Arguments: $source, $sqlt_table
913
914=item Return value: undefined
915
916=back
917
918This is the sensible default for L</sqlt_deploy_callback>.
919
920If a method named C<sqlt_deploy_hook> exists in your Result class, it
921will be called and passed the current C<$source> and the
922C<$sqlt_table> being deployed.
923
924=cut
925
926sub default_sqlt_deploy_hook {
927 my $self = shift;
928
929 my $class = $self->result_class;
930
931 if ($class and $class->can('sqlt_deploy_hook')) {
932 $class->sqlt_deploy_hook(@_);
933 }
934}
935
936sub _invoke_sqlt_deploy_hook {
937 my $self = shift;
938 if ( my $hook = $self->sqlt_deploy_callback) {
939 $self->$hook(@_);
940 }
941}
942
843f6bc1 943=head2 resultset
944
945=over 4
946
947=item Arguments: None
948
949=item Return value: $resultset
950
951=back
952
953Returns a resultset for the given source. This will initially be created
954on demand by calling
955
956 $self->resultset_class->new($self, $self->resultset_attributes)
957
958but is cached from then on unless resultset_class changes.
959
960=head2 resultset_class
961
962=over 4
963
964=item Arguments: $classname
965
966=item Return value: $classname
967
968=back
969
16ccb4fe 970 package My::Schema::ResultSet::Artist;
843f6bc1 971 use base 'DBIx::Class::ResultSet';
972 ...
973
16ccb4fe 974 # In the result class
975 __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
976
977 # Or in code
978 $source->resultset_class('My::Schema::ResultSet::Artist');
843f6bc1 979
7e51afbf 980Set the class of the resultset. This is useful if you want to create your
843f6bc1 981own resultset methods. Create your own class derived from
982L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
983this method returns the name of the existing resultset class, if one
984exists.
985
986=head2 resultset_attributes
987
988=over 4
989
990=item Arguments: \%attrs
991
992=item Return value: \%attrs
993
994=back
995
16ccb4fe 996 # In the result class
997 __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
998
999 # Or in code
843f6bc1 1000 $source->resultset_attributes({ order_by => [ 'id' ] });
1001
1002Store a collection of resultset attributes, that will be set on every
1003L<DBIx::Class::ResultSet> produced from this result source. For a full
1004list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
1005
1006=cut
1007
1008sub resultset {
1009 my $self = shift;
1010 $self->throw_exception(
1011 'resultset does not take any arguments. If you want another resultset, '.
1012 'call it on the schema instead.'
1013 ) if scalar @_;
1014
4376a157 1015 $self->resultset_class->new(
843f6bc1 1016 $self,
1017 {
4376a157 1018 try { %{$self->schema->default_resultset_attributes} },
843f6bc1 1019 %{$self->{resultset_attributes}},
843f6bc1 1020 },
1021 );
1022}
1023
1024=head2 source_name
1025
1026=over 4
1027
1028=item Arguments: $source_name
1029
1030=item Result value: $source_name
1031
1032=back
1033
1034Set an alternate name for the result source when it is loaded into a schema.
1035This is useful if you want to refer to a result source by a name other than
1036its class name.
1037
1038 package ArchivedBooks;
1039 use base qw/DBIx::Class/;
1040 __PACKAGE__->table('books_archive');
1041 __PACKAGE__->source_name('Books');
1042
1043 # from your schema...
1044 $schema->resultset('Books')->find(1);
1045
9c992ba1 1046=head2 from
1047
391ccf38 1048=over 4
1049
1050=item Arguments: None
1051
1052=item Return value: FROM clause
1053
1054=back
1055
1056 my $from_clause = $source->from();
1057
9c992ba1 1058Returns an expression of the source to be supplied to storage to specify
2053ab2a 1059retrieval from this source. In the case of a database, the required FROM
1060clause contents.
9c992ba1 1061
f9b7bd6e 1062=head2 schema
1063
391ccf38 1064=over 4
1065
4376a157 1066=item Arguments: $schema
391ccf38 1067
1068=item Return value: A schema object
1069
1070=back
1071
1072 my $schema = $source->schema();
1073
4376a157 1074Sets and/or returns the L<DBIx::Class::Schema> object to which this
1075result source instance has been attached to.
1076
1077=cut
1078
1079sub schema {
1080 if (@_ > 1) {
1081 $_[0]->{schema} = $_[1];
1082 }
1083 else {
1084 $_[0]->{schema} || do {
1085 my $name = $_[0]->{source_name} || '_unnamed_';
1086 my $err = 'Unable to perform storage-dependent operations with a detached result source '
1087 . "(source '$name' is not associated with a schema).";
1088
1089 $err .= ' You need to use $schema->thaw() or manually set'
1090 . ' $DBIx::Class::ResultSourceHandle::thaw_schema while thawing.'
1091 if $_[0]->{_detached_thaw};
1092
1093 DBIx::Class::Exception->throw($err);
1094 };
1095 }
1096}
9c992ba1 1097
1098=head2 storage
1099
391ccf38 1100=over 4
1101
1102=item Arguments: None
1103
1104=item Return value: A Storage object
1105
1106=back
1107
1108 $source->storage->debug(1);
1109
75d07914 1110Returns the storage handle for the current schema.
988bf309 1111
1112See also: L<DBIx::Class::Storage>
9c992ba1 1113
1114=cut
1115
1116sub storage { shift->schema->storage; }
1117
8452e496 1118=head2 add_relationship
1119
391ccf38 1120=over 4
1121
1122=item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
1123
1124=item Return value: 1/true if it succeeded
1125
1126=back
1127
8452e496 1128 $source->add_relationship('relname', 'related_source', $cond, $attrs);
1129
391ccf38 1130L<DBIx::Class::Relationship> describes a series of methods which
1131create pre-defined useful types of relationships. Look there first
1132before using this method directly.
1133
24d67825 1134The relationship name can be arbitrary, but must be unique for each
1135relationship attached to this result source. 'related_source' should
1136be the name with which the related result source was registered with
1137the current schema. For example:
8452e496 1138
24d67825 1139 $schema->source('Book')->add_relationship('reviews', 'Review', {
1140 'foreign.book_id' => 'self.id',
1141 });
1142
2053ab2a 1143The condition C<$cond> needs to be an L<SQL::Abstract>-style
24d67825 1144representation of the join between the tables. For example, if you're
391ccf38 1145creating a relation from Author to Book,
988bf309 1146
1147 { 'foreign.author_id' => 'self.id' }
1148
1149will result in the JOIN clause
1150
1151 author me JOIN book foreign ON foreign.author_id = me.id
1152
8452e496 1153You can specify as many foreign => self mappings as necessary.
1154
988bf309 1155Valid attributes are as follows:
1156
1157=over 4
1158
1159=item join_type
1160
1161Explicitly specifies the type of join to use in the relationship. Any
1162SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
1163the SQL command immediately before C<JOIN>.
1164
1165=item proxy
1166
24d67825 1167An arrayref containing a list of accessors in the foreign class to proxy in
1168the main class. If, for example, you do the following:
002a359a 1169
24d67825 1170 CD->might_have(liner_notes => 'LinerNotes', undef, {
1171 proxy => [ qw/notes/ ],
1172 });
002a359a 1173
24d67825 1174Then, assuming LinerNotes has an accessor named notes, you can do:
988bf309 1175
24d67825 1176 my $cd = CD->find(1);
2053ab2a 1177 # set notes -- LinerNotes object is created if it doesn't exist
1178 $cd->notes('Notes go here');
988bf309 1179
1180=item accessor
1181
1182Specifies the type of accessor that should be created for the
75d07914 1183relationship. Valid values are C<single> (for when there is only a single
1184related object), C<multi> (when there can be many), and C<filter> (for
1185when there is a single related object, but you also want the relationship
1186accessor to double as a column accessor). For C<multi> accessors, an
1187add_to_* method is also created, which calls C<create_related> for the
988bf309 1188relationship.
1189
8452e496 1190=back
1191
391ccf38 1192Throws an exception if the condition is improperly supplied, or cannot
6d0ee587 1193be resolved.
391ccf38 1194
8452e496 1195=cut
1196
1197sub add_relationship {
1198 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
27f01d1f 1199 $self->throw_exception("Can't create relationship without join condition")
1200 unless $cond;
8452e496 1201 $attrs ||= {};
87772e46 1202
eba322a7 1203 # Check foreign and self are right in cond
1204 if ( (ref $cond ||'') eq 'HASH') {
1205 for (keys %$cond) {
1206 $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
1207 if /\./ && !/^foreign\./;
1208 }
1209 }
1210
8452e496 1211 my %rels = %{ $self->_relationships };
1212 $rels{$rel} = { class => $f_source_name,
87772e46 1213 source => $f_source_name,
8452e496 1214 cond => $cond,
1215 attrs => $attrs };
1216 $self->_relationships(\%rels);
1217
30126ac7 1218 return $self;
87772e46 1219
52b420dd 1220# XXX disabled. doesn't work properly currently. skip in tests.
953a18ef 1221
8452e496 1222 my $f_source = $self->schema->source($f_source_name);
1223 unless ($f_source) {
c037c03a 1224 $self->ensure_class_loaded($f_source_name);
8452e496 1225 $f_source = $f_source_name->result_source;
87772e46 1226 #my $s_class = ref($self->schema);
1227 #$f_source_name =~ m/^${s_class}::(.*)$/;
1228 #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1229 #$f_source = $self->schema->source($f_source_name);
8452e496 1230 }
1231 return unless $f_source; # Can't test rel without f_source
1232
ed7ab0f4 1233 try { $self->_resolve_join($rel, 'me', {}, []) }
1234 catch {
1235 # If the resolve failed, back out and re-throw the error
52b420dd 1236 delete $rels{$rel};
8452e496 1237 $self->_relationships(\%rels);
ed7ab0f4 1238 $self->throw_exception("Error creating relationship $rel: $_");
1239 };
52b420dd 1240
8452e496 1241 1;
1242}
1243
87c4e602 1244=head2 relationships
8452e496 1245
391ccf38 1246=over 4
1247
1248=item Arguments: None
1249
1250=item Return value: List of relationship names
1251
1252=back
1253
1254 my @relnames = $source->relationships();
1255
2053ab2a 1256Returns all relationship names for this source.
8452e496 1257
1258=cut
1259
1260sub relationships {
1261 return keys %{shift->_relationships};
1262}
1263
87c4e602 1264=head2 relationship_info
1265
27f01d1f 1266=over 4
1267
ebc77b53 1268=item Arguments: $relname
27f01d1f 1269
391ccf38 1270=item Return value: Hashref of relation data,
1271
27f01d1f 1272=back
8452e496 1273
2053ab2a 1274Returns a hash of relationship information for the specified relationship
391ccf38 1275name. The keys/values are as specified for L</add_relationship>.
8452e496 1276
1277=cut
1278
1279sub relationship_info {
1280 my ($self, $rel) = @_;
1281 return $self->_relationships->{$rel};
75d07914 1282}
8452e496 1283
87c4e602 1284=head2 has_relationship
1285
27f01d1f 1286=over 4
1287
ebc77b53 1288=item Arguments: $rel
27f01d1f 1289
391ccf38 1290=item Return value: 1/0 (true/false)
1291
27f01d1f 1292=back
953a18ef 1293
2053ab2a 1294Returns true if the source has a relationship of this name, false otherwise.
988bf309 1295
1296=cut
953a18ef 1297
1298sub has_relationship {
1299 my ($self, $rel) = @_;
1300 return exists $self->_relationships->{$rel};
1301}
1302
de60a93d 1303=head2 reverse_relationship_info
1304
1305=over 4
1306
1307=item Arguments: $relname
1308
391ccf38 1309=item Return value: Hashref of relationship data
1310
de60a93d 1311=back
1312
391ccf38 1313Looks through all the relationships on the source this relationship
1314points to, looking for one whose condition is the reverse of the
1315condition on this relationship.
1316
1317A common use of this is to find the name of the C<belongs_to> relation
1318opposing a C<has_many> relation. For definition of these look in
1319L<DBIx::Class::Relationship>.
1320
1321The returned hashref is keyed by the name of the opposing
faaba25f 1322relationship, and contains its data in the same manner as
391ccf38 1323L</relationship_info>.
de60a93d 1324
1325=cut
1326
1327sub reverse_relationship_info {
1328 my ($self, $rel) = @_;
1e0daa97 1329
1330 my $rel_info = $self->relationship_info($rel)
1331 or $self->throw_exception("No such relationship '$rel'");
1332
de60a93d 1333 my $ret = {};
1334
1335 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1336
1e0daa97 1337 my $stripped_cond = $self->__strip_relcond ($rel_info->{cond});
1338
1339 my $rsrc_schema_moniker = $self->source_name
1340 if try { $self->schema };
bab77431 1341
1e0daa97 1342 # this may be a partial schema or something else equally esoteric
1343 my $other_rsrc = try { $self->related_source($rel) }
1344 or return $ret;
de60a93d 1345
1346 # Get all the relationships for that source that related to this source
1347 # whose foreign column set are our self columns on $rel and whose self
1e0daa97 1348 # columns are our foreign columns on $rel
1349 foreach my $other_rel ($other_rsrc->relationships) {
1350
1351 # only consider stuff that points back to us
1352 # "us" here is tricky - if we are in a schema registration, we want
1353 # to use the source_names, otherwise we will use the actual classes
1354
1355 # the schema may be partial
1356 my $roundtrip_rsrc = try { $other_rsrc->related_source($other_rel) }
1357 or next;
1358
1359 if ($rsrc_schema_moniker and try { $roundtrip_rsrc->schema } ) {
1360 next unless $rsrc_schema_moniker eq $roundtrip_rsrc->source_name;
1361 }
1362 else {
1363 next unless $self->result_class eq $roundtrip_rsrc->result_class;
1364 }
1365
1366 my $other_rel_info = $other_rsrc->relationship_info($other_rel);
1367
1368 # this can happen when we have a self-referential class
1369 next if $other_rel_info eq $rel_info;
1370
1371 next unless ref $other_rel_info->{cond} eq 'HASH';
1372 my $other_stripped_cond = $self->__strip_relcond($other_rel_info->{cond});
1373
1374 $ret->{$other_rel} = $other_rel_info if (
1375 $self->_compare_relationship_keys (
1376 [ keys %$stripped_cond ], [ values %$other_stripped_cond ]
1377 )
1378 and
1379 $self->_compare_relationship_keys (
1380 [ values %$stripped_cond ], [ keys %$other_stripped_cond ]
1381 )
1382 );
de60a93d 1383 }
1e0daa97 1384
de60a93d 1385 return $ret;
1386}
1387
1e0daa97 1388# all this does is removes the foreign/self prefix from a condition
1389sub __strip_relcond {
1390 +{
1391 map
1392 { map { /^ (?:foreign|self) \. (\w+) $/x } ($_, $_[1]{$_}) }
1393 keys %{$_[1]}
1394 }
1395}
1396
de60a93d 1397sub compare_relationship_keys {
6d0ee587 1398 carp 'compare_relationship_keys is a private method, stop calling it';
1399 my $self = shift;
1400 $self->_compare_relationship_keys (@_);
1401}
1402
1403# Returns true if both sets of keynames are the same, false otherwise.
1404sub _compare_relationship_keys {
5dbe74cd 1405# my ($self, $keys1, $keys2) = @_;
1406 return
1407 join ("\x00", sort @{$_[1]})
1408 eq
1409 join ("\x00", sort @{$_[2]})
1410 ;
de60a93d 1411}
1412
6d0ee587 1413# Returns the {from} structure used to express JOIN conditions
1414sub _resolve_join {
8a3fa4ae 1415 my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1979278e 1416
1417 # we need a supplied one, because we do in-place modifications, no returns
6d0ee587 1418 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
88a66388 1419 unless ref $seen eq 'HASH';
1979278e 1420
88a66388 1421 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1422 unless ref $jpath eq 'ARRAY';
1423
38f42d85 1424 $jpath = [@$jpath]; # copy
1979278e 1425
8a3fa4ae 1426 if (not defined $join) {
1427 return ();
1428 }
1429 elsif (ref $join eq 'ARRAY') {
caac1708 1430 return
1431 map {
8a3fa4ae 1432 $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
caac1708 1433 } @$join;
8a3fa4ae 1434 }
1435 elsif (ref $join eq 'HASH') {
1436
1437 my @ret;
1438 for my $rel (keys %$join) {
1439
1440 my $rel_info = $self->relationship_info($rel)
455a33cb 1441 or $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
8a3fa4ae 1442
1443 my $force_left = $parent_force_left;
1444 $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1445
1446 # the actual seen value will be incremented by the recursion
6c0230de 1447 my $as = $self->storage->relname_to_table_alias(
1448 $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1449 );
1979278e 1450
8a3fa4ae 1451 push @ret, (
1452 $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1453 $self->related_source($rel)->_resolve_join(
38f42d85 1454 $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
8a3fa4ae 1455 )
1456 );
1457 }
1458 return @ret;
096395af 1459
8a3fa4ae 1460 }
1461 elsif (ref $join) {
1462 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1463 }
1464 else {
489709af 1465 my $count = ++$seen->{$join};
6c0230de 1466 my $as = $self->storage->relname_to_table_alias(
1467 $join, ($count > 1 && $count)
1468 );
1979278e 1469
8a3fa4ae 1470 my $rel_info = $self->relationship_info($join)
455a33cb 1471 or $self->throw_exception("No such relationship $join on " . $self->source_name);
ba61fa2a 1472
1473 my $rel_src = $self->related_source($join);
1474 return [ { $as => $rel_src->from,
4376a157 1475 -rsrc => $rel_src,
8a3fa4ae 1476 -join_type => $parent_force_left
1477 ? 'left'
1478 : $rel_info->{attrs}{join_type}
1479 ,
38f42d85 1480 -join_path => [@$jpath, { $join => $as } ],
b82c8a28 1481 -is_single => (
1482 $rel_info->{attrs}{accessor}
1483 &&
6298a324 1484 first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
b82c8a28 1485 ),
ba61fa2a 1486 -alias => $as,
1979278e 1487 -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1488 },
6d0ee587 1489 $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
953a18ef 1490 }
1491}
1492
370f2ba2 1493sub pk_depends_on {
6d0ee587 1494 carp 'pk_depends_on is a private method, stop calling it';
1495 my $self = shift;
1496 $self->_pk_depends_on (@_);
1497}
1498
1499# Determines whether a relation is dependent on an object from this source
1500# having already been inserted. Takes the name of the relationship and a
1501# hashref of columns of the related object.
1502sub _pk_depends_on {
370f2ba2 1503 my ($self, $relname, $rel_data) = @_;
370f2ba2 1504
c39b48e5 1505 my $relinfo = $self->relationship_info($relname);
1506
1507 # don't assume things if the relationship direction is specified
1508 return $relinfo->{attrs}{is_foreign_key_constraint}
1509 if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1510
1511 my $cond = $relinfo->{cond};
370f2ba2 1512 return 0 unless ref($cond) eq 'HASH';
1513
1514 # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
370f2ba2 1515 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1516
1517 # assume anything that references our PK probably is dependent on us
1518 # rather than vice versa, unless the far side is (a) defined or (b)
1519 # auto-increment
370f2ba2 1520 my $rel_source = $self->related_source($relname);
1521
1522 foreach my $p ($self->primary_columns) {
1523 if (exists $keyhash->{$p}) {
1524 unless (defined($rel_data->{$keyhash->{$p}})
1525 || $rel_source->column_info($keyhash->{$p})
1526 ->{is_auto_increment}) {
1527 return 0;
1528 }
1529 }
1530 }
1531
1532 return 1;
1533}
1534
6d0ee587 1535sub resolve_condition {
1536 carp 'resolve_condition is a private method, stop calling it';
1537 my $self = shift;
1538 $self->_resolve_condition (@_);
1539}
953a18ef 1540
6d0ee587 1541# Resolves the passed condition to a concrete query fragment. If given an alias,
1542# returns a join condition; if given an object, inverts that object to produce
1543# a related conditional from that object.
8c368cf3 1544our $UNRESOLVABLE_CONDITION = \'1 = 0';
1545
6d0ee587 1546sub _resolve_condition {
489709af 1547 my ($self, $cond, $as, $for) = @_;
953a18ef 1548 if (ref $cond eq 'HASH') {
1549 my %ret;
bd054cb4 1550 foreach my $k (keys %{$cond}) {
1551 my $v = $cond->{$k};
953a18ef 1552 # XXX should probably check these are valid columns
27f01d1f 1553 $k =~ s/^foreign\.// ||
75d07914 1554 $self->throw_exception("Invalid rel cond key ${k}");
27f01d1f 1555 $v =~ s/^self\.// ||
75d07914 1556 $self->throw_exception("Invalid rel cond val ${v}");
953a18ef 1557 if (ref $for) { # Object
3842b955 1558 #warn "$self $k $for $v";
370f2ba2 1559 unless ($for->has_column_loaded($v)) {
1560 if ($for->in_storage) {
8bbfe6b2 1561 $self->throw_exception(sprintf
5c89c897 1562 "Unable to resolve relationship '%s' from object %s: column '%s' not "
1563 . 'loaded from storage (or not passed to new() prior to insert()). You '
1564 . 'probably need to call ->discard_changes to get the server-side defaults '
1565 . 'from the database.',
8bbfe6b2 1566 $as,
971beb94 1567 $for,
5c89c897 1568 $v,
a4fcda00 1569 );
370f2ba2 1570 }
68f3b0dd 1571 return $UNRESOLVABLE_CONDITION;
370f2ba2 1572 }
1573 $ret{$k} = $for->get_column($v);
1574 #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
3842b955 1575 #warn %ret;
2c037e6b 1576 } elsif (!defined $for) { # undef, i.e. "no object"
1577 $ret{$k} = undef;
2ec8e594 1578 } elsif (ref $as eq 'HASH') { # reverse hashref
1579 $ret{$v} = $as->{$k};
fde6e28e 1580 } elsif (ref $as) { # reverse object
1581 $ret{$v} = $as->get_column($k);
2c037e6b 1582 } elsif (!defined $as) { # undef, i.e. "no reverse object"
1583 $ret{$v} = undef;
953a18ef 1584 } else {
489709af 1585 $ret{"${as}.${k}"} = "${for}.${v}";
953a18ef 1586 }
953a18ef 1587 }
1588 return \%ret;
5efe4c79 1589 } elsif (ref $cond eq 'ARRAY') {
6d0ee587 1590 return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
953a18ef 1591 } else {
35c77aa3 1592 die("Can't handle condition $cond yet :(");
87772e46 1593 }
1594}
1595
988bf309 1596
6d0ee587 1597# Accepts one or more relationships for the current source and returns an
1598# array of column names for each of those relationships. Column names are
1599# prefixed relative to the current source, in accordance with where they appear
38f42d85 1600# in the supplied relationships.
b3e8ac9b 1601
6d0ee587 1602sub _resolve_prefetch {
1979278e 1603 my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1604 $pref_path ||= [];
1605
8a3fa4ae 1606 if (not defined $pre) {
1607 return ();
1608 }
1609 elsif( ref $pre eq 'ARRAY' ) {
0f66a01b 1610 return
6d0ee587 1611 map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
0f66a01b 1612 @$pre;
b3e8ac9b 1613 }
1614 elsif( ref $pre eq 'HASH' ) {
1615 my @ret =
1616 map {
6d0ee587 1617 $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1618 $self->related_source($_)->_resolve_prefetch(
1979278e 1619 $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
0f66a01b 1620 } keys %$pre;
b3e8ac9b 1621 return @ret;
1622 }
1623 elsif( ref $pre ) {
a86b1efe 1624 $self->throw_exception(
1625 "don't know how to resolve prefetch reftype ".ref($pre));
b3e8ac9b 1626 }
1627 else {
1979278e 1628 my $p = $alias_map;
1629 $p = $p->{$_} for (@$pref_path, $pre);
1630
1631 $self->throw_exception (
5e8cb53c 1632 "Unable to resolve prefetch '$pre' - join alias map does not contain an entry for path: "
1979278e 1633 . join (' -> ', @$pref_path, $pre)
1634 ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
88a66388 1635
1979278e 1636 my $as = shift @{$p->{-join_aliases}};
1637
b3e8ac9b 1638 my $rel_info = $self->relationship_info( $pre );
455a33cb 1639 $self->throw_exception( $self->source_name . " has no such relationship '$pre'" )
a86b1efe 1640 unless $rel_info;
37f23589 1641 my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
a86b1efe 1642 my $rel_source = $self->related_source($pre);
0f66a01b 1643
b82c8a28 1644 if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') {
0f66a01b 1645 $self->throw_exception(
1646 "Can't prefetch has_many ${pre} (join cond too complex)")
1647 unless ref($rel_info->{cond}) eq 'HASH';
cb136e67 1648 my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1649 if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1650 keys %{$collapse}) {
1651 my ($last) = ($fail =~ /([^\.]+)$/);
616b461d 1652 carp (
1653 "Prefetching multiple has_many rels ${last} and ${pre} "
1654 .(length($as_prefix)
1655 ? "at the same level (${as_prefix}) "
1656 : "at top level "
1657 )
2e251255 1658 . 'will explode the number of row objects retrievable via ->next or ->all. '
616b461d 1659 . 'Use at your own risk.'
1660 );
cb136e67 1661 }
b25e9fa0 1662 #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1663 # values %{$rel_info->{cond}};
b1d8e3fd 1664 $collapse->{".${as_prefix}${pre}"} = [ $rel_source->_pri_cols ];
b25e9fa0 1665 # action at a distance. prepending the '.' allows simpler code
1666 # in ResultSet->_collapse_result
37f23589 1667 my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
0f66a01b 1668 keys %{$rel_info->{cond}};
d2fcb9b3 1669 push @$order, map { "${as}.$_" } @key;
fd323bf1 1670
d2fcb9b3 1671 if (my $rel_order = $rel_info->{attrs}{order_by}) {
1672 # this is kludgy and incomplete, I am well aware
1673 # but the parent method is going away entirely anyway
1674 # so sod it
1675 my $sql_maker = $self->storage->sql_maker;
1676 my ($orig_ql, $orig_qr) = $sql_maker->_quote_chars;
1677 my $sep = $sql_maker->name_sep;
1678
1679 # install our own quoter, so we can catch unqualified stuff
1680 local $sql_maker->{quote_char} = ["\x00", "\xFF"];
1681
1682 my $quoted_prefix = "\x00${as}\xFF";
1683
1684 for my $chunk ( $sql_maker->_order_by_chunks ($rel_order) ) {
1685 my @bind;
1686 ($chunk, @bind) = @$chunk if ref $chunk;
1687
1688 $chunk = "${quoted_prefix}${sep}${chunk}"
1689 unless $chunk =~ /\Q$sep/;
1690
1691 $chunk =~ s/\x00/$orig_ql/g;
1692 $chunk =~ s/\xFF/$orig_qr/g;
1693 push @$order, \[$chunk, @bind];
1694 }
1695 }
0f66a01b 1696 }
1697
489709af 1698 return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
a86b1efe 1699 $rel_source->columns;
b3e8ac9b 1700 }
1701}
953a18ef 1702
87c4e602 1703=head2 related_source
1704
27f01d1f 1705=over 4
1706
ebc77b53 1707=item Arguments: $relname
27f01d1f 1708
391ccf38 1709=item Return value: $source
1710
27f01d1f 1711=back
87772e46 1712
2053ab2a 1713Returns the result source object for the given relationship.
87772e46 1714
1715=cut
1716
1717sub related_source {
1718 my ($self, $rel) = @_;
aea52c85 1719 if( !$self->has_relationship( $rel ) ) {
455a33cb 1720 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
aea52c85 1721 }
1e0daa97 1722
1723 # if we are not registered with a schema - just use the prototype
1724 # however if we do have a schema - ask for the source by name (and
1725 # throw in the process if all fails)
1726 if (my $schema = try { $self->schema }) {
1727 $schema->source($self->relationship_info($rel)->{source});
1728 }
1729 else {
1730 my $class = $self->relationship_info($rel)->{class};
1731 $self->ensure_class_loaded($class);
1732 $class->result_source_instance;
1733 }
8452e496 1734}
1735
77254782 1736=head2 related_class
1737
27f01d1f 1738=over 4
1739
ebc77b53 1740=item Arguments: $relname
27f01d1f 1741
391ccf38 1742=item Return value: $classname
1743
27f01d1f 1744=back
77254782 1745
2053ab2a 1746Returns the class name for objects in the given relationship.
77254782 1747
1748=cut
1749
1750sub related_class {
1751 my ($self, $rel) = @_;
1752 if( !$self->has_relationship( $rel ) ) {
455a33cb 1753 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
77254782 1754 }
1755 return $self->schema->class($self->relationship_info($rel)->{source});
1756}
1757
aec3eff1 1758=head2 handle
1759
4376a157 1760=over 4
1761
1762=item Arguments: None
1763
1764=item Return value: $source_handle
1765
1766=back
1767
1768Obtain a new L<result source handle instance|DBIx::Class::ResultSourceHandle>
1769for this source. Used as a serializable pointer to this resultsource, as it is not
1770easy (nor advisable) to serialize CODErefs which may very well be present in e.g.
1771relationship definitions.
aec3eff1 1772
1773=cut
1774
1775sub handle {
4376a157 1776 return DBIx::Class::ResultSourceHandle->new({
1777 source_moniker => $_[0]->source_name,
1778
1779 # so that a detached thaw can be re-frozen
1780 $_[0]->{_detached_thaw}
1781 ? ( _detached_source => $_[0] )
1782 : ( schema => $_[0]->schema )
1783 ,
1784 });
aec3eff1 1785}
1786
50261284 1787{
1788 my $global_phase_destroy;
1789
66917da3 1790 # SpeedyCGI runs END blocks every cycle but keeps object instances
1791 # hence we have to disable the globaldestroy hatch, and rely on the
1792 # eval trap below (which appears to work, but is risky done so late)
1793 END { $global_phase_destroy = 1 unless $CGI::SpeedyCGI::i_am_speedy }
50261284 1794
1795 sub DESTROY {
1796 return if $global_phase_destroy;
1797
1798######
1799# !!! ACHTUNG !!!!
1800######
1801#
1802# Under no circumstances shall $_[0] be stored anywhere else (like copied to
1803# a lexical variable, or shifted, or anything else). Doing so will mess up
1804# the refcount of this particular result source, and will allow the $schema
1805# we are trying to save to reattach back to the source we are destroying.
1806# The relevant code checking refcounts is in ::Schema::DESTROY()
1807
1808 # if we are not a schema instance holder - we don't matter
1809 return if(
1810 ! ref $_[0]->{schema}
1811 or
1812 isweak $_[0]->{schema}
1813 );
1814
1815 # weaken our schema hold forcing the schema to find somewhere else to live
66917da3 1816 # during global destruction (if we have not yet bailed out) this will throw
1817 # which will serve as a signal to not try doing anything else
1818 local $@;
1819 eval {
1820 weaken $_[0]->{schema};
1821 1;
1822 } or do {
1823 $global_phase_destroy = 1;
1824 return;
1825 };
1826
50261284 1827
66917da3 1828 # if schema is still there reintroduce ourselves with strong refs back to us
50261284 1829 if ($_[0]->{schema}) {
1830 my $srcregs = $_[0]->{schema}->source_registrations;
1831 for (keys %$srcregs) {
66917da3 1832 next unless $srcregs->{$_};
50261284 1833 $srcregs->{$_} = $_[0] if $srcregs->{$_} == $_[0];
1834 }
1835 }
1836 }
1837}
1838
3b80fa31 1839sub STORABLE_freeze { Storable::nfreeze($_[0]->handle) }
50261284 1840
1841sub STORABLE_thaw {
1842 my ($self, $cloning, $ice) = @_;
3b80fa31 1843 %$self = %{ (Storable::thaw($ice))->resolve };
50261284 1844}
1845
701da8c4 1846=head2 throw_exception
1847
2053ab2a 1848See L<DBIx::Class::Schema/"throw_exception">.
701da8c4 1849
1850=cut
1851
1852sub throw_exception {
1853 my $self = shift;
1a58752c 1854
4376a157 1855 $self->{schema}
1856 ? $self->{schema}->throw_exception(@_)
1857 : DBIx::Class::Exception->throw(@_)
1858 ;
701da8c4 1859}
1860
843f6bc1 1861=head2 source_info
d2f3e87b 1862
843f6bc1 1863Stores a hashref of per-source metadata. No specific key names
1864have yet been standardized, the examples below are purely hypothetical
1865and don't actually accomplish anything on their own:
391ccf38 1866
843f6bc1 1867 __PACKAGE__->source_info({
1868 "_tablespace" => 'fast_disk_array_3',
1869 "_engine" => 'InnoDB',
1870 });
391ccf38 1871
843f6bc1 1872=head2 new
391ccf38 1873
843f6bc1 1874 $class->new();
391ccf38 1875
843f6bc1 1876 $class->new({attribute_name => value});
d2f3e87b 1877
843f6bc1 1878Creates a new ResultSource object. Not normally called directly by end users.
391ccf38 1879
843f6bc1 1880=head2 column_info_from_storage
1881
1882=over
1883
1884=item Arguments: 1/0 (default: 0)
1885
1886=item Return value: 1/0
1887
1888=back
1889
880c075b 1890 __PACKAGE__->column_info_from_storage(1);
1891
843f6bc1 1892Enables the on-demand automatic loading of the above column
c1300297 1893metadata from storage as necessary. This is *deprecated*, and
843f6bc1 1894should not be used. It will be removed before 1.0.
1895
f89bb832 1896
9c992ba1 1897=head1 AUTHORS
1898
1899Matt S. Trout <mst@shadowcatsystems.co.uk>
1900
1901=head1 LICENSE
1902
1903You may distribute this code under the same terms as Perl itself.
1904
1905=cut
1906
b25e9fa0 19071;