Skip to content

Commit 6983130

Browse files
committed
More reshuffling of the m2m helper code - no functional changes intended
This is in preparation for the next commit switchin to qsubs
1 parent 8a67d9c commit 6983130

File tree

2 files changed

+84
-43
lines changed

2 files changed

+84
-43
lines changed

lib/DBIx/Class/Relationship/ManyToMany.pm

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -59,53 +59,82 @@ EOW
5959

6060
$rel_attrs->{alias} ||= $f_rel;
6161

62+
6263
my $rs_meth_name = join '::', $class, $rs_meth;
6364
*$rs_meth_name = subname $rs_meth_name, sub {
64-
my $self = shift;
65-
my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {};
66-
my $rs = $self->search_related($rel)->search_related(
67-
$f_rel, @_ > 0 ? @_ : undef, { %{$rel_attrs||{}}, %$attrs }
68-
);
69-
return $rs;
65+
66+
# this little horror is there replicating a deprecation from
67+
# within search_rs() itself
68+
shift->search_related_rs($rel)
69+
->search_related_rs(
70+
$f_rel,
71+
undef,
72+
( @_ > 1 and ref $_[-1] eq 'HASH' )
73+
? { %$rel_attrs, %{ pop @_ } }
74+
: $rel_attrs
75+
)->search_rs(@_)
76+
;
77+
7078
};
7179

80+
7281
my $meth_name = join '::', $class, $meth;
7382
*$meth_name = subname $meth_name, sub {
83+
7484
DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = fail_on_internal_wantarray;
75-
my $self = shift;
76-
my $rs = $self->$rs_meth( @_ );
77-
return (wantarray ? $rs->all : $rs);
85+
86+
my $rs = shift->$rs_meth( @_ );
87+
88+
wantarray ? $rs->all : $rs;
89+
7890
};
7991

92+
8093
my $add_meth_name = join '::', $class, $add_meth;
8194
*$add_meth_name = subname $add_meth_name, sub {
82-
my $self = shift;
83-
@_ or $self->throw_exception(
84-
"${add_meth} needs an object or hashref"
85-
);
8695

87-
my $link = $self->new_related( $rel,
88-
( @_ > 1 && ref $_[-1] eq 'HASH' )
89-
? pop
90-
: {}
96+
( @_ >= 2 and @_ <= 3 ) or $_[0]->throw_exception(
97+
"'$add_meth' expects an object or hashref to link to, and an optional hashref of link data"
9198
);
9299

93-
my $far_obj = defined blessed $_[0]
94-
? $_[0]
95-
: $self->result_source
96-
->related_source( $rel )
97-
->related_source( $f_rel )
98-
->resultset->search_rs( {}, $rel_attrs||{} )
99-
->find_or_create( ref $_[0] eq 'HASH' ? $_[0] : {@_} )
100-
;
100+
$_[0]->throw_exception(
101+
"The optional link data supplied to '$add_meth' is not a hashref (it was previously ignored)"
102+
) if $_[2] and ref $_[2] ne 'HASH';
101103

102-
$link->set_from_related($f_rel, $far_obj);
104+
my( $self, $far_obj ) = @_;
105+
106+
my $guard;
107+
108+
# the API needs is always expected to return the far object, possibly
109+
# creating it in the process
110+
if( not defined blessed $far_obj ) {
111+
112+
$guard = $self->result_source->schema->storage->txn_scope_guard;
113+
114+
# reify the hash into an actual object
115+
$far_obj = $self->result_source
116+
->related_source( $rel )
117+
->related_source( $f_rel )
118+
->resultset
119+
->search_rs( undef, $rel_attrs )
120+
->find_or_create( $far_obj );
121+
}
122+
123+
my $link = $self->new_related(
124+
$rel,
125+
$_[2] || {},
126+
);
127+
128+
$link->set_from_related( $f_rel, $far_obj );
103129

104130
$link->insert();
105131

106-
return $far_obj;
132+
$guard->commit if $guard;
133+
134+
$far_obj;
107135
};
108136

137+
109138
my $set_meth_name = join '::', $class, $set_meth;
110139
*$set_meth_name = subname $set_meth_name, sub {
111140

@@ -132,37 +161,43 @@ EOW
132161
( @_ and ref $_[0] ne 'HASH' )
133162
);
134163

135-
my $guard = $self->result_source->schema->storage->txn_scope_guard;
164+
my $guard;
165+
166+
# there will only be a single delete() op, unless we have what to set to
167+
$guard = $self->result_source->schema->storage->txn_scope_guard
168+
if @$set_to;
136169

137170
# if there is a where clause in the attributes, ensure we only delete
138171
# rows that are within the where restriction
172+
$self->search_related(
173+
$rel,
174+
( $rel_attrs->{where}
175+
? ( $rel_attrs->{where}, { join => $f_rel } )
176+
: ()
177+
)
178+
)->delete;
139179

140-
if ($rel_attrs && $rel_attrs->{where}) {
141-
$self->search_related( $rel, $rel_attrs->{where},{join => $f_rel})->delete;
142-
} else {
143-
$self->search_related( $rel, {} )->delete;
144-
}
145180
# add in the set rel objects
146181
$self->$add_meth(
147182
$_,
148183
@_, # at this point @_ is either empty or contains a lone link-data hash
149184
) for @$set_to;
150185

151-
$guard->commit;
186+
$guard->commit if $guard;
152187
};
153188

189+
154190
my $remove_meth_name = join '::', $class, $remove_meth;
155191
*$remove_meth_name = subname $remove_meth_name, sub {
156-
my ($self, $obj) = @_;
157192

158-
$self->throw_exception("${remove_meth} needs an object")
159-
unless blessed ($obj);
193+
$_[0]->throw_exception("'$remove_meth' expects an object")
194+
unless defined blessed $_[1];
160195

161-
$self->search_related_rs($rel)->search_rs(
162-
$obj->ident_condition( $f_rel ),
163-
{ join => $f_rel },
164-
)->delete;
196+
$_[0]->search_related_rs( $rel )
197+
->search_rs( $_[1]->ident_condition( $f_rel ), { join => $f_rel } )
198+
->delete;
165199
};
200+
166201
}
167202
}
168203

t/relationship/core.t

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ warnings_like {
203203
( qr/\QCalling 'set_producers' with a list of items to link to is deprecated, use an arrayref instead/ ) x 2
204204
], 'Warnings on deprecated invocation of set_* found';
205205

206+
warnings_like {
207+
is( $cd->producers( producerid => '666' )->count, 0 );
208+
} [
209+
qr/\Qsearch( %condition ) is deprecated/
210+
], 'Warning properly bubbled from search()';
211+
206212
$cd->set_producers([$schema->resultset('Producer')->all]);
207213
is( $cd->producers->count(), $prod_before_count+2,
208214
'many_to_many set_$rel(\@objs) count ok' );
@@ -211,11 +217,11 @@ is( $cd->producers->count(), 1, 'many_to_many set_$rel([$obj]) count ok' );
211217

212218
throws_ok {
213219
$cd->remove_from_producers({ fake => 'hash' })
214-
} qr/needs an object/, 'remove_from_$rel($hash) dies correctly';
220+
} qr/expects an object/, 'remove_from_$rel($hash) dies correctly';
215221

216222
throws_ok {
217223
$cd->add_to_producers()
218-
} qr/needs an object or hashref/, 'add_to_$rel(undef) dies correctly';
224+
} qr/expects an object or hashref/, 'add_to_$rel(undef) dies correctly';
219225

220226
# many_to_many stresstest
221227
my $twokey = $schema->resultset('TwoKeys')->find(1,1);

0 commit comments

Comments
 (0)