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