File Coverage

blib/lib/DBIx/Class/ResultSource.pm
Criterion Covered Total %
statement 469 511 91.7
branch 233 296 78.7
condition 150 224 66.9
subroutine 66 74 89.1
pod 32 37 86.4
total 950 1142 83.1


line stmt bran cond sub pod time code
1             package DBIx::Class::ResultSource;
2              
3 379     379   296359 use strict;
  379         1327  
  379         12934  
4 379     379   2346 use warnings;
  379         1130  
  379         13273  
5              
6 379     379   2319 use base qw/DBIx::Class::ResultSource::RowParser DBIx::Class/;
  379         1131  
  379         201284  
7              
8 379     379   3469 use DBIx::Class::ResultSet;
  379         1327  
  379         9085  
9 379     379   167531 use DBIx::Class::ResultSourceHandle;
  379         1387  
  379         12398  
10              
11 379     379   3078 use DBIx::Class::Carp;
  379         1243  
  379         3279  
12 379     379   2757 use DBIx::Class::_Util 'UNRESOLVABLE_CONDITION';
  379         1385  
  379         21062  
13 379     379   3054 use SQL::Abstract 'is_literal_value';
  379         1313  
  379         21726  
14 379     379   30031 use Devel::GlobalDestruction;
  379         36291  
  379         3648  
15 379     379   27638 use Try::Tiny;
  379         1419  
  379         19970  
16 379     379   2947 use List::Util 'first';
  379         1287  
  379         22974  
17 379     379   3093 use Scalar::Util qw/blessed weaken isweak/;
  379         1388  
  379         23357  
18              
19 379     379   2738 use namespace::clean;
  379         1400  
  379         2172  
20              
21             __PACKAGE__->mk_group_accessors(simple => qw/
22             source_name name source_info
23             _ordered_columns _columns _primaries _unique_constraints
24             _relationships resultset_attributes
25             column_info_from_storage
26             /);
27              
28             __PACKAGE__->mk_group_accessors(component_class => qw/
29             resultset_class
30             result_class
31             /);
32              
33             __PACKAGE__->mk_classdata( sqlt_deploy_callback => 'default_sqlt_deploy_hook' );
34              
35             =head1 NAME
36              
37             DBIx::Class::ResultSource - Result source object
38              
39             =head1 SYNOPSIS
40              
41             # Create a table based result source, in a result class.
42              
43             package MyApp::Schema::Result::Artist;
44             use base qw/DBIx::Class::Core/;
45              
46             __PACKAGE__->table('artist');
47             __PACKAGE__->add_columns(qw/ artistid name /);
48             __PACKAGE__->set_primary_key('artistid');
49             __PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD');
50              
51             1;
52              
53             # Create a query (view) based result source, in a result class
54             package MyApp::Schema::Result::Year2000CDs;
55             use base qw/DBIx::Class::Core/;
56              
57             __PACKAGE__->load_components('InflateColumn::DateTime');
58             __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
59              
60             __PACKAGE__->table('year2000cds');
61             __PACKAGE__->result_source_instance->is_virtual(1);
62             __PACKAGE__->result_source_instance->view_definition(
63             "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
64             );
65              
66              
67             =head1 DESCRIPTION
68              
69             A ResultSource is an object that represents a source of data for querying.
70              
71             This class is a base class for various specialised types of result
72             sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
73             default result source type, so one is created for you when defining a
74             result class as described in the synopsis above.
75              
76             More specifically, the L<DBIx::Class::Core> base class pulls in the
77             L<DBIx::Class::ResultSourceProxy::Table> component, which defines
78             the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
79             When called, C<table> creates and stores an instance of
80             L<DBIx::Class::ResultSource::Table>. Luckily, to use tables as result
81             sources, you don't need to remember any of this.
82              
83             Result sources representing select queries, or views, can also be
84             created, see L<DBIx::Class::ResultSource::View> for full details.
85              
86             =head2 Finding result source objects
87              
88             As mentioned above, a result source instance is created and stored for
89             you when you define a
90             L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
91              
92             You can retrieve the result source at runtime in the following ways:
93              
94             =over
95              
96             =item From a Schema object:
97              
98             $schema->source($source_name);
99              
100             =item From a Result object:
101              
102             $result->result_source;
103              
104             =item From a ResultSet object:
105              
106             $rs->result_source;
107              
108             =back
109              
110             =head1 METHODS
111              
112             =head2 new
113              
114             $class->new();
115              
116             $class->new({attribute_name => value});
117              
118             Creates a new ResultSource object. Not normally called directly by end users.
119              
120             =cut
121              
122             sub new {
123 128900     128900 1 983406 my ($class, $attrs) = @_;
124 128900 100       306646 $class = ref $class if ref $class;
125              
126 128900 50       180535 my $new = bless { %{$attrs || {}} }, $class;
  128900         1024813  
127 128900   100     382292 $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
128 128900 100       184357 $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
  128900         365232  
129 128900 100       207720 $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
  128900         418110  
130 128900 100       188418 $new->{_columns} = { %{$new->{_columns}||{}} };
  128900         511708  
131 128900 100       208934 $new->{_relationships} = { %{$new->{_relationships}||{}} };
  128900         498207  
132 128900   50     273271 $new->{name} ||= "!!NAME NOT SET!!";
133 128900   50     486476 $new->{_columns_info_loaded} ||= 0;
134 128900         299310 return $new;
135             }
136              
137             =pod
138              
139             =head2 add_columns
140              
141             =over
142              
143             =item Arguments: @columns
144              
145             =item Return Value: L<$result_source|/new>
146              
147             =back
148              
149             $source->add_columns(qw/col1 col2 col3/);
150              
151             $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
152              
153             $source->add_columns(
154             'col1' => { data_type => 'integer', is_nullable => 1, ... },
155             'col2' => { data_type => 'text', is_auto_increment => 1, ... },
156             );
157              
158             Adds columns to the result source. If supplied colname => hashref
159             pairs, uses the hashref as the L</column_info> for that column. Repeated
160             calls of this method will add more columns, not replace them.
161              
162             The column names given will be created as accessor methods on your
163             L<Result|DBIx::Class::Manual::ResultClass> objects. You can change the name of the accessor
164             by supplying an L</accessor> in the column_info hash.
165              
166             If a column name beginning with a plus sign ('+col1') is provided, the
167             attributes provided will be merged with any existing attributes for the
168             column, with the new attributes taking precedence in the case that an
169             attribute already exists. Using this without a hashref
170             (C<< $source->add_columns(qw/+col1 +col2/) >>) is legal, but useless --
171             it does the same thing it would do without the plus.
172              
173             The contents of the column_info are not set in stone. The following
174             keys are currently recognised/used by DBIx::Class:
175              
176             =over 4
177              
178             =item accessor
179              
180             { accessor => '_name' }
181              
182             # example use, replace standard accessor with one of your own:
183             sub name {
184             my ($self, $value) = @_;
185              
186             die "Name cannot contain digits!" if($value =~ /\d/);
187             $self->_name($value);
188              
189             return $self->_name();
190             }
191              
192             Use this to set the name of the accessor method for this column. If unset,
193             the name of the column will be used.
194              
195             =item data_type
196              
197             { data_type => 'integer' }
198              
199             This contains the column type. It is automatically filled if you use the
200             L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
201             L<DBIx::Class::Schema::Loader> module.
202              
203             Currently there is no standard set of values for the data_type. Use
204             whatever your database supports.
205              
206             =item size
207              
208             { size => 20 }
209              
210             The length of your column, if it is a column type that can have a size
211             restriction. This is currently only used to create tables from your
212             schema, see L<DBIx::Class::Schema/deploy>.
213              
214             { size => [ 9, 6 ] }
215              
216             For decimal or float values you can specify an ArrayRef in order to
217             control precision, assuming your database's
218             L<SQL::Translator::Producer> supports it.
219              
220             =item is_nullable
221              
222             { is_nullable => 1 }
223              
224             Set this to a true value for a column that is allowed to contain NULL
225             values, default is false. This is currently only used to create tables
226             from your schema, see L<DBIx::Class::Schema/deploy>.
227              
228             =item is_auto_increment
229              
230             { is_auto_increment => 1 }
231              
232             Set this to a true value for a column whose value is somehow
233             automatically set, defaults to false. This is used to determine which
234             columns to empty when cloning objects using
235             L<DBIx::Class::Row/copy>. It is also used by
236             L<DBIx::Class::Schema/deploy>.
237              
238             =item is_numeric
239              
240             { is_numeric => 1 }
241              
242             Set this to a true or false value (not C<undef>) to explicitly specify
243             if this column contains numeric data. This controls how set_column
244             decides whether to consider a column dirty after an update: if
245             C<is_numeric> is true a numeric comparison C<< != >> will take place
246             instead of the usual C<eq>
247              
248             If not specified the storage class will attempt to figure this out on
249             first access to the column, based on the column C<data_type>. The
250             result will be cached in this attribute.
251              
252             =item is_foreign_key
253              
254             { is_foreign_key => 1 }
255              
256             Set this to a true value for a column that contains a key from a
257             foreign table, defaults to false. This is currently only used to
258             create tables from your schema, see L<DBIx::Class::Schema/deploy>.
259              
260             =item default_value
261              
262             { default_value => \'now()' }
263              
264             Set this to the default value which will be inserted into a column by
265             the database. Can contain either a value or a function (use a
266             reference to a scalar e.g. C<\'now()'> if you want a function). This
267             is currently only used to create tables from your schema, see
268             L<DBIx::Class::Schema/deploy>.
269              
270             See the note on L<DBIx::Class::Row/new> for more information about possible
271             issues related to db-side default values.
272              
273             =item sequence
274              
275             { sequence => 'my_table_seq' }
276              
277             Set this on a primary key column to the name of the sequence used to
278             generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
279             will attempt to retrieve the name of the sequence from the database
280             automatically.
281              
282             =item retrieve_on_insert
283              
284             { retrieve_on_insert => 1 }
285              
286             For every column where this is set to true, DBIC will retrieve the RDBMS-side
287             value upon a new row insertion (normally only the autoincrement PK is
288             retrieved on insert). C<INSERT ... RETURNING> is used automatically if
289             supported by the underlying storage, otherwise an extra SELECT statement is
290             executed to retrieve the missing data.
291              
292             =item auto_nextval
293              
294             { auto_nextval => 1 }
295              
296             Set this to a true value for a column whose value is retrieved automatically
297             from a sequence or function (if supported by your Storage driver.) For a
298             sequence, if you do not use a trigger to get the nextval, you have to set the
299             L</sequence> value as well.
300              
301             Also set this for MSSQL columns with the 'uniqueidentifier'
302             L<data_type|DBIx::Class::ResultSource/data_type> whose values you want to
303             automatically generate using C<NEWID()>, unless they are a primary key in which
304             case this will be done anyway.
305              
306             =item extra
307              
308             This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
309             to add extra non-generic data to the column. For example: C<< extra
310             => { unsigned => 1} >> is used by the MySQL producer to set an integer
311             column to unsigned. For more details, see
312             L<SQL::Translator::Producer::MySQL>.
313              
314             =back
315              
316             =head2 add_column
317              
318             =over
319              
320             =item Arguments: $colname, \%columninfo?
321              
322             =item Return Value: 1/0 (true/false)
323              
324             =back
325              
326             $source->add_column('col' => \%info);
327              
328             Add a single column and optional column info. Uses the same column
329             info keys as L</add_columns>.
330              
331             =cut
332              
333             sub add_columns {
334 14203     14203 1 39212 my ($self, @cols) = @_;
335 14203 50       49627 $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
336              
337 14203         173133 my @added;
338 14203         34033 my $columns = $self->_columns;
339 14203         173780 while (my $col = shift @cols) {
340 45410         74245 my $column_info = {};
341 45410 100       97145 if ($col =~ s/^\+//) {
342 651         2654 $column_info = $self->column_info($col);
343             }
344              
345             # If next entry is { ... } use that for the column info, if not
346             # use an empty hashref
347 45410 100       89972 if (ref $cols[0]) {
348 45372         63689 my $new_info = shift(@cols);
349 45372         162884 %$column_info = (%$column_info, %$new_info);
350             }
351 45410 100       119781 push(@added, $col) unless exists $columns->{$col};
352 45410         145455 $columns->{$col} = $column_info;
353             }
354 14203         22331 push @{ $self->_ordered_columns }, @added;
  14203         45429  
355 14203         37744 return $self;
356             }
357              
358 1     1 1 17 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
359              
360             =head2 has_column
361              
362             =over
363              
364             =item Arguments: $colname
365              
366             =item Return Value: 1/0 (true/false)
367              
368             =back
369              
370             if ($source->has_column($colname)) { ... }
371              
372             Returns true if the source has a column of this name, false otherwise.
373              
374             =cut
375              
376             sub has_column {
377 73511     73511 1 1622117 my ($self, $column) = @_;
378 73511         312525 return exists $self->_columns->{$column};
379             }
380              
381             =head2 column_info
382              
383             =over
384              
385             =item Arguments: $colname
386              
387             =item Return Value: Hashref of info
388              
389             =back
390              
391             my $info = $source->column_info($col);
392              
393             Returns the column metadata hashref for a column, as originally passed
394             to L</add_columns>. See L</add_columns> above for information on the
395             contents of the hashref.
396              
397             =cut
398              
399             sub column_info {
400 62228     62228 1 736758 my ($self, $column) = @_;
401             $self->throw_exception("No such column $column")
402 62228 50       205504 unless exists $self->_columns->{$column};
403              
404 62228 100 66     224441 if ( ! $self->_columns->{$column}{data_type}
      100        
      66        
405             and ! $self->{_columns_info_loaded}
406             and $self->column_info_from_storage
407 1     1   48 and my $stor = try { $self->storage } )
408             {
409 1         29 $self->{_columns_info_loaded}++;
410              
411             # try for the case of storage without table
412             try {
413 1     1   41 my $info = $stor->columns_info_for( $self->from );
414             my $lc_info = { map
415 1         5 { (lc $_) => $info->{$_} }
  4         13  
416             ( keys %$info )
417             };
418              
419 1         3 foreach my $col ( keys %{$self->_columns} ) {
  1         8  
420             $self->_columns->{$col} = {
421 4         13 %{ $self->_columns->{$col} },
422 4 50 33     7 %{ $info->{$col} || $lc_info->{lc $col} || {} }
  4         31  
423             };
424             }
425 1         8 };
426             }
427              
428 62228         414793 return $self->_columns->{$column};
429             }
430              
431             =head2 columns
432              
433             =over
434              
435             =item Arguments: none
436              
437             =item Return Value: Ordered list of column names
438              
439             =back
440              
441             my @column_names = $source->columns;
442              
443             Returns all column names in the order they were declared to L</add_columns>.
444              
445             =cut
446              
447             sub columns {
448 24061     24061 1 289667 my $self = shift;
449 24061 100       56072 $self->throw_exception(
450             "columns() is a read-only accessor, did you mean add_columns()?"
451             ) if @_;
452 24060 50       35253 return @{$self->{_ordered_columns}||[]};
  24060         124170  
453             }
454              
455             =head2 columns_info
456              
457             =over
458              
459             =item Arguments: \@colnames ?
460              
461             =item Return Value: Hashref of column name/info pairs
462              
463             =back
464              
465             my $columns_info = $source->columns_info;
466              
467             Like L</column_info> but returns information for the requested columns. If
468             the optional column-list arrayref is omitted it returns info on all columns
469             currently defined on the ResultSource via L</add_columns>.
470              
471             =cut
472              
473             sub columns_info {
474 47301     47301 1 98407 my ($self, $columns) = @_;
475              
476 47301         115589 my $colinfo = $self->_columns;
477              
478 47301 100 66     275496 if (
      100        
      100        
479 186475     186475   371649 first { ! $_->{data_type} } values %$colinfo
480             and
481             ! $self->{_columns_info_loaded}
482             and
483             $self->column_info_from_storage
484             and
485 3     3   158 my $stor = try { $self->storage }
486             ) {
487 1         27 $self->{_columns_info_loaded}++;
488              
489             # try for the case of storage without table
490             try {
491 1     1   41 my $info = $stor->columns_info_for( $self->from );
492             my $lc_info = { map
493 1         6 { (lc $_) => $info->{$_} }
  4         14  
494             ( keys %$info )
495             };
496              
497 1         6 foreach my $col ( keys %$colinfo ) {
498             $colinfo->{$col} = {
499 4         9 %{ $colinfo->{$col} },
500 4 50 33     8 %{ $info->{$col} || $lc_info->{lc $col} || {} }
  4         31  
501             };
502             }
503 1         9 };
504             }
505              
506 47301         141909 my %ret;
507              
508 47301 100       103374 if ($columns) {
509 21606         46409 for (@$columns) {
510 41248 100       89101 if (my $inf = $colinfo->{$_}) {
511 41247         94505 $ret{$_} = $inf;
512             }
513             else {
514 1   50     9 $self->throw_exception( sprintf (
515             "No such column '%s' on source '%s'",
516             $_,
517             $self->source_name || $self->name || 'Unknown source...?',
518             ));
519             }
520             }
521             }
522             else {
523 25695         104808 %ret = %$colinfo;
524             }
525              
526 47300         213349 return \%ret;
527             }
528              
529             =head2 remove_columns
530              
531             =over
532              
533             =item Arguments: @colnames
534              
535             =item Return Value: not defined
536              
537             =back
538              
539             $source->remove_columns(qw/col1 col2 col3/);
540              
541             Removes the given list of columns by name, from the result source.
542              
543             B<Warning>: Removing a column that is also used in the sources primary
544             key, or in one of the sources unique constraints, B<will> result in a
545             broken result source.
546              
547             =head2 remove_column
548              
549             =over
550              
551             =item Arguments: $colname
552              
553             =item Return Value: not defined
554              
555             =back
556              
557             $source->remove_column('col');
558              
559             Remove a single column by name from the result source, similar to
560             L</remove_columns>.
561              
562             B<Warning>: Removing a column that is also used in the sources primary
563             key, or in one of the sources unique constraints, B<will> result in a
564             broken result source.
565              
566             =cut
567              
568             sub remove_columns {
569 2     2 1 8 my ($self, @to_remove) = @_;
570              
571 2 50       12 my $columns = $self->_columns
572             or return;
573              
574 2         4 my %to_remove;
575 2         6 for (@to_remove) {
576 3         6 delete $columns->{$_};
577 3         8 ++$to_remove{$_};
578             }
579              
580 2         5 $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
  12         31  
  2         7  
581             }
582              
583 0     0 1 0 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
584              
585             =head2 set_primary_key
586              
587             =over 4
588              
589             =item Arguments: @cols
590              
591             =item Return Value: not defined
592              
593             =back
594              
595             Defines one or more columns as primary key for this source. Must be
596             called after L</add_columns>.
597              
598             Additionally, defines a L<unique constraint|/add_unique_constraint>
599             named C<primary>.
600              
601             Note: you normally do want to define a primary key on your sources
602             B<even if the underlying database table does not have a primary key>.
603             See
604             L<DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
605             for more info.
606              
607             =cut
608              
609             sub set_primary_key {
610 13526     13526 1 5296155 my ($self, @cols) = @_;
611              
612 13526         53526 my $colinfo = $self->columns_info(\@cols);
613 13525         27073 for my $col (@cols) {
614             carp_unique(sprintf (
615             "Primary key of source '%s' includes the column '%s' which has its "
616             . "'is_nullable' attribute set to true. This is a mistake and will cause "
617             . 'various Result-object operations to fail',
618             $self->source_name || $self->name || 'Unknown source...?',
619             $col,
620 18727 100 50     47468 )) if $colinfo->{$col}{is_nullable};
621             }
622              
623 13525         47932 $self->_primaries(\@cols);
624              
625 13525         205470 $self->add_unique_constraint(primary => \@cols);
626             }
627              
628             =head2 primary_columns
629              
630             =over 4
631              
632             =item Arguments: none
633              
634             =item Return Value: Ordered list of primary column names
635              
636             =back
637              
638             Read-only accessor which returns the list of primary keys, supplied by
639             L</set_primary_key>.
640              
641             =cut
642              
643             sub primary_columns {
644 26136 100   26136 1 40180 return @{shift->_primaries||[]};
  26136         137301  
645             }
646              
647             # a helper method that will automatically die with a descriptive message if
648             # no pk is defined on the source in question. For internal use to save
649             # on if @pks... boilerplate
650             sub _pri_cols_or_die {
651 21778     21778   35343 my $self = shift;
652 21778 100 0     51359 my @pcols = $self->primary_columns
653             or $self->throw_exception (sprintf(
654             "Operation requires a primary key to be declared on '%s' via set_primary_key",
655             # source_name is set only after schema-registration
656             $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
657             ));
658 21776         58197 return @pcols;
659             }
660              
661             # same as above but mandating single-column PK (used by relationship condition
662             # inference)
663             sub _single_pri_col_or_die {
664 18516     18516   199127 my $self = shift;
665 18516         49187 my ($pri, @too_many) = $self->_pri_cols_or_die;
666              
667 18516 50 0     43793 $self->throw_exception( sprintf(
668             "Operation requires a single-column primary key declared on '%s'",
669             $self->source_name || $self->result_class || $self->name || 'Unknown source...?',
670             )) if @too_many;
671 18516         47694 return $pri;
672             }
673              
674              
675             =head2 sequence
676              
677             Manually define the correct sequence for your table, to avoid the overhead
678             associated with looking up the sequence automatically. The supplied sequence
679             will be applied to the L</column_info> of each L<primary_key|/set_primary_key>
680              
681             =over 4
682              
683             =item Arguments: $sequence_name
684              
685             =item Return Value: not defined
686              
687             =back
688              
689             =cut
690              
691             sub sequence {
692 325     325 1 238026 my ($self,$seq) = @_;
693              
694 325 50       2007 my @pks = $self->primary_columns
695             or return;
696              
697             $_->{sequence} = $seq
698 325         1028 for values %{ $self->columns_info (\@pks) };
  325         1469  
699             }
700              
701              
702             =head2 add_unique_constraint
703              
704             =over 4
705              
706             =item Arguments: $name?, \@colnames
707              
708             =item Return Value: not defined
709              
710             =back
711              
712             Declare a unique constraint on this source. Call once for each unique
713             constraint.
714              
715             # For UNIQUE (column1, column2)
716             __PACKAGE__->add_unique_constraint(
717             constraint_name => [ qw/column1 column2/ ],
718             );
719              
720             Alternatively, you can specify only the columns:
721              
722             __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
723              
724             This will result in a unique constraint named
725             C<table_column1_column2>, where C<table> is replaced with the table
726             name.
727              
728             Unique constraints are used, for example, when you pass the constraint
729             name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
730             only columns in the constraint are searched.
731              
732             Throws an error if any of the given column names do not yet exist on
733             the result source.
734              
735             =cut
736              
737             sub add_unique_constraint {
738 19561     19561 1 691823 my $self = shift;
739              
740 19561 100       46092 if (@_ > 2) {
741 1         5 $self->throw_exception(
742             'add_unique_constraint() does not accept multiple constraints, use '
743             . 'add_unique_constraints() instead'
744             );
745             }
746              
747 19560         31523 my $cols = pop @_;
748 19560 50       48708 if (ref $cols ne 'ARRAY') {
749 0   0     0 $self->throw_exception (
750             'Expecting an arrayref of constraint columns, got ' . ($cols||'NOTHING')
751             );
752             }
753              
754 19560         32535 my $name = shift @_;
755              
756 19560   66     52793 $name ||= $self->name_unique_constraint($cols);
757              
758 19560         35997 foreach my $col (@$cols) {
759 29023 50       68841 $self->throw_exception("No such column $col on table " . $self->name)
760             unless $self->has_column($col);
761             }
762              
763 19560         55186 my %unique_constraints = $self->unique_constraints;
764 19560         204229 $unique_constraints{$name} = $cols;
765 19560         86253 $self->_unique_constraints(\%unique_constraints);
766             }
767              
768             =head2 add_unique_constraints
769              
770             =over 4
771              
772             =item Arguments: @constraints
773              
774             =item Return Value: not defined
775              
776             =back
777              
778             Declare multiple unique constraints on this source.
779              
780             __PACKAGE__->add_unique_constraints(
781             constraint_name1 => [ qw/column1 column2/ ],
782             constraint_name2 => [ qw/column2 column3/ ],
783             );
784              
785             Alternatively, you can specify only the columns:
786              
787             __PACKAGE__->add_unique_constraints(
788             [ qw/column1 column2/ ],
789             [ qw/column3 column4/ ]
790             );
791              
792             This will result in unique constraints named C<table_column1_column2> and
793             C<table_column3_column4>, where C<table> is replaced with the table name.
794              
795             Throws an error if any of the given column names do not yet exist on
796             the result source.
797              
798             See also L</add_unique_constraint>.
799              
800             =cut
801              
802             sub add_unique_constraints {
803 650     650 1 237822 my $self = shift;
804 650         2131 my @constraints = @_;
805              
806 650 100 66 975   5968 if ( !(@constraints % 2) && first { ref $_ ne 'ARRAY' } @constraints ) {
  975         4245  
807             # with constraint name
808 325         2311 while (my ($name, $constraint) = splice @constraints, 0, 2) {
809 650         1863 $self->add_unique_constraint($name => $constraint);
810             }
811             }
812             else {
813             # no constraint name
814 325         1406 foreach my $constraint (@constraints) {
815 650         1757 $self->add_unique_constraint($constraint);
816             }
817             }
818             }
819              
820             =head2 name_unique_constraint
821              
822             =over 4
823              
824             =item Arguments: \@colnames
825              
826             =item Return Value: Constraint name
827              
828             =back
829              
830             $source->table('mytable');
831             $source->name_unique_constraint(['col1', 'col2']);
832             # returns
833             'mytable_col1_col2'
834              
835             Return a name for a unique constraint containing the specified
836             columns. The name is created by joining the table name and each column
837             name, using an underscore character.
838              
839             For example, a constraint on a table named C<cd> containing the columns
840             C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
841              
842             This is used by L</add_unique_constraint> if you do not specify the
843             optional constraint name.
844              
845             =cut
846              
847             sub name_unique_constraint {
848 3387     3387 1 8536 my ($self, $cols) = @_;
849              
850 3387         8643 my $name = $self->name;
851 3387 100       9436 $name = $$name if (ref $name eq 'SCALAR');
852 3387         7785 $name =~ s/ ^ [^\.]+ \. //x; # strip possible schema qualifier
853              
854 3387         16957 return join '_', $name, @$cols;
855             }
856              
857             =head2 unique_constraints
858              
859             =over 4
860              
861             =item Arguments: none
862              
863             =item Return Value: Hash of unique constraint data
864              
865             =back
866              
867             $source->unique_constraints();
868              
869             Read-only accessor which returns a hash of unique constraints on this
870             source.
871              
872             The hash is keyed by constraint name, and contains an arrayref of
873             column names as values.
874              
875             =cut
876              
877             sub unique_constraints {
878 30566 100   30566 1 44616 return %{shift->_unique_constraints||{}};
  30566         189000  
879             }
880              
881             =head2 unique_constraint_names
882              
883             =over 4
884              
885             =item Arguments: none
886              
887             =item Return Value: Unique constraint names
888              
889             =back
890              
891             $source->unique_constraint_names();
892              
893             Returns the list of unique constraint names defined on this source.
894              
895             =cut
896              
897             sub unique_constraint_names {
898 1158     1158 1 3058 my ($self) = @_;
899              
900 1158         3892 my %unique_constraints = $self->unique_constraints;
901              
902 1158         8561 return keys %unique_constraints;
903             }
904              
905             =head2 unique_constraint_columns
906              
907             =over 4
908              
909             =item Arguments: $constraintname
910              
911             =item Return Value: List of constraint columns
912              
913             =back
914              
915             $source->unique_constraint_columns('myconstraint');
916              
917             Returns the list of columns that make up the specified unique constraint.
918              
919             =cut
920              
921             sub unique_constraint_columns {
922 7330     7330 1 14934 my ($self, $constraint_name) = @_;
923              
924 7330         15367 my %unique_constraints = $self->unique_constraints;
925              
926             $self->throw_exception(
927             "Unknown unique constraint $constraint_name on '" . $self->name . "'"
928 7330 50       20229 ) unless exists $unique_constraints{$constraint_name};
929              
930 7330         10832 return @{ $unique_constraints{$constraint_name} };
  7330         34687  
931             }
932              
933             =head2 sqlt_deploy_callback
934              
935             =over
936              
937             =item Arguments: $callback_name | \&callback_code
938              
939             =item Return Value: $callback_name | \&callback_code
940              
941             =back
942              
943             __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
944              
945             or
946              
947             __PACKAGE__->sqlt_deploy_callback(sub {
948             my ($source_instance, $sqlt_table) = @_;
949             ...
950             } );
951              
952             An accessor to set a callback to be called during deployment of
953             the schema via L<DBIx::Class::Schema/create_ddl_dir> or
954             L<DBIx::Class::Schema/deploy>.
955              
956             The callback can be set as either a code reference or the name of a
957             method in the current result class.
958              
959             Defaults to L</default_sqlt_deploy_hook>.
960              
961             Your callback will be passed the $source object representing the
962             ResultSource instance being deployed, and the
963             L<SQL::Translator::Schema::Table> object being created from it. The
964             callback can be used to manipulate the table object or add your own
965             customised indexes. If you need to manipulate a non-table object, use
966             the L<DBIx::Class::Schema/sqlt_deploy_hook>.
967              
968             See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
969             Your SQL> for examples.
970              
971             This sqlt deployment callback can only be used to manipulate
972             SQL::Translator objects as they get turned into SQL. To execute
973             post-deploy statements which SQL::Translator does not currently
974             handle, override L<DBIx::Class::Schema/deploy> in your Schema class
975             and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
976              
977             =head2 default_sqlt_deploy_hook
978              
979             This is the default deploy hook implementation which checks if your
980             current Result class has a C<sqlt_deploy_hook> method, and if present
981             invokes it B<on the Result class directly>. This is to preserve the
982             semantics of C<sqlt_deploy_hook> which was originally designed to expect
983             the Result class name and the
984             L<$sqlt_table instance|SQL::Translator::Schema::Table> of the table being
985             deployed.
986              
987             =cut
988              
989             sub default_sqlt_deploy_hook {
990 886     886 1 4901 my $self = shift;
991              
992 886         17419 my $class = $self->result_class;
993              
994 886 100 66     14582 if ($class and $class->can('sqlt_deploy_hook')) {
995 85         482 $class->sqlt_deploy_hook(@_);
996             }
997             }
998              
999             sub _invoke_sqlt_deploy_hook {
1000 886     886   1530 my $self = shift;
1001 886 50       17177 if ( my $hook = $self->sqlt_deploy_callback) {
1002 886         39453 $self->$hook(@_);
1003             }
1004             }
1005              
1006             =head2 result_class
1007              
1008             =over 4
1009              
1010             =item Arguments: $classname
1011              
1012             =item Return Value: $classname
1013              
1014             =back
1015              
1016             use My::Schema::ResultClass::Inflator;
1017             ...
1018              
1019             use My::Schema::Artist;
1020             ...
1021             __PACKAGE__->result_class('My::Schema::ResultClass::Inflator');
1022              
1023             Set the default result class for this source. You can use this to create
1024             and use your own result inflator. See L<DBIx::Class::ResultSet/result_class>
1025             for more details.
1026              
1027             Please note that setting this to something like
1028             L<DBIx::Class::ResultClass::HashRefInflator> will make every result unblessed
1029             and make life more difficult. Inflators like those are better suited to
1030             temporary usage via L<DBIx::Class::ResultSet/result_class>.
1031              
1032             =head2 resultset
1033              
1034             =over 4
1035              
1036             =item Arguments: none
1037              
1038             =item Return Value: L<$resultset|DBIx::Class::ResultSet>
1039              
1040             =back
1041              
1042             Returns a resultset for the given source. This will initially be created
1043             on demand by calling
1044              
1045             $self->resultset_class->new($self, $self->resultset_attributes)
1046              
1047             but is cached from then on unless resultset_class changes.
1048              
1049             =head2 resultset_class
1050              
1051             =over 4
1052              
1053             =item Arguments: $classname
1054              
1055             =item Return Value: $classname
1056              
1057             =back
1058              
1059             package My::Schema::ResultSet::Artist;
1060             use base 'DBIx::Class::ResultSet';
1061             ...
1062              
1063             # In the result class
1064             __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
1065              
1066             # Or in code
1067             $source->resultset_class('My::Schema::ResultSet::Artist');
1068              
1069             Set the class of the resultset. This is useful if you want to create your
1070             own resultset methods. Create your own class derived from
1071             L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
1072             this method returns the name of the existing resultset class, if one
1073             exists.
1074              
1075             =head2 resultset_attributes
1076              
1077             =over 4
1078              
1079             =item Arguments: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
1080              
1081             =item Return Value: L<\%attrs|DBIx::Class::ResultSet/ATTRIBUTES>
1082              
1083             =back
1084              
1085             # In the result class
1086             __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
1087              
1088             # Or in code
1089             $source->resultset_attributes({ order_by => [ 'id' ] });
1090              
1091             Store a collection of resultset attributes, that will be set on every
1092             L<DBIx::Class::ResultSet> produced from this result source.
1093              
1094             B<CAVEAT>: C<resultset_attributes> comes with its own set of issues and
1095             bugs! While C<resultset_attributes> isn't deprecated per se, its usage is
1096             not recommended!
1097              
1098             Since relationships use attributes to link tables together, the "default"
1099             attributes you set may cause unpredictable and undesired behavior. Furthermore,
1100             the defaults cannot be turned off, so you are stuck with them.
1101              
1102             In most cases, what you should actually be using are project-specific methods:
1103              
1104             package My::Schema::ResultSet::Artist;
1105             use base 'DBIx::Class::ResultSet';
1106             ...
1107              
1108             # BAD IDEA!
1109             #__PACKAGE__->resultset_attributes({ prefetch => 'tracks' });
1110              
1111             # GOOD IDEA!
1112             sub with_tracks { shift->search({}, { prefetch => 'tracks' }) }
1113              
1114             # in your code
1115             $schema->resultset('Artist')->with_tracks->...
1116              
1117             This gives you the flexibility of not using it when you don't need it.
1118              
1119             For more complex situations, another solution would be to use a virtual view
1120             via L<DBIx::Class::ResultSource::View>.
1121              
1122             =cut
1123              
1124             sub resultset {
1125 14759     14759 1 31143 my $self = shift;
1126 14759 50       37668 $self->throw_exception(
1127             'resultset does not take any arguments. If you want another resultset, '.
1128             'call it on the schema instead.'
1129             ) if scalar @_;
1130              
1131             $self->resultset_class->new(
1132             $self,
1133             {
1134 14759     14759   543803 try { %{$self->schema->default_resultset_attributes} },
  14759         43800  
1135 14759         303294 %{$self->{resultset_attributes}},
  14759         1022367  
1136             },
1137             );
1138             }
1139              
1140             =head2 name
1141              
1142             =over 4
1143              
1144             =item Arguments: none
1145              
1146             =item Result value: $name
1147              
1148             =back
1149              
1150             Returns the name of the result source, which will typically be the table
1151             name. This may be a scalar reference if the result source has a non-standard
1152             name.
1153              
1154             =head2 source_name
1155              
1156             =over 4
1157              
1158             =item Arguments: $source_name
1159              
1160             =item Result value: $source_name
1161              
1162             =back
1163              
1164             Set an alternate name for the result source when it is loaded into a schema.
1165             This is useful if you want to refer to a result source by a name other than
1166             its class name.
1167              
1168             package ArchivedBooks;
1169             use base qw/DBIx::Class/;
1170             __PACKAGE__->table('books_archive');
1171             __PACKAGE__->source_name('Books');
1172              
1173             # from your schema...
1174             $schema->resultset('Books')->find(1);
1175              
1176             =head2 from
1177              
1178             =over 4
1179              
1180             =item Arguments: none
1181              
1182             =item Return Value: FROM clause
1183              
1184             =back
1185              
1186             my $from_clause = $source->from();
1187              
1188             Returns an expression of the source to be supplied to storage to specify
1189             retrieval from this source. In the case of a database, the required FROM
1190             clause contents.
1191              
1192             =cut
1193              
1194 0     0 1 0 sub from { die 'Virtual method!' }
1195              
1196             =head2 source_info
1197              
1198             Stores a hashref of per-source metadata. No specific key names
1199             have yet been standardized, the examples below are purely hypothetical
1200             and don't actually accomplish anything on their own:
1201              
1202             __PACKAGE__->source_info({
1203             "_tablespace" => 'fast_disk_array_3',
1204             "_engine" => 'InnoDB',
1205             });
1206              
1207             =head2 schema
1208              
1209             =over 4
1210              
1211             =item Arguments: L<$schema?|DBIx::Class::Schema>
1212              
1213             =item Return Value: L<$schema|DBIx::Class::Schema>
1214              
1215             =back
1216              
1217             my $schema = $source->schema();
1218              
1219             Sets and/or returns the L<DBIx::Class::Schema> object to which this
1220             result source instance has been attached to.
1221              
1222             =cut
1223              
1224             sub schema {
1225 159237 100   159237 1 377490 if (@_ > 1) {
1226 73836         162133 $_[0]->{schema} = $_[1];
1227             }
1228             else {
1229 85401 100       1467349 $_[0]->{schema} || do {
1230 88   100     271 my $name = $_[0]->{source_name} || '_unnamed_';
1231 88         219 my $err = 'Unable to perform storage-dependent operations with a detached result source '
1232             . "(source '$name' is not associated with a schema).";
1233              
1234             $err .= ' You need to use $schema->thaw() or manually set'
1235             . ' $DBIx::Class::ResultSourceHandle::thaw_schema while thawing.'
1236 88 100       226 if $_[0]->{_detached_thaw};
1237              
1238 88         350 DBIx::Class::Exception->throw($err);
1239             };
1240             }
1241             }
1242              
1243             =head2 storage
1244              
1245             =over 4
1246              
1247             =item Arguments: none
1248              
1249             =item Return Value: L<$storage|DBIx::Class::Storage>
1250              
1251             =back
1252              
1253             $source->storage->debug(1);
1254              
1255             Returns the L<storage handle|DBIx::Class::Storage> for the current schema.
1256              
1257             =cut
1258              
1259 23616     23616 1 58223 sub storage { shift->schema->storage; }
1260              
1261             =head2 add_relationship
1262              
1263             =over 4
1264              
1265             =item Arguments: $rel_name, $related_source_name, \%cond, \%attrs?
1266              
1267             =item Return Value: 1/true if it succeeded
1268              
1269             =back
1270              
1271             $source->add_relationship('rel_name', 'related_source', $cond, $attrs);
1272              
1273             L<DBIx::Class::Relationship> describes a series of methods which
1274             create pre-defined useful types of relationships. Look there first
1275             before using this method directly.
1276              
1277             The relationship name can be arbitrary, but must be unique for each
1278             relationship attached to this result source. 'related_source' should
1279             be the name with which the related result source was registered with
1280             the current schema. For example:
1281              
1282             $schema->source('Book')->add_relationship('reviews', 'Review', {
1283             'foreign.book_id' => 'self.id',
1284             });
1285              
1286             The condition C<$cond> needs to be an L<SQL::Abstract>-style
1287             representation of the join between the tables. For example, if you're
1288             creating a relation from Author to Book,
1289              
1290             { 'foreign.author_id' => 'self.id' }
1291              
1292             will result in the JOIN clause
1293              
1294             author me JOIN book foreign ON foreign.author_id = me.id
1295              
1296             You can specify as many foreign => self mappings as necessary.
1297              
1298             Valid attributes are as follows:
1299              
1300             =over 4
1301              
1302             =item join_type
1303              
1304             Explicitly specifies the type of join to use in the relationship. Any
1305             SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
1306             the SQL command immediately before C<JOIN>.
1307              
1308             =item proxy
1309              
1310             An arrayref containing a list of accessors in the foreign class to proxy in
1311             the main class. If, for example, you do the following:
1312              
1313             CD->might_have(liner_notes => 'LinerNotes', undef, {
1314             proxy => [ qw/notes/ ],
1315             });
1316              
1317             Then, assuming LinerNotes has an accessor named notes, you can do:
1318              
1319             my $cd = CD->find(1);
1320             # set notes -- LinerNotes object is created if it doesn't exist
1321             $cd->notes('Notes go here');
1322              
1323             =item accessor
1324              
1325             Specifies the type of accessor that should be created for the
1326             relationship. Valid values are C<single> (for when there is only a single
1327             related object), C<multi> (when there can be many), and C<filter> (for
1328             when there is a single related object, but you also want the relationship
1329             accessor to double as a column accessor). For C<multi> accessors, an
1330             add_to_* method is also created, which calls C<create_related> for the
1331             relationship.
1332              
1333             =back
1334              
1335             Throws an exception if the condition is improperly supplied, or cannot
1336             be resolved.
1337              
1338             =cut
1339              
1340             sub add_relationship {
1341 29096     29096 1 68035 my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
1342 29096 100       65743 $self->throw_exception("Can't create relationship without join condition")
1343             unless $cond;
1344 29095   100     59740 $attrs ||= {};
1345              
1346             # Check foreign and self are right in cond
1347 29095 100 50     86690 if ( (ref $cond ||'') eq 'HASH') {
1348             $_ =~ /^foreign\./ or $self->throw_exception("Malformed relationship condition key '$_': must be prefixed with 'foreign.'")
1349 24081   66     125197 for keys %$cond;
1350              
1351             $_ =~ /^self\./ or $self->throw_exception("Malformed relationship condition value '$_': must be prefixed with 'self.'")
1352 24078   66     97787 for values %$cond;
1353             }
1354              
1355 29088         45253 my %rels = %{ $self->_relationships };
  29088         153380  
1356 29088         318033 $rels{$rel} = { class => $f_source_name,
1357             source => $f_source_name,
1358             cond => $cond,
1359             attrs => $attrs };
1360 29088         97932 $self->_relationships(\%rels);
1361              
1362 29088         75715 return $self;
1363              
1364             # XXX disabled. doesn't work properly currently. skip in tests.
1365              
1366 0         0 my $f_source = $self->schema->source($f_source_name);
1367 0 0       0 unless ($f_source) {
1368 0         0 $self->ensure_class_loaded($f_source_name);
1369 0         0 $f_source = $f_source_name->result_source;
1370             #my $s_class = ref($self->schema);
1371             #$f_source_name =~ m/^${s_class}::(.*)$/;
1372             #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1373             #$f_source = $self->schema->source($f_source_name);
1374             }
1375 0 0       0 return unless $f_source; # Can't test rel without f_source
1376              
1377 0     0   0 try { $self->_resolve_join($rel, 'me', {}, []) }
1378             catch {
1379             # If the resolve failed, back out and re-throw the error
1380 0     0   0 delete $rels{$rel};
1381 0         0 $self->_relationships(\%rels);
1382 0         0 $self->throw_exception("Error creating relationship $rel: $_");
1383 0         0 };
1384              
1385 0         0 1;
1386             }
1387              
1388             =head2 relationships
1389              
1390             =over 4
1391              
1392             =item Arguments: none
1393              
1394             =item Return Value: L<@rel_names|DBIx::Class::Relationship>
1395              
1396             =back
1397              
1398             my @rel_names = $source->relationships();
1399              
1400             Returns all relationship names for this source.
1401              
1402             =cut
1403              
1404             sub relationships {
1405 12066     12066 1 21402 return keys %{shift->_relationships};
  12066         80446  
1406             }
1407              
1408             =head2 relationship_info
1409              
1410             =over 4
1411              
1412             =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1413              
1414             =item Return Value: L<\%rel_data|DBIx::Class::Relationship::Base/add_relationship>
1415              
1416             =back
1417              
1418             Returns a hash of relationship information for the specified relationship
1419             name. The keys/values are as specified for L<DBIx::Class::Relationship::Base/add_relationship>.
1420              
1421             =cut
1422              
1423             sub relationship_info {
1424             #my ($self, $rel) = @_;
1425 115021     115021 1 870535 return shift->_relationships->{+shift};
1426             }
1427              
1428             =head2 has_relationship
1429              
1430             =over 4
1431              
1432             =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1433              
1434             =item Return Value: 1/0 (true/false)
1435              
1436             =back
1437              
1438             Returns true if the source has a relationship of this name, false otherwise.
1439              
1440             =cut
1441              
1442             sub has_relationship {
1443             #my ($self, $rel) = @_;
1444 29731     29731 1 98357 return exists shift->_relationships->{+shift};
1445             }
1446              
1447             =head2 reverse_relationship_info
1448              
1449             =over 4
1450              
1451             =item Arguments: L<$rel_name|DBIx::Class::Relationship>
1452              
1453             =item Return Value: L<\%rel_data|DBIx::Class::Relationship::Base/add_relationship>
1454              
1455             =back
1456              
1457             Looks through all the relationships on the source this relationship
1458             points to, looking for one whose condition is the reverse of the
1459             condition on this relationship.
1460              
1461             A common use of this is to find the name of the C<belongs_to> relation
1462             opposing a C<has_many> relation. For definition of these look in
1463             L<DBIx::Class::Relationship>.
1464              
1465             The returned hashref is keyed by the name of the opposing
1466             relationship, and contains its data in the same manner as
1467             L</relationship_info>.
1468              
1469             =cut
1470              
1471             sub reverse_relationship_info {
1472 2474     2474 1 5701 my ($self, $rel) = @_;
1473              
1474 2474 50       6012 my $rel_info = $self->relationship_info($rel)
1475             or $self->throw_exception("No such relationship '$rel'");
1476              
1477 2474         5327 my $ret = {};
1478              
1479 2474 100       7492 return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1480              
1481 2473         6746 my $stripped_cond = $self->__strip_relcond ($rel_info->{cond});
1482              
1483 2473         7393 my $registered_source_name = $self->source_name;
1484              
1485             # this may be a partial schema or something else equally esoteric
1486 2473         11539 my $other_rsrc = $self->related_source($rel);
1487              
1488             # Get all the relationships for that source that related to this source
1489             # whose foreign column set are our self columns on $rel and whose self
1490             # columns are our foreign columns on $rel
1491 2473         12902 foreach my $other_rel ($other_rsrc->relationships) {
1492              
1493             # only consider stuff that points back to us
1494             # "us" here is tricky - if we are in a schema registration, we want
1495             # to use the source_names, otherwise we will use the actual classes
1496              
1497             # the schema may be partial
1498 18389     18389   718938 my $roundtrip_rsrc = try { $other_rsrc->related_source($other_rel) }
1499 18389 100       86337 or next;
1500              
1501 18340 100       213931 if ($registered_source_name) {
1502 18326 100 50     76939 next if $registered_source_name ne ($roundtrip_rsrc->source_name || '')
1503             }
1504             else {
1505 14 100       270 next if $self->result_class ne $roundtrip_rsrc->result_class;
1506             }
1507              
1508 5374         11614 my $other_rel_info = $other_rsrc->relationship_info($other_rel);
1509              
1510             # this can happen when we have a self-referential class
1511 5374 100       15678 next if $other_rel_info eq $rel_info;
1512              
1513 5304 100       16874 next unless ref $other_rel_info->{cond} eq 'HASH';
1514 3872         8575 my $other_stripped_cond = $self->__strip_relcond($other_rel_info->{cond});
1515              
1516 3872 100 100     18990 $ret->{$other_rel} = $other_rel_info if (
1517             $self->_compare_relationship_keys (
1518             [ keys %$stripped_cond ], [ values %$other_stripped_cond ]
1519             )
1520             and
1521             $self->_compare_relationship_keys (
1522             [ values %$stripped_cond ], [ keys %$other_stripped_cond ]
1523             )
1524             );
1525             }
1526              
1527 2473         14080 return $ret;
1528             }
1529              
1530             # all this does is removes the foreign/self prefix from a condition
1531             sub __strip_relcond {
1532             +{
1533             map
1534 6702         12616 { map { /^ (?:foreign|self) \. (\w+) $/x } ($_, $_[1]{$_}) }
  13404         63268  
1535 6345     6345   9273 keys %{$_[1]}
  6345         19131  
1536             }
1537             }
1538              
1539             sub compare_relationship_keys {
1540 0     0 0 0 carp 'compare_relationship_keys is a private method, stop calling it';
1541 0         0 my $self = shift;
1542 0         0 $self->_compare_relationship_keys (@_);
1543             }
1544              
1545             # Returns true if both sets of keynames are the same, false otherwise.
1546             sub _compare_relationship_keys {
1547             # my ($self, $keys1, $keys2) = @_;
1548             return
1549 8439         19984 join ("\x00", sort @{$_[1]})
1550             eq
1551 8439     8439   13752 join ("\x00", sort @{$_[2]})
  8439         47981  
1552             ;
1553             }
1554              
1555             # optionally takes either an arrayref of column names, or a hashref of already
1556             # retrieved colinfos
1557             # returns an arrayref of column names of the shortest unique constraint
1558             # (matching some of the input if any), giving preference to the PK
1559             sub _identifying_column_set {
1560 666     666   1782 my ($self, $cols) = @_;
1561              
1562 666         2329 my %unique = $self->unique_constraints;
1563 666 100 66     2985 my $colinfos = ref $cols eq 'HASH' ? $cols : $self->columns_info($cols||());
1564              
1565             # always prefer the PK first, and then shortest constraints first
1566             USET:
1567 666         2977 for my $set (delete $unique{primary}, sort { @$a <=> @$b } (values %unique) ) {
  373         1090  
1568 839 50 33     3614 next unless $set && @$set;
1569              
1570 839         1973 for (@$set) {
1571 1022 100 100     4529 next USET unless ($colinfos->{$_} && !$colinfos->{$_}{is_nullable} );
1572             }
1573              
1574             # copy so we can mangle it at will
1575 631         4546 return [ @$set ];
1576             }
1577              
1578 35         190 return undef;
1579             }
1580              
1581             sub _minimal_valueset_satisfying_constraint {
1582 3263     3263   7135 my $self = shift;
1583 3263 50       16530 my $args = { ref $_[0] eq 'HASH' ? %{ $_[0] } : @_ };
  0         0  
1584              
1585 3263   66     10551 $args->{columns_info} ||= $self->columns_info;
1586              
1587             my $vals = $self->storage->_extract_fixed_condition_columns(
1588             $args->{values},
1589 3263 100       9345 ($args->{carp_on_nulls} ? 'consider_nulls' : undef ),
1590             );
1591              
1592 3259         6059 my $cols;
1593 3259         10042 for my $col ($self->unique_constraint_columns($args->{constraint_name}) ) {
1594 4272 100 100     19470 if( ! exists $vals->{$col} or ( $vals->{$col}||'' ) eq UNRESOLVABLE_CONDITION ) {
    100 100        
1595 2836         7857 $cols->{missing}{$col} = undef;
1596             }
1597             elsif( ! defined $vals->{$col} ) {
1598 2 50       15 $cols->{$args->{carp_on_nulls} ? 'undefined' : 'missing'}{$col} = undef;
1599             }
1600             else {
1601             # we need to inject back the '=' as _extract_fixed_condition_columns
1602             # will strip it from literals and values alike, resulting in an invalid
1603             # condition in the end
1604 1434         7047 $cols->{present}{$col} = { '=' => $vals->{$col} };
1605             }
1606              
1607             $cols->{fc}{$col} = 1 if (
1608             ( ! $cols->{missing} or ! exists $cols->{missing}{$col} )
1609             and
1610 4272 100 100     18885 keys %{ $args->{columns_info}{$col}{_filter_info} || {} }
  1436 100 100     10777  
1611             );
1612             }
1613              
1614             $self->throw_exception( sprintf ( "Unable to satisfy requested constraint '%s', missing values for column(s): %s",
1615             $args->{constraint_name},
1616 2836         18723 join (', ', map { "'$_'" } sort keys %{$cols->{missing}} ),
  1969         7002  
1617 3259 100       9909 ) ) if $cols->{missing};
1618              
1619             $self->throw_exception( sprintf (
1620             "Unable to satisfy requested constraint '%s', FilterColumn values not usable for column(s): %s",
1621             $args->{constraint_name},
1622 2         21 join (', ', map { "'$_'" } sort keys %{$cols->{fc}}),
  2         6  
1623 1290 100       3692 )) if $cols->{fc};
1624              
1625 1288 100 66     4092 if (
1626             $cols->{undefined}
1627             and
1628             !$ENV{DBIC_NULLABLE_KEY_NOWARN}
1629             ) {
1630             carp_unique ( sprintf (
1631             "NULL/undef values supplied for requested unique constraint '%s' (NULL "
1632             . 'values in column(s): %s). This is almost certainly not what you wanted, '
1633             . 'though you can set DBIC_NULLABLE_KEY_NOWARN to disable this warning.',
1634             $args->{constraint_name},
1635 2         6 join (', ', map { "'$_'" } sort keys %{$cols->{undefined}}),
  2         27  
  2         7  
1636             ));
1637             }
1638              
1639 1288 100       2860 return { map { %{ $cols->{$_}||{} } } qw(present undefined) };
  2576         3557  
  2576         17774  
1640             }
1641              
1642             # Returns the {from} structure used to express JOIN conditions
1643             sub _resolve_join {
1644 2393     2393   6573 my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1645              
1646             # we need a supplied one, because we do in-place modifications, no returns
1647 2393 50       6256 $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1648             unless ref $seen eq 'HASH';
1649              
1650 2393 50       5349 $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1651             unless ref $jpath eq 'ARRAY';
1652              
1653 2393         4328 $jpath = [@$jpath]; # copy
1654              
1655 2393 100 100     13235 if (not defined $join or not length $join) {
    100          
    100          
    50          
1656 428         1560 return ();
1657             }
1658             elsif (ref $join eq 'ARRAY') {
1659             return
1660             map {
1661 529         1447 $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
  741         2263  
1662             } @$join;
1663             }
1664             elsif (ref $join eq 'HASH') {
1665              
1666 259         485 my @ret;
1667 259         820 for my $rel (keys %$join) {
1668              
1669 256 50       869 my $rel_info = $self->relationship_info($rel)
1670             or $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1671              
1672 256         551 my $force_left = $parent_force_left;
1673 256   100     1667 $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
      100        
1674              
1675             # the actual seen value will be incremented by the recursion
1676             my $as = $self->storage->relname_to_table_alias(
1677 256   66     800 $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1678             );
1679              
1680             push @ret, (
1681             $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1682             $self->related_source($rel)->_resolve_join(
1683 256         1306 $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
1684             )
1685             );
1686             }
1687 259         1619 return @ret;
1688              
1689             }
1690             elsif (ref $join) {
1691 0         0 $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1692             }
1693             else {
1694 1177         3386 my $count = ++$seen->{$join};
1695 1177   66     3571 my $as = $self->storage->relname_to_table_alias(
1696             $join, ($count > 1 && $count)
1697             );
1698              
1699 1177 50       3839 my $rel_info = $self->relationship_info($join)
1700             or $self->throw_exception("No such relationship $join on " . $self->source_name);
1701              
1702 1177         3963 my $rel_src = $self->related_source($join);
1703             return [ { $as => $rel_src->from,
1704             -rsrc => $rel_src,
1705             -join_type => $parent_force_left
1706             ? 'left'
1707             : $rel_info->{attrs}{join_type}
1708             ,
1709             -join_path => [@$jpath, { $join => $as } ],
1710             -is_single => (
1711             (! $rel_info->{attrs}{accessor})
1712             or
1713 2068     2068   14354 first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
1714             ),
1715             -alias => $as,
1716             -relation_chain_depth => ( $seen->{-relation_chain_depth} || 0 ) + 1,
1717             },
1718 1177 100 66     7522 scalar $self->_resolve_condition($rel_info->{cond}, $as, $alias, $join)
      100        
1719             ];
1720             }
1721             }
1722              
1723             sub pk_depends_on {
1724 0     0 0 0 carp 'pk_depends_on is a private method, stop calling it';
1725 0         0 my $self = shift;
1726 0         0 $self->_pk_depends_on (@_);
1727             }
1728              
1729             # Determines whether a relation is dependent on an object from this source
1730             # having already been inserted. Takes the name of the relationship and a
1731             # hashref of columns of the related object.
1732             sub _pk_depends_on {
1733 696     696   1702 my ($self, $rel_name, $rel_data) = @_;
1734              
1735 696         1633 my $relinfo = $self->relationship_info($rel_name);
1736              
1737             # don't assume things if the relationship direction is specified
1738             return $relinfo->{attrs}{is_foreign_key_constraint}
1739 696 100       4242 if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1740              
1741 200         446 my $cond = $relinfo->{cond};
1742 200 50       622 return 0 unless ref($cond) eq 'HASH';
1743              
1744             # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1745 200         582 my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
  400         703  
  400         1600  
  400         1242  
1746              
1747             # assume anything that references our PK probably is dependent on us
1748             # rather than vice versa, unless the far side is (a) defined or (b)
1749             # auto-increment
1750 200         673 my $rel_source = $self->related_source($rel_name);
1751              
1752 200         1158 foreach my $p ($self->primary_columns) {
1753 200 50       601 if (exists $keyhash->{$p}) {
1754 200 50 33     1040 unless (defined($rel_data->{$keyhash->{$p}})
1755             || $rel_source->column_info($keyhash->{$p})
1756             ->{is_auto_increment}) {
1757 200         1048 return 0;
1758             }
1759             }
1760             }
1761              
1762 0         0 return 1;
1763             }
1764              
1765             sub resolve_condition {
1766 0     0 0 0 carp 'resolve_condition is a private method, stop calling it';
1767 0         0 shift->_resolve_condition (@_);
1768             }
1769              
1770             sub _resolve_condition {
1771             # carp_unique sprintf
1772             # '_resolve_condition is a private method, and moreover is about to go '
1773             # . 'away. Please contact the development team at %s if you believe you '
1774             # . 'have a genuine use for this method, in order to discuss alternatives.',
1775             # DBIx::Class::_ENV_::HELP_URL,
1776             # ;
1777              
1778             #######################
1779             ### API Design? What's that...? (a backwards compatible shim, kill me now)
1780              
1781 4179     4179   8666 my ($self, $cond, @res_args, $rel_name);
1782              
1783             # we *SIMPLY DON'T KNOW YET* which arg is which, yay
1784 4179         12486 ($self, $cond, $res_args[0], $res_args[1], $rel_name) = @_;
1785              
1786             # assume that an undef is an object-like unset (set_from_related(undef))
1787 4179 50       8055 my @is_objlike = map { ! defined $_ or length ref $_ } (@res_args);
  8358         32345  
1788              
1789             # turn objlike into proper objects for saner code further down
1790 4179         9752 for (0,1) {
1791 8358 100       18291 next unless $is_objlike[$_];
1792              
1793 3002 100       10710 if ( defined blessed $res_args[$_] ) {
1794              
1795             # but wait - there is more!!! WHAT THE FUCK?!?!?!?!
1796 2995 50       22269 if ($res_args[$_]->isa('DBIx::Class::ResultSet')) {
1797 0         0 carp('Passing a resultset for relationship resolution makes no sense - invoking __gremlins__');
1798 0         0 $is_objlike[$_] = 0;
1799 0         0 $res_args[$_] = '__gremlins__';
1800             }
1801             }
1802             else {
1803 7   50     34 $res_args[$_] ||= {};
1804              
1805             # hate everywhere - have to pass in as a plain hash
1806             # pretending to be an object at least for now
1807 7 50       32 $self->throw_exception("Unsupported object-like structure encountered: $res_args[$_]")
1808             unless ref $res_args[$_] eq 'HASH';
1809             }
1810             }
1811              
1812 4179 100       27124 my $args = {
    100          
    50          
1813             condition => $cond,
1814              
1815             # where-is-waldo block guesses relname, then further down we override it if available
1816             (
1817             $is_objlike[1] ? ( rel_name => $res_args[0], self_alias => $res_args[0], foreign_alias => 'me', self_result_object => $res_args[1] )
1818             : $is_objlike[0] ? ( rel_name => $res_args[1], self_alias => 'me', foreign_alias => $res_args[1], foreign_values => $res_args[0] )
1819             : ( rel_name => $res_args[0], self_alias => $res_args[1], foreign_alias => $res_args[0] )
1820             ),
1821              
1822             ( $rel_name ? ( rel_name => $rel_name ) : () ),
1823             };
1824             #######################
1825              
1826             # now it's fucking easy isn't it?!
1827 4179         11524 my $rc = $self->_resolve_relationship_condition( $args );
1828              
1829             my @res = (
1830             ( $rc->{join_free_condition} || $rc->{condition} ),
1831             ! $rc->{join_free_condition},
1832 4177   66     17412 );
1833              
1834             # _resolve_relationship_condition always returns qualified cols even in the
1835             # case of join_free_condition, but nothing downstream expects this
1836 4177 100 100     16370 if ($rc->{join_free_condition} and ref $res[0] eq 'HASH') {
1837             $res[0] = { map
1838 2873         15623 { ($_ =~ /\.(.+)/) => $res[0]{$_} }
1839 2831         4714 keys %{$res[0]}
  2831         7320  
1840             };
1841             }
1842              
1843             # and more legacy
1844 4177 100       37701 return wantarray ? @res : $res[0];
1845             }
1846              
1847             # Keep this indefinitely. There is evidence of both CPAN and
1848             # darkpan using it, and there isn't much harm in an extra var
1849             # anyway.
1850             our $UNRESOLVABLE_CONDITION = UNRESOLVABLE_CONDITION;
1851             # YES I KNOW THIS IS EVIL
1852             # it is there to save darkpan from themselves, since internally
1853             # we are moving to a constant
1854             Internals::SvREADONLY($UNRESOLVABLE_CONDITION => 1);
1855              
1856             # Resolves the passed condition to a concrete query fragment and extra
1857             # metadata
1858             #
1859             ## self-explanatory API, modeled on the custom cond coderef:
1860             # rel_name => (scalar)
1861             # foreign_alias => (scalar)
1862             # foreign_values => (either not supplied, or a hashref, or a foreign ResultObject (to be ->get_columns()ed), or plain undef )
1863             # self_alias => (scalar)
1864             # self_result_object => (either not supplied or a result object)
1865             # require_join_free_condition => (boolean, throws on failure to construct a JF-cond)
1866             # infer_values_based_on => (either not supplied or a hashref, implies require_join_free_condition)
1867             # condition => (sqla cond struct, optional, defeaults to from $self->rel_info(rel_name)->{cond})
1868             #
1869             ## returns a hash
1870             # condition => (a valid *likely fully qualified* sqla cond structure)
1871             # identity_map => (a hashref of foreign-to-self *unqualified* column equality names)
1872             # join_free_condition => (a valid *fully qualified* sqla cond structure, maybe unset)
1873             # inferred_values => (in case of an available join_free condition, this is a hashref of
1874             # *unqualified* column/value *EQUALITY* pairs, representing an amalgamation
1875             # of the JF-cond parse and infer_values_based_on
1876             # always either complete or unset)
1877             #
1878             sub _resolve_relationship_condition {
1879 6002     6002   10346 my $self = shift;
1880              
1881 6002 100       19884 my $args = { ref $_[0] eq 'HASH' ? %{ $_[0] } : @_ };
  4213         18370  
1882              
1883 6002         14867 for ( qw( rel_name self_alias foreign_alias ) ) {
1884             $self->throw_exception("Mandatory argument '$_' to _resolve_relationship_condition() is not a plain string")
1885 18006 50 33     63076 if !defined $args->{$_} or length ref $args->{$_};
1886             }
1887              
1888             $self->throw_exception("Arguments 'self_alias' and 'foreign_alias' may not be identical")
1889 6002 50       15786 if $args->{self_alias} eq $args->{foreign_alias};
1890              
1891             # TEMP
1892 6002         14242 my $exception_rel_id = "relationship '$args->{rel_name}' on source '@{[ $self->source_name ]}'";
  6002         24258  
1893              
1894             my $rel_info = $self->relationship_info($args->{rel_name})
1895             # TEMP
1896             # or $self->throw_exception( "No such $exception_rel_id" );
1897 6002 50       53115 or carp_unique("Requesting resolution on non-existent relationship '$args->{rel_name}' on source '@{[ $self->source_name ]}': fix your code *soon*, as it will break with the next major version");
  0         0  
1898              
1899             # TEMP
1900 77         280 $exception_rel_id = "relationship '$rel_info->{_original_name}' on source '@{[ $self->source_name ]}'"
1901 6002 100 66     24977 if $rel_info and exists $rel_info->{_original_name};
1902              
1903             $self->throw_exception("No practical way to resolve $exception_rel_id between two data structures")
1904 6002 50 66     19891 if exists $args->{self_result_object} and exists $args->{foreign_values};
1905              
1906             $self->throw_exception( "Argument to infer_values_based_on must be a hash" )
1907 6002 50 66     16827 if exists $args->{infer_values_based_on} and ref $args->{infer_values_based_on} ne 'HASH';
1908              
1909 6002   66     26901 $args->{require_join_free_condition} ||= !!$args->{infer_values_based_on};
1910              
1911 6002   66     16945 $args->{condition} ||= $rel_info->{cond};
1912              
1913             $self->throw_exception( "Argument 'self_result_object' must be an object inheriting from DBIx::Class::Row" )
1914             if (
1915             exists $args->{self_result_object}
1916             and
1917 6002 50 33     35549 ( ! defined blessed $args->{self_result_object} or ! $args->{self_result_object}->isa('DBIx::Class::Row') )
      66        
1918             )
1919             ;
1920              
1921             #TEMP
1922 6002         10275 my $rel_rsrc;# = $self->related_source($args->{rel_name});
1923              
1924 6002 100       12239 if (exists $args->{foreign_values}) {
1925             # TEMP
1926 609   33     2517 $rel_rsrc ||= $self->related_source($args->{rel_name});
1927              
1928 609 100 66     4386 if (defined blessed $args->{foreign_values}) {
    50          
1929              
1930             $self->throw_exception( "Objects supplied as 'foreign_values' ($args->{foreign_values}) must inherit from DBIx::Class::Row" )
1931 600 50       3554 unless $args->{foreign_values}->isa('DBIx::Class::Row');
1932              
1933             carp_unique(
1934             "Objects supplied as 'foreign_values' ($args->{foreign_values}) "
1935 0         0 . "usually should inherit from the related ResultClass ('@{[ $rel_rsrc->result_class ]}'), "
1936             . "perhaps you've made a mistake invoking the condition resolver?"
1937 600 50       12559 ) unless $args->{foreign_values}->isa($rel_rsrc->result_class);
1938              
1939 600         2682 $args->{foreign_values} = { $args->{foreign_values}->get_columns };
1940             }
1941             elsif (! defined $args->{foreign_values} or ref $args->{foreign_values} eq 'HASH') {
1942 9         41 my $ri = { map { $_ => 1 } $rel_rsrc->relationships };
  107         236  
1943 9         53 my $ci = $rel_rsrc->columns_info;
1944             ! exists $ci->{$_} and ! exists $ri->{$_} and $self->throw_exception(
1945 0         0 "Key '$_' supplied as 'foreign_values' is not a column on related source '@{[ $rel_rsrc->source_name ]}'"
1946 9   100     23 ) for keys %{ $args->{foreign_values} ||= {} };
  9   66     91  
      33        
1947             }
1948             else {
1949 0         0 $self->throw_exception(
1950 0         0 "Argument 'foreign_values' must be either an object inheriting from '@{[ $rel_rsrc->result_class ]}', "
1951             . "or a hash reference, or undef"
1952             );
1953             }
1954             }
1955              
1956 6002         9431 my $ret;
1957              
1958 6002 100       19266 if (ref $args->{condition} eq 'CODE') {
    100          
    50          
1959              
1960             my $cref_args = {
1961             rel_name => $args->{rel_name},
1962             self_resultsource => $self,
1963             self_alias => $args->{self_alias},
1964             foreign_alias => $args->{foreign_alias},
1965             ( map
1966 226 100       583 { (exists $args->{$_}) ? ( $_ => $args->{$_} ) : () }
  452         1598  
1967             qw( self_result_object foreign_values )
1968             ),
1969             };
1970              
1971             # legacy - never remove these!!!
1972 226         493 $cref_args->{foreign_relname} = $cref_args->{rel_name};
1973              
1974             $cref_args->{self_rowobj} = $cref_args->{self_result_object}
1975 226 100       592 if exists $cref_args->{self_result_object};
1976              
1977 226         722 ($ret->{condition}, $ret->{join_free_condition}, my @extra) = $args->{condition}->($cref_args);
1978              
1979             # sanity check
1980 226 100       1817 $self->throw_exception("A custom condition coderef can return at most 2 conditions, but $exception_rel_id returned extra values: @extra")
1981             if @extra;
1982              
1983 225 100       941 if (my $jfc = $ret->{join_free_condition}) {
1984              
1985 22 50       66 $self->throw_exception (
1986             "The join-free condition returned for $exception_rel_id must be a hash reference"
1987             ) unless ref $jfc eq 'HASH';
1988              
1989             # TEMP
1990 22   66     102 $rel_rsrc ||= $self->related_source($args->{rel_name});
1991              
1992 22         97 my ($joinfree_alias, $joinfree_source);
1993 22 100       78 if (defined $args->{self_result_object}) {
    50          
1994 19         45 $joinfree_alias = $args->{foreign_alias};
1995 19         33 $joinfree_source = $rel_rsrc;
1996             }
1997             elsif (defined $args->{foreign_values}) {
1998 3         7 $joinfree_alias = $args->{self_alias};
1999 3         8 $joinfree_source = $self;
2000             }
2001              
2002             # FIXME sanity check until things stabilize, remove at some point
2003             $self->throw_exception (
2004 22 50       62 "A join-free condition returned for $exception_rel_id without a result object to chain from"
2005             ) unless $joinfree_alias;
2006              
2007             my $fq_col_list = { map
2008 22         71 { ( "$joinfree_alias.$_" => 1 ) }
  120         346  
2009             $joinfree_source->columns
2010             };
2011              
2012             exists $fq_col_list->{$_} or $self->throw_exception (
2013             "The join-free condition returned for $exception_rel_id may only "
2014             . 'contain keys that are fully qualified column names of the corresponding source '
2015             . "(it returned '$_')"
2016 22   33     174 ) for keys %$jfc;
2017              
2018             (
2019             length ref $_
2020             and
2021             defined blessed($_)
2022             and
2023             $_->isa('DBIx::Class::Row')
2024             and
2025             $self->throw_exception (
2026             "The join-free condition returned for $exception_rel_id may not "
2027             . 'contain result objects as values - perhaps instead of invoking '
2028             . '->$something you meant to return ->get_column($something)'
2029             )
2030 22   66     223 ) for values %$jfc;
      33        
      33        
2031              
2032             }
2033             }
2034             elsif (ref $args->{condition} eq 'HASH') {
2035              
2036             # the condition is static - use parallel arrays
2037             # for a "pivot" depending on which side of the
2038             # rel did we get as an object
2039 5759         9662 my (@f_cols, @l_cols);
2040 5759         8253 for my $fc (keys %{$args->{condition}}) {
  5759         17139  
2041 5871         11897 my $lc = $args->{condition}{$fc};
2042              
2043             # FIXME STRICTMODE should probably check these are valid columns
2044 5871 50       28992 $fc =~ s/^foreign\.// ||
2045             $self->throw_exception("Invalid rel cond key '$fc'");
2046              
2047 5871 50       22448 $lc =~ s/^self\.// ||
2048             $self->throw_exception("Invalid rel cond val '$lc'");
2049              
2050 5871         13340 push @f_cols, $fc;
2051 5871         13060 push @l_cols, $lc;
2052             }
2053              
2054             # construct the crosstable condition and the identity map
2055 5759         16504 for (0..$#f_cols) {
2056 5871         30549 $ret->{condition}{"$args->{foreign_alias}.$f_cols[$_]"} = { -ident => "$args->{self_alias}.$l_cols[$_]" };
2057 5871         19848 $ret->{identity_map}{$l_cols[$_]} = $f_cols[$_];
2058             };
2059              
2060 5759 100       17898 if ($args->{foreign_values}) {
    100          
2061             $ret->{join_free_condition}{"$args->{self_alias}.$l_cols[$_]"} = $args->{foreign_values}{$f_cols[$_]}
2062 605         3279 for 0..$#f_cols;
2063             }
2064             elsif (defined $args->{self_result_object}) {
2065              
2066 4053         8114 for my $i (0..$#l_cols) {
2067 4083 100       16024 if ( $args->{self_result_object}->has_column_loaded($l_cols[$i]) ) {
2068 3993         12604 $ret->{join_free_condition}{"$args->{foreign_alias}.$f_cols[$i]"} = $args->{self_result_object}->get_column($l_cols[$i]);
2069             }
2070             else {
2071             $self->throw_exception(sprintf
2072             "Unable to resolve relationship '%s' from object '%s': column '%s' not "
2073             . 'loaded from storage (or not passed to new() prior to insert()). You '
2074             . 'probably need to call ->discard_changes to get the server-side defaults '
2075             . 'from the database.',
2076             $args->{rel_name},
2077             $args->{self_result_object},
2078             $l_cols[$i],
2079 90 100       400 ) if $args->{self_result_object}->in_storage;
2080              
2081             # FIXME - temporarly force-override
2082 88         1989 delete $args->{require_join_free_condition};
2083 88         193 $ret->{join_free_condition} = UNRESOLVABLE_CONDITION;
2084 88         214 last;
2085             }
2086             }
2087             }
2088             }
2089             elsif (ref $args->{condition} eq 'ARRAY') {
2090 17 50       35 if (@{$args->{condition}} == 0) {
  17 50       69  
2091 0         0 $ret = {
2092             condition => UNRESOLVABLE_CONDITION,
2093             join_free_condition => UNRESOLVABLE_CONDITION,
2094             };
2095             }
2096 17         74 elsif (@{$args->{condition}} == 1) {
2097             $ret = $self->_resolve_relationship_condition({
2098             %$args,
2099 0         0 condition => $args->{condition}[0],
2100             });
2101             }
2102             else {
2103             # we are discarding inferred values here... likely incorrect...
2104             # then again - the entire thing is an OR, so we *can't* use them anyway
2105 17         34 for my $subcond ( map
2106 34         361 { $self->_resolve_relationship_condition({ %$args, condition => $_ }) }
2107 17         54 @{$args->{condition}}
2108             ) {
2109             $self->throw_exception('Either all or none of the OR-condition members must resolve to a join-free condition')
2110 34 50 50     186 if ( $ret and ( $ret->{join_free_condition} xor $subcond->{join_free_condition} ) );
      66        
2111              
2112 34   66     113 $subcond->{$_} and push @{$ret->{$_}}, $subcond->{$_} for (qw(condition join_free_condition));
  54         205  
2113             }
2114             }
2115             }
2116             else {
2117 0         0 $self->throw_exception ("Can't handle condition $args->{condition} for $exception_rel_id yet :(");
2118             }
2119              
2120             $self->throw_exception(ucfirst "$exception_rel_id does not resolve to a join-free condition fragment") if (
2121             $args->{require_join_free_condition}
2122             and
2123 5999 100 66     19987 ( ! $ret->{join_free_condition} or $ret->{join_free_condition} eq UNRESOLVABLE_CONDITION )
      66        
2124             );
2125              
2126 5998         16082 my $storage = $self->schema->storage;
2127              
2128             # we got something back - sanity check and infer values if we can
2129 5998         85766 my @nonvalues;
2130 5998 100 100     28339 if ( my $jfc = $ret->{join_free_condition} and $ret->{join_free_condition} ne UNRESOLVABLE_CONDITION ) {
2131              
2132 4600         18031 my $jfc_eqs = $storage->_extract_fixed_condition_columns($jfc, 'consider_nulls');
2133              
2134 4600 100       12208 if (keys %$jfc_eqs) {
2135              
2136 4590         9613 for (keys %$jfc) {
2137             # $jfc is fully qualified by definition
2138 4672         21756 my ($col) = $_ =~ /\.(.+)/;
2139              
2140 4672 100 100     25245 if (exists $jfc_eqs->{$_} and ($jfc_eqs->{$_}||'') ne UNRESOLVABLE_CONDITION) {
    100 66        
      100        
2141 4661         16686 $ret->{inferred_values}{$col} = $jfc_eqs->{$_};
2142             }
2143             elsif ( !$args->{infer_values_based_on} or ! exists $args->{infer_values_based_on}{$col} ) {
2144 10         31 push @nonvalues, $col;
2145             }
2146             }
2147              
2148             # all or nothing
2149 4590 100       13748 delete $ret->{inferred_values} if @nonvalues;
2150             }
2151             }
2152              
2153             # did the user explicitly ask
2154 5998 100       15507 if ($args->{infer_values_based_on}) {
2155              
2156             $self->throw_exception(sprintf (
2157             "Unable to complete value inferrence - custom $exception_rel_id returns conditions instead of values for column(s): %s",
2158 1252 100       2925 map { "'$_'" } @nonvalues
  1         17  
2159             )) if @nonvalues;
2160              
2161              
2162 1251   100     3146 $ret->{inferred_values} ||= {};
2163              
2164             $ret->{inferred_values}{$_} = $args->{infer_values_based_on}{$_}
2165 1251         1986 for keys %{$args->{infer_values_based_on}};
  1251         4825  
2166             }
2167              
2168             # add the identities based on the main condition
2169             # (may already be there, since easy to calculate on the fly in the HASH case)
2170 5997 100       14347 if ( ! $ret->{identity_map} ) {
2171              
2172 240         903 my $col_eqs = $storage->_extract_fixed_condition_columns($ret->{condition});
2173              
2174 240         433 my $colinfos;
2175 240         701 for my $lhs (keys %$col_eqs) {
2176              
2177 222 50       898 next if $col_eqs->{$lhs} eq UNRESOLVABLE_CONDITION;
2178              
2179             # TEMP
2180 222   66     1054 $rel_rsrc ||= $self->related_source($args->{rel_name});
2181              
2182             # there is no way to know who is right and who is left in a cref
2183             # therefore a full blown resolution call, and figure out the
2184             # direction a bit further below
2185             $colinfos ||= $storage->_resolve_column_info([
2186             { -alias => $args->{self_alias}, -rsrc => $self },
2187 222   66     2276 { -alias => $args->{foreign_alias}, -rsrc => $rel_rsrc },
2188             ]);
2189              
2190 222 50       837 next unless $colinfos->{$lhs}; # someone is engaging in witchcraft
2191              
2192 222 100 50     876 if ( my $rhs_ref = is_literal_value( $col_eqs->{$lhs} ) ) {
    100 66        
2193              
2194 184 100 66     3870 if (
2195             $colinfos->{$rhs_ref->[0]}
2196             and
2197             $colinfos->{$lhs}{-source_alias} ne $colinfos->{$rhs_ref->[0]}{-source_alias}
2198             ) {
2199             ( $colinfos->{$lhs}{-source_alias} eq $args->{self_alias} )
2200             ? ( $ret->{identity_map}{$colinfos->{$lhs}{-colname}} = $colinfos->{$rhs_ref->[0]}{-colname} )
2201             : ( $ret->{identity_map}{$colinfos->{$rhs_ref->[0]}{-colname}} = $colinfos->{$lhs}{-colname} )
2202 8 50       110 ;
2203             }
2204             }
2205             elsif (
2206             $col_eqs->{$lhs} =~ /^ ( \Q$args->{self_alias}\E \. .+ ) /x
2207             and
2208             ($colinfos->{$1}||{})->{-result_source} == $rel_rsrc
2209             ) {
2210             my ($lcol, $rcol) = map
2211 2         66 { $colinfos->{$_}{-colname} }
  4         15  
2212             ( $lhs, $1 )
2213             ;
2214 2         16 carp_unique(
2215             "The $exception_rel_id specifies equality of column '$lcol' and the "
2216             . "*VALUE* '$rcol' (you did not use the { -ident => ... } operator)"
2217             );
2218             }
2219             }
2220             }
2221              
2222             # FIXME - temporary, to fool the idiotic check in SQLMaker::_join_condition
2223             $ret->{condition} = { -and => [ $ret->{condition} ] }
2224 5997 50       27942 unless $ret->{condition} eq UNRESOLVABLE_CONDITION;
2225              
2226 5997         36872 $ret;
2227             }
2228              
2229             =head2 related_source
2230              
2231             =over 4
2232              
2233             =item Arguments: $rel_name
2234              
2235             =item Return Value: $source
2236              
2237             =back
2238              
2239             Returns the result source object for the given relationship.
2240              
2241             =cut
2242              
2243             sub related_source {
2244 29634     29634 1 58225 my ($self, $rel) = @_;
2245 29634 50       58746 if( !$self->has_relationship( $rel ) ) {
2246 0         0 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
2247             }
2248              
2249             # if we are not registered with a schema - just use the prototype
2250             # however if we do have a schema - ask for the source by name (and
2251             # throw in the process if all fails)
2252 29634 100   29634   126765 if (my $schema = try { $self->schema }) {
  29634         1074320  
2253 29615         310763 $schema->source($self->relationship_info($rel)->{source});
2254             }
2255             else {
2256 19         315 my $class = $self->relationship_info($rel)->{class};
2257 19         73 $self->ensure_class_loaded($class);
2258 19         644 $class->result_source_instance;
2259             }
2260             }
2261              
2262             =head2 related_class
2263              
2264             =over 4
2265              
2266             =item Arguments: $rel_name
2267              
2268             =item Return Value: $classname
2269              
2270             =back
2271              
2272             Returns the class name for objects in the given relationship.
2273              
2274             =cut
2275              
2276             sub related_class {
2277 0     0 1 0 my ($self, $rel) = @_;
2278 0 0       0 if( !$self->has_relationship( $rel ) ) {
2279 0         0 $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
2280             }
2281 0         0 return $self->schema->class($self->relationship_info($rel)->{source});
2282             }
2283              
2284             =head2 handle
2285              
2286             =over 4
2287              
2288             =item Arguments: none
2289              
2290             =item Return Value: L<$source_handle|DBIx::Class::ResultSourceHandle>
2291              
2292             =back
2293              
2294             Obtain a new L<result source handle instance|DBIx::Class::ResultSourceHandle>
2295             for this source. Used as a serializable pointer to this resultsource, as it is not
2296             easy (nor advisable) to serialize CODErefs which may very well be present in e.g.
2297             relationship definitions.
2298              
2299             =cut
2300              
2301             sub handle {
2302             return DBIx::Class::ResultSourceHandle->new({
2303             source_moniker => $_[0]->source_name,
2304              
2305             # so that a detached thaw can be re-frozen
2306             $_[0]->{_detached_thaw}
2307 206 50   206 1 1129 ? ( _detached_source => $_[0] )
2308             : ( schema => $_[0]->schema )
2309             ,
2310             });
2311             }
2312              
2313             my $global_phase_destroy;
2314             sub DESTROY {
2315             ### NO detected_reinvoked_destructor check
2316             ### This code very much relies on being called multuple times
2317              
2318 126250 50 33 126250   2663664 return if $global_phase_destroy ||= in_global_destruction;
2319              
2320             ######
2321             # !!! ACHTUNG !!!!
2322             ######
2323             #
2324             # Under no circumstances shall $_[0] be stored anywhere else (like copied to
2325             # a lexical variable, or shifted, or anything else). Doing so will mess up
2326             # the refcount of this particular result source, and will allow the $schema
2327             # we are trying to save to reattach back to the source we are destroying.
2328             # The relevant code checking refcounts is in ::Schema::DESTROY()
2329              
2330             # if we are not a schema instance holder - we don't matter
2331             return if(
2332             ! ref $_[0]->{schema}
2333             or
2334             isweak $_[0]->{schema}
2335 126250 100 100     2041206 );
2336              
2337             # weaken our schema hold forcing the schema to find somewhere else to live
2338             # during global destruction (if we have not yet bailed out) this will throw
2339             # which will serve as a signal to not try doing anything else
2340             # however beware - on older perls the exception seems randomly untrappable
2341             # due to some weird race condition during thread joining :(((
2342 19228         34971 local $@;
2343             eval {
2344 19228         50777 weaken $_[0]->{schema};
2345              
2346             # if schema is still there reintroduce ourselves with strong refs back to us
2347 19228 100       42033 if ($_[0]->{schema}) {
2348 19217         354645 my $srcregs = $_[0]->{schema}->source_registrations;
2349 19217         330500 for (keys %$srcregs) {
2350 884078 50       1481782 next unless $srcregs->{$_};
2351 884078 100       1586998 $srcregs->{$_} = $_[0] if $srcregs->{$_} == $_[0];
2352             }
2353             }
2354              
2355 19228         70127 1;
2356 19228 50       32225 } or do {
2357 0         0 $global_phase_destroy = 1;
2358             };
2359              
2360 19228         118940 return;
2361             }
2362              
2363 204     204 0 5186 sub STORABLE_freeze { Storable::nfreeze($_[0]->handle) }
2364              
2365             sub STORABLE_thaw {
2366 204     204 0 3304 my ($self, $cloning, $ice) = @_;
2367 204         330 %$self = %{ (Storable::thaw($ice))->resolve };
  204         505  
2368             }
2369              
2370             =head2 throw_exception
2371              
2372             See L<DBIx::Class::Schema/"throw_exception">.
2373              
2374             =cut
2375              
2376             sub throw_exception {
2377 2058     2058 1 4816 my $self = shift;
2378              
2379             $self->{schema}
2380 2058 100       11762 ? $self->{schema}->throw_exception(@_)
2381             : DBIx::Class::Exception->throw(@_)
2382             ;
2383             }
2384              
2385             =head2 column_info_from_storage
2386              
2387             =over
2388              
2389             =item Arguments: 1/0 (default: 0)
2390              
2391             =item Return Value: 1/0
2392              
2393             =back
2394              
2395             __PACKAGE__->column_info_from_storage(1);
2396              
2397             Enables the on-demand automatic loading of the above column
2398             metadata from storage as necessary. This is *deprecated*, and
2399             should not be used. It will be removed before 1.0.
2400              
2401             =head1 FURTHER QUESTIONS?
2402              
2403             Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
2404              
2405             =head1 COPYRIGHT AND LICENSE
2406              
2407             This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
2408             by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
2409             redistribute it and/or modify it under the same terms as the
2410             L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
2411              
2412             =cut
2413              
2414             1;