line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mongoose::Join; |
2
|
|
|
|
|
|
|
$Mongoose::Join::VERSION = '2.01'; |
3
|
1
|
|
|
1
|
|
7
|
use Moose; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
4
|
1
|
|
|
1
|
|
5730
|
use Moose::Util::TypeConstraints; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
7
|
|
5
|
1
|
|
|
1
|
|
1809
|
use Moose::Meta::TypeConstraint::Parameterizable; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
37
|
|
6
|
1
|
|
|
1
|
|
5
|
use Moose::Meta::TypeConstraint::Registry; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
7
|
1
|
|
|
1
|
|
4
|
use Tie::IxHash; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
220
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new; |
10
|
|
|
|
|
|
|
$REGISTRY->add_type_constraint( |
11
|
|
|
|
|
|
|
Moose::Meta::TypeConstraint::Parameterizable->new( |
12
|
|
|
|
|
|
|
name => 'Mongoose::Join', |
13
|
|
|
|
|
|
|
package_defined_in => __PACKAGE__, |
14
|
|
|
|
|
|
|
parent => find_type_constraint('Item'), |
15
|
|
|
|
|
|
|
constraint => sub { die 'constrained' }, |
16
|
|
|
|
|
|
|
constraint_generator => sub { |
17
|
|
|
|
|
|
|
my $type_parameter = shift; |
18
|
|
|
|
|
|
|
sub { return {} }; |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
) |
21
|
|
|
|
|
|
|
); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
Moose::Util::TypeConstraints::add_parameterizable_type( $REGISTRY->get_type_constraint('Mongoose::Join') ); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
has 'class' => ( is => 'rw', isa => 'Str' ); |
26
|
|
|
|
|
|
|
has 'field' => ( is => 'rw', isa => 'Str' ); |
27
|
|
|
|
|
|
|
has 'with_class' => ( is => 'rw', isa => 'Str' ); |
28
|
|
|
|
|
|
|
has '_with_collection_name' => ( is => 'rw', isa => 'Str' ); |
29
|
|
|
|
|
|
|
has 'parent' => ( is => 'rw', isa => 'BSON::OID' ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# once the object is expanded, it has children too |
32
|
|
|
|
|
|
|
has 'children' => ( is => 'rw', isa => 'ArrayRef', default => sub{[]} ); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# before being saved, objects are stored in this buffer |
35
|
|
|
|
|
|
|
has 'buffer' => ( is => 'rw', isa => 'HashRef', default => sub { {} } ); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# deleting happens at a later moment, meanwhile delete candidates are here |
38
|
|
|
|
|
|
|
has 'delete_buffer' => ( is => 'rw', isa => 'HashRef', default => sub { {} } ); |
39
|
|
|
|
|
|
|
|
40
|
1
|
|
|
1
|
|
6
|
use Scalar::Util qw/refaddr/; |
|
1
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
1208
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub add { |
43
|
0
|
|
|
0
|
1
|
|
my ( $self, @objs ) = @_; |
44
|
0
|
|
|
|
|
|
for my $obj (@objs) { |
45
|
0
|
|
|
|
|
|
$self->buffer->{ refaddr $obj } = $obj; |
46
|
|
|
|
|
|
|
} |
47
|
0
|
|
|
|
|
|
@objs; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub remove { |
51
|
0
|
|
|
0
|
1
|
|
my ( $self, @objs ) = @_; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# if the collection is live, remove from memory |
54
|
0
|
0
|
|
|
|
|
if( my $buffer = $self->buffer ) { |
55
|
0
|
|
|
|
|
|
for my $obj (@objs) { |
56
|
0
|
0
|
|
|
|
|
next unless defined $obj; |
57
|
0
|
|
|
|
|
|
delete $buffer->{ refaddr $obj }; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# children get cleaned too |
62
|
0
|
0
|
|
|
|
|
if( defined ( my $children = $self->children ) ) { |
63
|
0
|
|
|
|
|
|
for my $obj (@objs) { |
64
|
0
|
|
|
|
|
|
my $id = $obj->_id; |
65
|
0
|
0
|
|
|
|
|
next unless defined $id; |
66
|
|
|
|
|
|
|
$self->children([ |
67
|
0
|
|
|
|
|
|
grep { $_->id ne $id } _build_rel( @{$children} ) |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
]); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# save action for later (when save is called) |
73
|
0
|
0
|
|
|
|
|
my $delete_buffer = defined $self->delete_buffer |
74
|
|
|
|
|
|
|
? $self->delete_buffer |
75
|
|
|
|
|
|
|
: $self->delete_buffer({}); |
76
|
0
|
|
|
|
|
|
for my $obj (@objs) { |
77
|
0
|
|
|
|
|
|
$delete_buffer->{ refaddr $obj } = $obj; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub collection { |
82
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
83
|
0
|
0
|
|
|
|
|
defined $self->with_class |
84
|
|
|
|
|
|
|
and return $self->with_class->collection; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub with_collection_name { |
88
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
89
|
0
|
0
|
|
|
|
|
defined $self->_with_collection_name |
90
|
|
|
|
|
|
|
and return $self->_with_collection_name; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
$self->_with_collection_name( Mongoose->class_config($self->with_class)->{collection_name} ); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
0
|
|
|
sub _insert { #TODO insert and commit |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub _save { |
99
|
0
|
|
|
0
|
|
|
my ( $self, $parent, @scope ) = @_; |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
my $children = delete $self->{children}; |
102
|
0
|
0
|
|
|
|
|
if( ref $children eq 'Mongoose::Join' ) { |
103
|
0
|
|
|
|
|
|
$children = $children->children; |
104
|
|
|
|
|
|
|
} |
105
|
0
|
0
|
|
|
|
|
my @objs = _build_rel( @{$children ||[]} ); |
|
0
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
0
|
|
|
|
|
|
my $collection_name = $self->with_collection_name; |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# load buffers |
110
|
0
|
|
|
|
|
|
my $buffer = delete $self->{buffer}; |
111
|
0
|
|
|
|
|
|
my $delete_buffer = delete $self->{delete_buffer}; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# save buffered children |
114
|
0
|
|
|
|
|
|
for ( keys %{ $buffer } ) { |
|
0
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
my $obj = delete $buffer->{$_}; |
116
|
0
|
0
|
|
|
|
|
next if exists $delete_buffer->{ refaddr $obj }; |
117
|
0
|
|
|
|
|
|
$obj->save( @scope ); |
118
|
0
|
|
|
|
|
|
push @objs, _build_rel({ '$ref' => $collection_name, '$id' => $obj->_id }); |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# adjust |
122
|
0
|
|
|
|
|
|
$self->buffer( $buffer ); # restore the list |
123
|
0
|
|
|
|
|
|
$self->delete_buffer({}); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# make sure unique children is saved |
126
|
0
|
|
|
|
|
|
my %unique = map { $_->id => $_ } @objs; |
|
0
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
@objs = values %unique; |
128
|
0
|
|
|
|
|
|
$self->children( \@objs ); |
129
|
0
|
|
|
|
|
|
return @objs; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub _children_refs { |
133
|
0
|
|
|
0
|
|
|
my ($self)=@_; |
134
|
0
|
|
|
|
|
|
my @found; |
135
|
|
|
|
|
|
|
$self->find->each( sub{ |
136
|
0
|
|
|
0
|
|
|
push @found, _build_rel({ '$ref' => $_[0]->_collection_name, '$id' => $_[0]->{_id} }); |
137
|
0
|
|
|
|
|
|
}); |
138
|
0
|
|
|
|
|
|
return @found; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub find { |
142
|
0
|
|
|
0
|
1
|
|
my ( $self, $opts, @scope ) = @_; |
143
|
0
|
|
|
|
|
|
my $class = $self->with_class; |
144
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
145
|
0
|
|
|
|
|
|
my $children = $self->children; |
146
|
0
|
0
|
|
|
|
|
if( ref $children eq 'Mongoose::Join' ) { |
147
|
0
|
|
|
|
|
|
$children = $children->children; |
148
|
|
|
|
|
|
|
} |
149
|
0
|
0
|
|
|
|
|
my @children = map { $_->id } _build_rel( @{$children ||[]} ); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
$opts->{_id} = { '$in' => \@children }; |
152
|
0
|
|
|
|
|
|
return $class->find( $opts, @scope ); |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub count { |
156
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
157
|
0
|
|
|
|
|
|
$self->_call_rel_method( count => @_ ); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub find_one { |
161
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
162
|
0
|
|
|
|
|
|
$self->_call_rel_method( find_one => @_ ); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub _call_rel_method { |
166
|
0
|
|
|
0
|
|
|
my ( $self, $method, $opts, @scope ) = @_; |
167
|
0
|
|
|
|
|
|
my $class = $self->with_class; |
168
|
|
|
|
|
|
|
|
169
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
170
|
0
|
0
|
|
|
|
|
$opts->{_id} = { '$in' => [ map { $_->id } _build_rel( @{$self->children ||[]} ) ] }; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
|
return $class->$method( $opts, @scope ); |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
0
|
|
|
0
|
1
|
|
sub first { shift->find_one } |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub query { |
178
|
0
|
|
|
0
|
1
|
|
my ( $self, $opts, $attrs, @scope ) = @_; |
179
|
0
|
|
|
|
|
|
my $class = $self->with_class; |
180
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
181
|
0
|
0
|
|
|
|
|
my @children = map { $_->id } _build_rel( @{$self->children ||[]} ); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
$opts->{_id} = { '$in' => \@children }; |
183
|
0
|
|
|
|
|
|
return $class->query( $opts, $attrs, @scope ); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub all { |
187
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
188
|
0
|
|
|
|
|
|
return $self->find(@_)->all; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub hash_on { |
192
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
193
|
0
|
|
|
|
|
|
my $key = shift; |
194
|
0
|
|
|
|
|
|
my %hash; |
195
|
|
|
|
|
|
|
map { |
196
|
0
|
0
|
|
|
|
|
$hash{ $_->{$key} } = $_ unless exists $hash{ $_->{$key} }; |
|
0
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
} $self->find(@_)->all; |
198
|
0
|
|
|
|
|
|
return %hash; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub hash_array { |
202
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
203
|
0
|
|
|
|
|
|
my $key = shift; |
204
|
0
|
|
|
|
|
|
my %hash; |
205
|
|
|
|
|
|
|
map { |
206
|
0
|
|
|
|
|
|
push @{ $hash{ $_->{$key} } }, $_; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
} $self->find(@_)->all; |
208
|
0
|
|
|
|
|
|
return %hash; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# make sure all refs what's expected on the MongoDB driver in use |
212
|
|
|
|
|
|
|
sub _build_rel { |
213
|
0
|
|
|
0
|
|
|
map { ref $_ eq 'BSON::DBRef' |
214
|
|
|
|
|
|
|
? $_ |
215
|
0
|
0
|
|
|
|
|
: BSON::DBRef->new( ref => $_->{'$ref'}, id => $_->{'$id'} ) |
216
|
|
|
|
|
|
|
} @_; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=head1 NAME |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
Mongoose::Join - simple class relationship resolver |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head1 SYNOPSIS |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
package Author; |
226
|
|
|
|
|
|
|
use Moose; |
227
|
|
|
|
|
|
|
with 'Mongoose::Document'; |
228
|
|
|
|
|
|
|
has 'articles' => ( |
229
|
|
|
|
|
|
|
is => 'rw', |
230
|
|
|
|
|
|
|
isa => 'Mongoose::Join[Article]', |
231
|
|
|
|
|
|
|
default => sub { Mongoose::Join->new( with_class => 'Article' ) } |
232
|
|
|
|
|
|
|
); |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 DESCRIPTION |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
This module can be used to establish relationships |
237
|
|
|
|
|
|
|
between two C<Mongoose::Document> classes. It should not |
238
|
|
|
|
|
|
|
be used with C<Mongoose::EmbeddedDocument> classes. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
All object relationships are stored as reference C<$id> arrays |
241
|
|
|
|
|
|
|
into the parent object. This translates into a slight performance hit |
242
|
|
|
|
|
|
|
when loading the parent class, but not as much as loading all |
243
|
|
|
|
|
|
|
objects at one as when using an C<ArrayRef>. |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
B<Attention>: the relationship attribute needs to be initialized to |
246
|
|
|
|
|
|
|
an instance of C<Mongoose::Join> before it can be used. |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=head2 Mongoose::Class |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
Take a look at L<Mongoose::Class>, it has nice syntatic sugar |
251
|
|
|
|
|
|
|
that does most of the initialization behind the scenes for you. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=head1 METHODS |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=head2 add |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
Add (join) a Mongoose::Document object for later saving. |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
Saving the parent Mongoose::Document will save both. |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
my $author = Author->new; |
262
|
|
|
|
|
|
|
$author->articles->add( Article->new ); |
263
|
|
|
|
|
|
|
$author->save; # saves all objects |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=head2 remove |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
Delete from the relationship list. |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
my $author = Author->find_one; |
270
|
|
|
|
|
|
|
my $first_article = $author->articles->find_one; |
271
|
|
|
|
|
|
|
$author->articles->remove( $first_article ); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head2 find |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
Run a MongoDB C<find> on the joint collection. |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# searches for articles belonging to this collection |
278
|
|
|
|
|
|
|
my $cursor = $author->articles->find({ title=>'foo article' }); |
279
|
|
|
|
|
|
|
while( my $article = $cursor->next ) { |
280
|
|
|
|
|
|
|
... |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Returns a L<Mongoose::Cursor>. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=head2 count |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
Count relations. |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=head2 find_one |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
Just like find, but returns the first row found. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=head2 first |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
Alias to C<find_one> |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
$first_cd = $artist->cds->first; |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head2 all |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
Same as C<find>, but returns an ARRAY with all the results, instead |
302
|
|
|
|
|
|
|
of a cursor. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
my @cds = $artist->cds->all; |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=head2 hash_on |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Same as C<all>, but returns a HASH instead of an ARRAY. |
309
|
|
|
|
|
|
|
The hash will be indexed by the key name sent as the first parameter. |
310
|
|
|
|
|
|
|
The hash value contains exactly one object. In case duplicate rows |
311
|
|
|
|
|
|
|
with the same key value are found, the resulting hash will contain |
312
|
|
|
|
|
|
|
the first one found. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# ie. returns $cds{'111888888292adf0000003'} = <CD Object>; |
315
|
|
|
|
|
|
|
my %cds = $artist->cds->hash_on( '_id' => { artist=>'Joe' }); |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# ie. returns $joe_cds{'Title1'} = <CD Object>; |
318
|
|
|
|
|
|
|
my %joe_cds = $artist->cds->hash_on( 'title' => { artist=>qr/Joe/ }); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head2 hash_array |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Similar to C<hash_on>, but returns a hash with ALL rows found, grouped |
323
|
|
|
|
|
|
|
by the key. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# ie. returns $cds{'Title1'} = [ <CD1 Object>, <CD2 Object>, ... ]; |
326
|
|
|
|
|
|
|
my %cds = $artist->cds->hash_array( 'title' => { artist=>'Joe' }); |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Hash values are ARRAYREFs with 1 or more rows. |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head2 query |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Run a MongoDB C<query> on the joint collection. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=head2 collection |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Returns the L<MongoDB::Collection> for the joint collection. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head2 with_collection_name |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Return the collection name for the joint Mongoose::Document. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=cut |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable(); |