sets quote_char and name_sep appropriate for your RDBMS
- Add retrieve_on_insert column info flag, allowing to retrieve any
column value instead of just autoinc primary keys
+ - Allow specification of some runtime relationship options (see
+ DBIx::Class::ResultSet/relationship_options)
- All limit dialects (except for the older Top and FetchFirst) are
now using bind parameters for the limits/offsets, making DBI's
prepare_cached useful across paged resutsets
=over 4
-=item Value: ($rel_name | \@rel_names | \%rel_names)
+=item Value: ($rel_name | \@rel_names | \%rel_names_and_join_opts)
=back
{ join => 'artist' }
);
-Can also contain a hash reference to refer to the other relation's relations.
+Can also contain a hash reference to refer to the other relation's relations,
+as well as various built in options for a relationship.
For example:
package MyApp::Schema::Track;
}
);
+=head3 relationship options
+
+Currently there are two relationship options that are supported:
+
+=over 6
+
+=item C<-join_type>
+
+This allows you to override the join type
+
+=item C<-alias>
+
+This allows you to override the join name, presumably for joining the same
+relationship more than once.
+
+=back
+
+For example, one might want to do the following with the listed options:
+
+ my $rs = $rs->search({
+ 'friends.like' => 1,
+ 'enemies.like' => 0,
+ }, {
+ join => [
+ { relationships => { -alias => 'friends' },
+ { relationships => { -alias => 'enemies', -join_type => 'left },
+ ],
+ });
+
You need to use the relationship (not the table) name in conditions,
because they are aliased as such. The current table is aliased as "me", so
you need to use me.column_name in order to avoid ambiguity. For example:
# Returns the {from} structure used to express JOIN conditions
sub _resolve_join {
- my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
+ my ($self, $join, $alias, $seen, $jpath, $parent_force_left, $opt) = @_;
+
+ $opt ||= {};
# we need a supplied one, because we do in-place modifications, no returns
$self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
$rel, ($seen->{$rel} && $seen->{$rel} + 1)
);
+ my $val = $join->{$rel};
+ my $opt;
+ if (ref $val && ref $val eq 'HASH') {
+ $opt = {
+ alias => delete $val->{-alias},
+ join_type => delete $val->{-join_type},
+ };
+
+ if (my $fail = first { defined && /^-/ } keys %$val) {
+ die "$fail is not a join argument"
+ }
+ }
+
push @ret, (
- $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
+ $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left, $opt),
$self->related_source($rel)->_resolve_join(
- $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
+ $val, $as, $seen, [@$jpath, { $rel => $as }], $force_left
)
);
}
}
else {
my $count = ++$seen->{$join};
- my $as = $self->storage->relname_to_table_alias(
+ my $as = $opt->{alias} || $self->storage->relname_to_table_alias(
$join, ($count > 1 && $count)
);
my $rel_src = $self->related_source($join);
return [ { $as => $rel_src->from,
-rsrc => $rel_src,
- -join_type => $parent_force_left
+ -join_type => $opt->{join_type} || ($parent_force_left
? 'left'
- : $rel_info->{attrs}{join_type}
+ : $rel_info->{attrs}{join_type})
,
-join_path => [@$jpath, { $join => $as } ],
-is_single => (
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBIC::SqlMakerTest;
+use Test::Exception;
+
+my $schema = DBICTest->init_schema;
+
+dies_ok {
+ my $rsq = $schema->resultset('Artist')->search({
+ 'artwork_to_artist.artwork_cd_id' => 5,
+ }, {
+ join => { artwork_to_artist => { -unknown_arg => 'foo' } }
+ })->as_query
+} 'dies on unknown rel args';
+
+lives_ok {
+ my $rsq = $schema->resultset('Artist')->search({
+ 'a2a.artwork_cd_id' => 5,
+ }, {
+ join => { artwork_to_artist => { -alias => 'a2a' } }
+ })->as_query
+} 'lives for arg -alias';
+
+lives_ok {
+ my $rsq = $schema->resultset('Artist')->search({
+ 'artwork_to_artist.artwork_cd_id' => 5,
+ }, {
+ join => { artwork_to_artist => { -join_type => 'left' } }
+ })->as_query
+} 'lives for arg -join_type';
+
+is_same_sql_bind( $schema->resultset('Artist')->search({
+ 'a2a.artwork_cd_id' => 5,
+}, {
+ join => {
+ 'artwork_to_artist' => { -alias => 'a2a', -join_type => 'right' }
+ }
+})->as_query,
+'(
+ SELECT me.artistid, me.name, me.rank, me.charfield
+ FROM artist me
+ RIGHT JOIN artwork_to_artist a2a
+ ON a2a.artist_id = me.artistid
+ WHERE ( a2a.artwork_cd_id = ? )
+)', [[ 'a2a.artwork_cd_id' => 5 ]], 'rel is aliased and join-typed correctly'
+);
+
+done_testing;